ETH Price: $3,634.12 (+9.37%)

Token

Maggottown (MGT)
 

Overview

Max Total Supply

1,699 MGT

Holders

1,449

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 MGT
0x3ba75c7ccfe8d3353dfcae0e13271ab0ac228ddd
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
Maggottown

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license
File 1 of 15 : Maggottown.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/common/ERC2981.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "erc721a/contracts/ERC721A.sol";

error ErrorSaleNotStarted();
error ErrorInsufficientFund();
error ErrorExceedTransactionLimit();
error ErrorExceedWalletLimit();
error ErrorExceedMaxSupply();

contract Maggottown is ERC2981, ERC721A, Ownable {
    using Address for address payable;
    using ECDSA for bytes32;
    using Strings for uint256;

    uint256 public immutable _mintPrice = 0.0077 ether;
    uint32 public immutable _txLimit = 15;
    uint32 public immutable _maxSupply = 10000;
    uint32 public immutable _walletLimit = 15;

    bool public _started;
    string public _metadataURI = "";

    constructor() ERC721A("Maggottown", "MGT") {
        _setDefaultRoyalty(owner(), 500);
    }

    function mint(uint32 amount) external payable {
        if (!_started) revert ErrorSaleNotStarted();
        if (amount + _totalMinted() > _maxSupply) revert ErrorExceedMaxSupply();
        if (amount > _txLimit) revert ErrorExceedTransactionLimit();

        uint256 requiredValue = amount * _mintPrice;
        uint64 userMinted = _getAux(msg.sender);
        if (userMinted == 0) requiredValue -= _mintPrice;

        userMinted += amount;
        _setAux(msg.sender, userMinted);
        if (userMinted > _walletLimit) revert ErrorExceedWalletLimit();

        if (msg.value < requiredValue) revert ErrorInsufficientFund();

        _safeMint(msg.sender, amount);
    }

    struct State {
        uint256 mintPrice;
        uint32 txLimit;
        uint32 walletLimit;
        uint32 maxSupply;
        uint32 totalMinted;
        uint32 userMinted;
        bool started;
    }

    function _state(address minter) external view returns (State memory) {
        return
            State({
                mintPrice: _mintPrice,
                txLimit: _txLimit,
                walletLimit: _walletLimit,
                maxSupply: _maxSupply,
                totalMinted: uint32(ERC721A._totalMinted()),
                userMinted: uint32(_getAux(minter)),
                started: _started
            });
    }

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        string memory baseURI = _metadataURI;
        return string(abi.encodePacked(baseURI, tokenId.toString(), ".json"));
    }

    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC2981, ERC721A) returns (bool) {
        return
            interfaceId == type(IERC2981).interfaceId ||
            interfaceId == type(IERC721A).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    function godMint(address to, uint32 amount) external onlyOwner {
        if (amount + _totalMinted() > _maxSupply) revert ErrorExceedMaxSupply();
        _safeMint(to, amount);
    }

    function setFeeNumerator(uint96 feeNumerator) external onlyOwner {
        _setDefaultRoyalty(owner(), feeNumerator);
    }

    function setStarted(bool started) external onlyOwner {
        _started = started;
    }

    function setMetadataURI(string memory uri) external onlyOwner {
        _metadataURI = uri;
    }

    function withdraw() external onlyOwner {
        payable(msg.sender).sendValue(address(this).balance);
    }
}

File 2 of 15 : ERC721A.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.0.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721A.sol';

/**
 * @dev ERC721 token receiver interface.
 */
interface ERC721A__IERC721Receiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension. Built to optimize for lower gas during batch mints.
 *
 * Assumes serials are sequentially minted starting at _startTokenId() (defaults to 0, e.g. 0, 1, 2, 3..).
 *
 * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 *
 * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // Mask of an entry in packed address data.
    uint256 private constant BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;

    // The bit position of `numberMinted` in packed address data.
    uint256 private constant BITPOS_NUMBER_MINTED = 64;

    // The bit position of `numberBurned` in packed address data.
    uint256 private constant BITPOS_NUMBER_BURNED = 128;

    // The bit position of `aux` in packed address data.
    uint256 private constant BITPOS_AUX = 192;

    // Mask of all 256 bits in packed address data except the 64 bits for `aux`.
    uint256 private constant BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;

    // The bit position of `startTimestamp` in packed ownership.
    uint256 private constant BITPOS_START_TIMESTAMP = 160;

    // The bit mask of the `burned` bit in packed ownership.
    uint256 private constant BITMASK_BURNED = 1 << 224;
    
    // The bit position of the `nextInitialized` bit in packed ownership.
    uint256 private constant BITPOS_NEXT_INITIALIZED = 225;

    // The bit mask of the `nextInitialized` bit in packed ownership.
    uint256 private constant BITMASK_NEXT_INITIALIZED = 1 << 225;

    // The tokenId of the next token to be minted.
    uint256 private _currentIndex;

    // The number of tokens burned.
    uint256 private _burnCounter;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to ownership details
    // An empty struct value does not necessarily mean the token is unowned.
    // See `_packedOwnershipOf` implementation for details.
    //
    // Bits Layout:
    // - [0..159]   `addr`
    // - [160..223] `startTimestamp`
    // - [224]      `burned`
    // - [225]      `nextInitialized`
    mapping(uint256 => uint256) private _packedOwnerships;

    // Mapping owner address to address data.
    //
    // Bits Layout:
    // - [0..63]    `balance`
    // - [64..127]  `numberMinted`
    // - [128..191] `numberBurned`
    // - [192..255] `aux`
    mapping(address => uint256) private _packedAddressData;

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

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
        _currentIndex = _startTokenId();
    }

    /**
     * @dev Returns the starting token ID. 
     * To change the starting token ID, please override this function.
     */
    function _startTokenId() internal view virtual returns (uint256) {
        return 0;
    }

    /**
     * @dev Returns the next token ID to be minted.
     */
    function _nextTokenId() internal view returns (uint256) {
        return _currentIndex;
    }

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count. 
     * To get the total number of tokens minted, please see `_totalMinted`.
     */
    function totalSupply() public view override returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than `_currentIndex - _startTokenId()` times.
        unchecked {
            return _currentIndex - _burnCounter - _startTokenId();
        }
    }

    /**
     * @dev Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() internal view returns (uint256) {
        // Counter underflow is impossible as _currentIndex does not decrement,
        // and it is initialized to `_startTokenId()`
        unchecked {
            return _currentIndex - _startTokenId();
        }
    }

    /**
     * @dev Returns the total number of tokens burned.
     */
    function _totalBurned() internal view returns (uint256) {
        return _burnCounter;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        // The interface IDs are constants representing the first 4 bytes of the XOR of
        // all function selectors in the interface. See: https://eips.ethereum.org/EIPS/eip-165
        // e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`
        return
            interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
            interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
            interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return _packedAddressData[owner] & BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> BITPOS_NUMBER_MINTED) & BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens burned by or on behalf of `owner`.
     */
    function _numberBurned(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> BITPOS_NUMBER_BURNED) & BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view returns (uint64) {
        return uint64(_packedAddressData[owner] >> BITPOS_AUX);
    }

    /**
     * Sets the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     * If there are multiple variables, please pack them into a uint64.
     */
    function _setAux(address owner, uint64 aux) internal {
        uint256 packed = _packedAddressData[owner];
        uint256 auxCasted;
        assembly { // Cast aux without masking.
            auxCasted := aux
        }
        packed = (packed & BITMASK_AUX_COMPLEMENT) | (auxCasted << BITPOS_AUX);
        _packedAddressData[owner] = packed;
    }

    /**
     * Returns the packed ownership data of `tokenId`.
     */
    function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) {
        uint256 curr = tokenId;

        unchecked {
            if (_startTokenId() <= curr)
                if (curr < _currentIndex) {
                    uint256 packed = _packedOwnerships[curr];
                    // If not burned.
                    if (packed & BITMASK_BURNED == 0) {
                        // Invariant:
                        // There will always be an ownership that has an address and is not burned
                        // before an ownership that does not have an address and is not burned.
                        // Hence, curr will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed is zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * Returns the unpacked `TokenOwnership` struct from `packed`.
     */
    function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) {
        ownership.addr = address(uint160(packed));
        ownership.startTimestamp = uint64(packed >> BITPOS_START_TIMESTAMP);
        ownership.burned = packed & BITMASK_BURNED != 0;
    }

    /**
     * Returns the unpacked `TokenOwnership` struct at `index`.
     */
    function _ownershipAt(uint256 index) internal view returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnerships[index]);
    }

    /**
     * @dev Initializes the ownership slot minted at `index` for efficiency purposes.
     */
    function _initializeOwnershipAt(uint256 index) internal {
        if (_packedOwnerships[index] == 0) {
            _packedOwnerships[index] = _packedOwnershipOf(index);
        }
    }

    /**
     * Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around in the collection over time.
     */
    function _ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnershipOf(tokenId));
    }

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

    /**
     * @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) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        string memory baseURI = _baseURI();
        return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : '';
    }

    /**
     * @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 Casts the address to uint256 without masking.
     */
    function _addressToUint256(address value) private pure returns (uint256 result) {
        assembly {
            result := value
        }
    }

    /**
     * @dev Casts the boolean to uint256 without branching.
     */
    function _boolToUint256(bool value) private pure returns (uint256 result) {
        assembly {
            result := value
        }
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public override {
        address owner = address(uint160(_packedOwnershipOf(tokenId)));
        if (to == owner) revert ApprovalToCurrentOwner();

        if (_msgSenderERC721A() != owner)
            if (!isApprovedForAll(owner, _msgSenderERC721A())) {
                revert ApprovalCallerNotOwnerNorApproved();
            }

        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        if (operator == _msgSenderERC721A()) revert ApproveToCaller();

        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), 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 {
        _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 {
        _transfer(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

    /**
     * @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`),
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        return
            _startTokenId() <= tokenId &&
            tokenId < _currentIndex && // If within bounds,
            _packedOwnerships[tokenId] & BITMASK_BURNED == 0; // and not burned.
    }

    /**
     * @dev Equivalent to `_safeMint(to, quantity, '')`.
     */
    function _safeMint(address to, uint256 quantity) internal {
        _safeMint(to, quantity, '');
    }

    /**
     * @dev Safely mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement
     *   {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the balance and number minted.
            _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            if (to.code.length != 0) {
                do {
                    emit Transfer(address(0), to, updatedIndex);
                    if (!_checkContractOnERC721Received(address(0), to, updatedIndex++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (updatedIndex < end);
                // Reentrancy protection
                if (_currentIndex != startTokenId) revert();
            } else {
                do {
                    emit Transfer(address(0), to, updatedIndex++);
                } while (updatedIndex < end);
            }
            _currentIndex = updatedIndex;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 quantity) internal {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the balance and number minted.
            _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            do {
                emit Transfer(address(0), to, updatedIndex++);
            } while (updatedIndex < end);

            _currentIndex = updatedIndex;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * 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
    ) private {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner();

        bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
            isApprovedForAll(from, _msgSenderERC721A()) ||
            getApproved(tokenId) == _msgSenderERC721A());

        if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        delete _tokenApprovals[tokenId];

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            // We can directly increment and decrement the balances.
            --_packedAddressData[from]; // Updates: `balance -= 1`.
            ++_packedAddressData[to]; // Updates: `balance += 1`.

            // Updates:
            // - `address` to the next owner.
            // - `startTimestamp` to the timestamp of transfering.
            // - `burned` to `false`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                BITMASK_NEXT_INITIALIZED;

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        emit Transfer(from, to, tokenId);
        _afterTokenTransfers(from, to, tokenId, 1);
    }

    /**
     * @dev Equivalent to `_burn(tokenId, false)`.
     */
    function _burn(uint256 tokenId) internal virtual {
        _burn(tokenId, false);
    }

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

        address from = address(uint160(prevOwnershipPacked));

        if (approvalCheck) {
            bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
                isApprovedForAll(from, _msgSenderERC721A()) ||
                getApproved(tokenId) == _msgSenderERC721A());

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

        _beforeTokenTransfers(from, address(0), tokenId, 1);

        // Clear approvals from the previous owner.
        delete _tokenApprovals[tokenId];

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            // Updates:
            // - `balance -= 1`.
            // - `numberBurned += 1`.
            //
            // We can directly decrement the balance, and increment the number burned.
            // This is equivalent to `packed -= 1; packed += 1 << BITPOS_NUMBER_BURNED;`.
            _packedAddressData[from] += (1 << BITPOS_NUMBER_BURNED) - 1;

            // Updates:
            // - `address` to the last owner.
            // - `startTimestamp` to the timestamp of burning.
            // - `burned` to `true`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] =
                _addressToUint256(from) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                BITMASK_BURNED | 
                BITMASK_NEXT_INITIALIZED;

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        emit Transfer(from, address(0), tokenId);
        _afterTokenTransfers(from, address(0), tokenId, 1);

        // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
        unchecked {
            _burnCounter++;
        }
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target 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 _checkContractOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (
            bytes4 retval
        ) {
            return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
        } catch (bytes memory reason) {
            if (reason.length == 0) {
                revert TransferToNonERC721ReceiverImplementer();
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

    /**
     * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting.
     * And also called before burning one token.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * 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, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes
     * minting.
     * And also called after one token has been burned.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
     * transferred to `to`.
     * - When `from` is zero, `tokenId` has been minted for `to`.
     * - When `to` is zero, `tokenId` has been burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Returns the message sender (defaults to `msg.sender`).
     *
     * If you are writing GSN compatible contracts, you need to override this function.
     */
    function _msgSenderERC721A() internal view virtual returns (address) {
        return msg.sender;
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function _toString(uint256 value) internal pure returns (string memory ptr) {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit), 
            // but we allocate 128 bytes to keep the free memory pointer 32-byte word aliged.
            // We will need 1 32-byte word to store the length, 
            // and 3 32-byte words to store a maximum of 78 digits. Total: 32 + 3 * 32 = 128.
            ptr := add(mload(0x40), 128)
            // Update the free memory pointer to allocate.
            mstore(0x40, ptr)

            // Cache the end of the memory to calculate the length later.
            let end := ptr

            // We write the string from the rightmost digit to the leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // Costs a bit more than early returning for the zero case,
            // but cheaper in terms of deployment and overall runtime costs.
            for { 
                // Initialize and perform the first pass without check.
                let temp := value
                // Move the pointer 1 byte leftwards to point to an empty character slot.
                ptr := sub(ptr, 1)
                // Write the character to the pointer. 48 is the ASCII index of '0'.
                mstore8(ptr, add(48, mod(temp, 10)))
                temp := div(temp, 10)
            } temp { 
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
            } { // Body of the for loop.
                ptr := sub(ptr, 1)
                mstore8(ptr, add(48, mod(temp, 10)))
            }
            
            let length := sub(end, ptr)
            // Move the pointer 32 bytes leftwards to make room for the length.
            ptr := sub(ptr, 32)
            // Store the length.
            mstore(ptr, length)
        }
    }
}

File 3 of 15 : ECDSA.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;

import "../Strings.sol";

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

File 4 of 15 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 5 of 15 : ERC2981.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/common/ERC2981.sol)

pragma solidity ^0.8.0;

import "../../interfaces/IERC2981.sol";
import "../../utils/introspection/ERC165.sol";

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

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

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

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

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

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

        return (royalty.receiver, royaltyAmount);
    }

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

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

        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
    }

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

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

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

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

File 6 of 15 : ERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

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

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens 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 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been 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 _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

File 7 of 15 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

File 8 of 15 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)

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 9 of 15 : IERC721A.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.0.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;

/**
 * @dev Interface of an ERC721A compliant contract.
 */
interface IERC721A {
    /**
     * The caller must own the token or be an approved operator.
     */
    error ApprovalCallerNotOwnerNorApproved();

    /**
     * The token does not exist.
     */
    error ApprovalQueryForNonexistentToken();

    /**
     * The caller cannot approve to their own address.
     */
    error ApproveToCaller();

    /**
     * The caller cannot approve to the current owner.
     */
    error ApprovalToCurrentOwner();

    /**
     * Cannot query the balance for the zero address.
     */
    error BalanceQueryForZeroAddress();

    /**
     * Cannot mint to the zero address.
     */
    error MintToZeroAddress();

    /**
     * The quantity of tokens minted must be more than zero.
     */
    error MintZeroQuantity();

    /**
     * The token does not exist.
     */
    error OwnerQueryForNonexistentToken();

    /**
     * The caller must own the token or be an approved operator.
     */
    error TransferCallerNotOwnerNorApproved();

    /**
     * The token must be owned by `from`.
     */
    error TransferFromIncorrectOwner();

    /**
     * Cannot safely transfer to a contract that does not implement the ERC721Receiver interface.
     */
    error TransferToNonERC721ReceiverImplementer();

    /**
     * Cannot transfer to the zero address.
     */
    error TransferToZeroAddress();

    /**
     * The token does not exist.
     */
    error URIQueryForNonexistentToken();

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
    }

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     *
     * Burned tokens are calculated here, use `_totalMinted()` if you want to count just minted tokens.
     */
    function totalSupply() external view returns (uint256);

    // ==============================
    //            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);

    // ==============================
    //            IERC721
    // ==============================

    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

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

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

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

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must 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 Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

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

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

    // ==============================
    //        IERC721Metadata
    // ==============================

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

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

File 11 of 15 : IERC2981.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)

pragma solidity ^0.8.0;

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

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

File 12 of 15 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

File 13 of 15 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

File 14 of 15 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}

File 15 of 15 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

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

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"ErrorExceedMaxSupply","type":"error"},{"inputs":[],"name":"ErrorExceedTransactionLimit","type":"error"},{"inputs":[],"name":"ErrorExceedWalletLimit","type":"error"},{"inputs":[],"name":"ErrorInsufficientFund","type":"error"},{"inputs":[],"name":"ErrorSaleNotStarted","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"_maxSupply","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_metadataURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_started","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"_state","outputs":[{"components":[{"internalType":"uint256","name":"mintPrice","type":"uint256"},{"internalType":"uint32","name":"txLimit","type":"uint32"},{"internalType":"uint32","name":"walletLimit","type":"uint32"},{"internalType":"uint32","name":"maxSupply","type":"uint32"},{"internalType":"uint32","name":"totalMinted","type":"uint32"},{"internalType":"uint32","name":"userMinted","type":"uint32"},{"internalType":"bool","name":"started","type":"bool"}],"internalType":"struct Maggottown.State","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_txLimit","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_walletLimit","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"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":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint32","name":"amount","type":"uint32"}],"name":"godMint","outputs":[],"stateMutability":"nonpayable","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":"uint32","name":"amount","type":"uint32"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setFeeNumerator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"setMetadataURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"started","type":"bool"}],"name":"setStarted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

610100604052661b5b1bf4c54000608090815250600f63ffffffff1660a09063ffffffff1681525061271063ffffffff1660c09063ffffffff16815250600f63ffffffff1660e09063ffffffff1681525060405180602001604052806000815250600b9080519060200190620000779291906200042e565b503480156200008557600080fd5b506040518060400160405280600a81526020017f4d6167676f74746f776e000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f4d4754000000000000000000000000000000000000000000000000000000000081525081600490805190602001906200010a9291906200042e565b508060059080519060200190620001239291906200042e565b50620001346200018560201b60201c565b60028190555050506200015c620001506200018a60201b60201c565b6200019260201b60201c565b6200017f620001706200025860201b60201c565b6101f46200028260201b60201c565b6200065d565b600090565b600033905090565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b620002926200042460201b60201c565b6bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115620002f3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002ea9062000565565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160362000365576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200035c90620005d7565b60405180910390fd5b60405180604001604052808373ffffffffffffffffffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff168152506000808201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055509050505050565b6000612710905090565b8280546200043c9062000628565b90600052602060002090601f016020900481019282620004605760008555620004ac565b82601f106200047b57805160ff1916838001178555620004ac565b82800160010185558215620004ac579182015b82811115620004ab5782518255916020019190600101906200048e565b5b509050620004bb9190620004bf565b5090565b5b80821115620004da576000816000905550600101620004c0565b5090565b600082825260208201905092915050565b7f455243323938313a20726f79616c7479206665652077696c6c2065786365656460008201527f2073616c65507269636500000000000000000000000000000000000000000000602082015250565b60006200054d602a83620004de565b91506200055a82620004ef565b604082019050919050565b6000602082019050818103600083015262000580816200053e565b9050919050565b7f455243323938313a20696e76616c696420726563656976657200000000000000600082015250565b6000620005bf601983620004de565b9150620005cc8262000587565b602082019050919050565b60006020820190508181036000830152620005f281620005b0565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200064157607f821691505b602082108103620006575762000656620005f9565b5b50919050565b60805160a05160c05160e051613d85620006dd60003960008181610b1401528181610eac01526115dc015260008181610b4f01528181610ed80152818161145c0152611b38015260008181610e8001528181610f5901526114d401526000818161083c01528181610e5a0152818161153c015261158f0152613d856000f3fe6080604052600436106101d85760003560e01c806363553e7c11610102578063a71bbebe11610095578063e985e9c511610064578063e985e9c5146106a0578063ef6b141a146106dd578063f2fde38b14610706578063fe54c29c1461072f576101d8565b8063a71bbebe146105f3578063b88d4fde1461060f578063c87b56dd14610638578063d4a6762314610675576101d8565b8063750521f5116100d1578063750521f51461054b5780638da5cb5b1461057457806395d89b411461059f578063a22cb465146105ca576101d8565b806363553e7c146104a3578063653a819e146104ce57806370a08231146104f7578063715018a614610534576101d8565b806322f4596f1161017a57806342842e0e1161014957806342842e0e146103d55780634df22a54146103fe5780634df8bb45146104295780636352211e14610466576101d8565b806322f4596f1461032c57806323b872dd146103575780632a55205a146103805780633ccfd60b146103be576101d8565b8063081812fc116101b6578063081812fc14610270578063095ea7b3146102ad5780630e2351e2146102d657806318160ddd14610301576101d8565b806301ffc9a7146101dd5780630387da421461021a57806306fdde0314610245575b600080fd5b3480156101e957600080fd5b5061020460048036038101906101ff9190612cb7565b610758565b6040516102119190612cff565b60405180910390f35b34801561022657600080fd5b5061022f61083a565b60405161023c9190612d33565b60405180910390f35b34801561025157600080fd5b5061025a61085e565b6040516102679190612de7565b60405180910390f35b34801561027c57600080fd5b5061029760048036038101906102929190612e35565b6108f0565b6040516102a49190612ea3565b60405180910390f35b3480156102b957600080fd5b506102d460048036038101906102cf9190612eea565b61096c565b005b3480156102e257600080fd5b506102eb610b12565b6040516102f89190612f49565b60405180910390f35b34801561030d57600080fd5b50610316610b36565b6040516103239190612d33565b60405180910390f35b34801561033857600080fd5b50610341610b4d565b60405161034e9190612f49565b60405180910390f35b34801561036357600080fd5b5061037e60048036038101906103799190612f64565b610b71565b005b34801561038c57600080fd5b506103a760048036038101906103a29190612fb7565b610b81565b6040516103b5929190612ff7565b60405180910390f35b3480156103ca57600080fd5b506103d3610d6b565b005b3480156103e157600080fd5b506103fc60048036038101906103f79190612f64565b610e12565b005b34801561040a57600080fd5b50610413610e32565b6040516104209190612cff565b60405180910390f35b34801561043557600080fd5b50610450600480360381019061044b9190613020565b610e45565b60405161045d9190613108565b60405180910390f35b34801561047257600080fd5b5061048d60048036038101906104889190612e35565b610f45565b60405161049a9190612ea3565b60405180910390f35b3480156104af57600080fd5b506104b8610f57565b6040516104c59190612f49565b60405180910390f35b3480156104da57600080fd5b506104f560048036038101906104f09190613167565b610f7b565b005b34801561050357600080fd5b5061051e60048036038101906105199190613020565b61100b565b60405161052b9190612d33565b60405180910390f35b34801561054057600080fd5b506105496110c3565b005b34801561055757600080fd5b50610572600480360381019061056d91906132c9565b61114b565b005b34801561058057600080fd5b506105896111e1565b6040516105969190612ea3565b60405180910390f35b3480156105ab57600080fd5b506105b461120b565b6040516105c19190612de7565b60405180910390f35b3480156105d657600080fd5b506105f160048036038101906105ec919061333e565b61129d565b005b61060d600480360381019061060891906133aa565b611414565b005b34801561061b57600080fd5b5061063660048036038101906106319190613478565b611693565b005b34801561064457600080fd5b5061065f600480360381019061065a9190612e35565b611706565b60405161066c9190612de7565b60405180910390f35b34801561068157600080fd5b5061068a611808565b6040516106979190612de7565b60405180910390f35b3480156106ac57600080fd5b506106c760048036038101906106c291906134fb565b611896565b6040516106d49190612cff565b60405180910390f35b3480156106e957600080fd5b5061070460048036038101906106ff919061353b565b61192a565b005b34801561071257600080fd5b5061072d60048036038101906107289190613020565b6119c3565b005b34801561073b57600080fd5b5061075660048036038101906107519190613568565b611aba565b005b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061082357507fc21b8f28000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610833575061083282611bc2565b5b9050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60606004805461086d906135d7565b80601f0160208091040260200160405190810160405280929190818152602001828054610899906135d7565b80156108e65780601f106108bb576101008083540402835291602001916108e6565b820191906000526020600020905b8154815290600101906020018083116108c957829003601f168201915b5050505050905090565b60006108fb82611c54565b610931576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6008600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061097782611cb3565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036109de576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166109fd611d7f565b73ffffffffffffffffffffffffffffffffffffffff1614610a6057610a2981610a24611d7f565b611896565b610a5f576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826008600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000610b40611d87565b6003546002540303905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b610b7c838383611d8c565b505050565b6000806000600160008681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1603610d165760006040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b6000610d20612133565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff1686610d4c9190613637565b610d5691906136c0565b90508160000151819350935050509250929050565b610d7361213d565b73ffffffffffffffffffffffffffffffffffffffff16610d916111e1565b73ffffffffffffffffffffffffffffffffffffffff1614610de7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dde9061373d565b60405180910390fd5b610e10473373ffffffffffffffffffffffffffffffffffffffff1661214590919063ffffffff16565b565b610e2d83838360405180602001604052806000815250611693565b505050565b600a60149054906101000a900460ff1681565b610e4d612b4b565b6040518060e001604052807f000000000000000000000000000000000000000000000000000000000000000081526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000063ffffffff168152602001610f0a612239565b63ffffffff168152602001610f1e8461224c565b63ffffffff168152602001600a60149054906101000a900460ff1615158152509050919050565b6000610f5082611cb3565b9050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b610f8361213d565b73ffffffffffffffffffffffffffffffffffffffff16610fa16111e1565b73ffffffffffffffffffffffffffffffffffffffff1614610ff7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fee9061373d565b60405180910390fd5b6110086110026111e1565b82612299565b50565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611072576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6110cb61213d565b73ffffffffffffffffffffffffffffffffffffffff166110e96111e1565b73ffffffffffffffffffffffffffffffffffffffff161461113f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111369061373d565b60405180910390fd5b611149600061242d565b565b61115361213d565b73ffffffffffffffffffffffffffffffffffffffff166111716111e1565b73ffffffffffffffffffffffffffffffffffffffff16146111c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111be9061373d565b60405180910390fd5b80600b90805190602001906111dd929190612ba8565b5050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606005805461121a906135d7565b80601f0160208091040260200160405190810160405280929190818152602001828054611246906135d7565b80156112935780601f1061126857610100808354040283529160200191611293565b820191906000526020600020905b81548152906001019060200180831161127657829003601f168201915b5050505050905090565b6112a5611d7f565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611309576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060096000611316611d7f565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166113c3611d7f565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516114089190612cff565b60405180910390a35050565b600a60149054906101000a900460ff1661145a576040517f1e3177ee00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff16611489612239565b8263ffffffff1661149a919061375d565b11156114d2576040517f57bb669800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff161115611538576040517f552d9c8300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000008263ffffffff1661156c9190613637565b905060006115793361224c565b905060008167ffffffffffffffff16036115bc577f0000000000000000000000000000000000000000000000000000000000000000826115b991906137b3565b91505b8263ffffffff16816115ce91906137fb565b90506115da33826124f3565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168167ffffffffffffffff161115611644576040517f171b8e9400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8134101561167e576040517f9cb10c3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61168e338463ffffffff166125a9565b505050565b61169e848484611d8c565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611700576116c9848484846125c7565b6116ff576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b606061171182611c54565b611747576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600b8054611756906135d7565b80601f0160208091040260200160405190810160405280929190818152602001828054611782906135d7565b80156117cf5780601f106117a4576101008083540402835291602001916117cf565b820191906000526020600020905b8154815290600101906020018083116117b257829003601f168201915b50505050509050806117e084612717565b6040516020016117f19291906138c1565b604051602081830303815290604052915050919050565b600b8054611815906135d7565b80601f0160208091040260200160405190810160405280929190818152602001828054611841906135d7565b801561188e5780601f106118635761010080835404028352916020019161188e565b820191906000526020600020905b81548152906001019060200180831161187157829003601f168201915b505050505081565b6000600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61193261213d565b73ffffffffffffffffffffffffffffffffffffffff166119506111e1565b73ffffffffffffffffffffffffffffffffffffffff16146119a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161199d9061373d565b60405180910390fd5b80600a60146101000a81548160ff02191690831515021790555050565b6119cb61213d565b73ffffffffffffffffffffffffffffffffffffffff166119e96111e1565b73ffffffffffffffffffffffffffffffffffffffff1614611a3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a369061373d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611aae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aa590613962565b60405180910390fd5b611ab78161242d565b50565b611ac261213d565b73ffffffffffffffffffffffffffffffffffffffff16611ae06111e1565b73ffffffffffffffffffffffffffffffffffffffff1614611b36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b2d9061373d565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff16611b65612239565b8263ffffffff16611b76919061375d565b1115611bae576040517f57bb669800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611bbe828263ffffffff166125a9565b5050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611c1d57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611c4d5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600081611c5f611d87565b11158015611c6e575060025482105b8015611cac575060007c0100000000000000000000000000000000000000000000000000000000600660008581526020019081526020016000205416145b9050919050565b60008082905080611cc2611d87565b11611d4857600254811015611d475760006006600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603611d45575b60008103611d3b576006600083600190039350838152602001908152602001600020549050611d11565b8092505050611d7a565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600033905090565b600090565b6000611d9782611cb3565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611dfe576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff16611e1f611d7f565b73ffffffffffffffffffffffffffffffffffffffff161480611e4e5750611e4d85611e48611d7f565b611896565b5b80611e935750611e5c611d7f565b73ffffffffffffffffffffffffffffffffffffffff16611e7b846108f0565b73ffffffffffffffffffffffffffffffffffffffff16145b905080611ecc576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611f32576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f3f8585856001612877565b6008600084815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b61203c8661287d565b1717600660008581526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008316036120c457600060018401905060006006600083815260200190815260200160002054036120c25760025481146120c1578260066000838152602001908152602001600020819055505b5b505b828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461212c8585856001612887565b5050505050565b6000612710905090565b600033905090565b80471015612188576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161217f906139ce565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff16826040516121ae90613a1f565b60006040518083038185875af1925050503d80600081146121eb576040519150601f19603f3d011682016040523d82523d6000602084013e6121f0565b606091505b5050905080612234576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161222b90613aa6565b60405180910390fd5b505050565b6000612243611d87565b60025403905090565b600060c0600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c9050919050565b6122a1612133565b6bffffffffffffffffffffffff16816bffffffffffffffffffffffff1611156122ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122f690613b38565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361236e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161236590613ba4565b60405180910390fd5b60405180604001604052808373ffffffffffffffffffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff168152506000808201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055509050505050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600082905060c081901b77ffffffffffffffffffffffffffffffffffffffffffffffff831617915081600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050505050565b6125c382826040518060200160405280600081525061288d565b5050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026125ed611d7f565b8786866040518563ffffffff1660e01b815260040161260f9493929190613c19565b6020604051808303816000875af192505050801561264b57506040513d601f19601f820116820180604052508101906126489190613c7a565b60015b6126c4573d806000811461267b576040519150601f19603f3d011682016040523d82523d6000602084013e612680565b606091505b5060008151036126bc576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60606000820361275e576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612872565b600082905060005b6000821461279057808061277990613ca7565b915050600a8261278991906136c0565b9150612766565b60008167ffffffffffffffff8111156127ac576127ab61319e565b5b6040519080825280601f01601f1916602001820160405280156127de5781602001600182028036833780820191505090505b5090505b6000851461286b576001826127f791906137b3565b9150600a856128069190613cef565b6030612812919061375d565b60f81b81838151811061282857612827613d20565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561286491906136c0565b94506127e2565b8093505050505b919050565b50505050565b6000819050919050565b50505050565b60006002549050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036128fa576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008303612934576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129416000858386612877565b600160406001901b178302600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e16129a660018514612b41565b901b60a042901b6129b68661287d565b1717600660008381526020019081526020016000208190555060008190506000848201905060008673ffffffffffffffffffffffffffffffffffffffff163b14612aba575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612a6a60008784806001019550876125c7565b612aa0576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8082106129fb578260025414612ab557600080fd5b612b25565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4808210612abb575b816002819055505050612b3b6000858386612887565b50505050565b6000819050919050565b6040518060e0016040528060008152602001600063ffffffff168152602001600063ffffffff168152602001600063ffffffff168152602001600063ffffffff168152602001600063ffffffff1681526020016000151581525090565b828054612bb4906135d7565b90600052602060002090601f016020900481019282612bd65760008555612c1d565b82601f10612bef57805160ff1916838001178555612c1d565b82800160010185558215612c1d579182015b82811115612c1c578251825591602001919060010190612c01565b5b509050612c2a9190612c2e565b5090565b5b80821115612c47576000816000905550600101612c2f565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612c9481612c5f565b8114612c9f57600080fd5b50565b600081359050612cb181612c8b565b92915050565b600060208284031215612ccd57612ccc612c55565b5b6000612cdb84828501612ca2565b91505092915050565b60008115159050919050565b612cf981612ce4565b82525050565b6000602082019050612d146000830184612cf0565b92915050565b6000819050919050565b612d2d81612d1a565b82525050565b6000602082019050612d486000830184612d24565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612d88578082015181840152602081019050612d6d565b83811115612d97576000848401525b50505050565b6000601f19601f8301169050919050565b6000612db982612d4e565b612dc38185612d59565b9350612dd3818560208601612d6a565b612ddc81612d9d565b840191505092915050565b60006020820190508181036000830152612e018184612dae565b905092915050565b612e1281612d1a565b8114612e1d57600080fd5b50565b600081359050612e2f81612e09565b92915050565b600060208284031215612e4b57612e4a612c55565b5b6000612e5984828501612e20565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612e8d82612e62565b9050919050565b612e9d81612e82565b82525050565b6000602082019050612eb86000830184612e94565b92915050565b612ec781612e82565b8114612ed257600080fd5b50565b600081359050612ee481612ebe565b92915050565b60008060408385031215612f0157612f00612c55565b5b6000612f0f85828601612ed5565b9250506020612f2085828601612e20565b9150509250929050565b600063ffffffff82169050919050565b612f4381612f2a565b82525050565b6000602082019050612f5e6000830184612f3a565b92915050565b600080600060608486031215612f7d57612f7c612c55565b5b6000612f8b86828701612ed5565b9350506020612f9c86828701612ed5565b9250506040612fad86828701612e20565b9150509250925092565b60008060408385031215612fce57612fcd612c55565b5b6000612fdc85828601612e20565b9250506020612fed85828601612e20565b9150509250929050565b600060408201905061300c6000830185612e94565b6130196020830184612d24565b9392505050565b60006020828403121561303657613035612c55565b5b600061304484828501612ed5565b91505092915050565b61305681612d1a565b82525050565b61306581612f2a565b82525050565b61307481612ce4565b82525050565b60e082016000820151613090600085018261304d565b5060208201516130a3602085018261305c565b5060408201516130b6604085018261305c565b5060608201516130c9606085018261305c565b5060808201516130dc608085018261305c565b5060a08201516130ef60a085018261305c565b5060c082015161310260c085018261306b565b50505050565b600060e08201905061311d600083018461307a565b92915050565b60006bffffffffffffffffffffffff82169050919050565b61314481613123565b811461314f57600080fd5b50565b6000813590506131618161313b565b92915050565b60006020828403121561317d5761317c612c55565b5b600061318b84828501613152565b91505092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6131d682612d9d565b810181811067ffffffffffffffff821117156131f5576131f461319e565b5b80604052505050565b6000613208612c4b565b905061321482826131cd565b919050565b600067ffffffffffffffff8211156132345761323361319e565b5b61323d82612d9d565b9050602081019050919050565b82818337600083830152505050565b600061326c61326784613219565b6131fe565b90508281526020810184848401111561328857613287613199565b5b61329384828561324a565b509392505050565b600082601f8301126132b0576132af613194565b5b81356132c0848260208601613259565b91505092915050565b6000602082840312156132df576132de612c55565b5b600082013567ffffffffffffffff8111156132fd576132fc612c5a565b5b6133098482850161329b565b91505092915050565b61331b81612ce4565b811461332657600080fd5b50565b60008135905061333881613312565b92915050565b6000806040838503121561335557613354612c55565b5b600061336385828601612ed5565b925050602061337485828601613329565b9150509250929050565b61338781612f2a565b811461339257600080fd5b50565b6000813590506133a48161337e565b92915050565b6000602082840312156133c0576133bf612c55565b5b60006133ce84828501613395565b91505092915050565b600067ffffffffffffffff8211156133f2576133f161319e565b5b6133fb82612d9d565b9050602081019050919050565b600061341b613416846133d7565b6131fe565b90508281526020810184848401111561343757613436613199565b5b61344284828561324a565b509392505050565b600082601f83011261345f5761345e613194565b5b813561346f848260208601613408565b91505092915050565b6000806000806080858703121561349257613491612c55565b5b60006134a087828801612ed5565b94505060206134b187828801612ed5565b93505060406134c287828801612e20565b925050606085013567ffffffffffffffff8111156134e3576134e2612c5a565b5b6134ef8782880161344a565b91505092959194509250565b6000806040838503121561351257613511612c55565b5b600061352085828601612ed5565b925050602061353185828601612ed5565b9150509250929050565b60006020828403121561355157613550612c55565b5b600061355f84828501613329565b91505092915050565b6000806040838503121561357f5761357e612c55565b5b600061358d85828601612ed5565b925050602061359e85828601613395565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806135ef57607f821691505b602082108103613602576136016135a8565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061364282612d1a565b915061364d83612d1a565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561368657613685613608565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006136cb82612d1a565b91506136d683612d1a565b9250826136e6576136e5613691565b5b828204905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613727602083612d59565b9150613732826136f1565b602082019050919050565b600060208201905081810360008301526137568161371a565b9050919050565b600061376882612d1a565b915061377383612d1a565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156137a8576137a7613608565b5b828201905092915050565b60006137be82612d1a565b91506137c983612d1a565b9250828210156137dc576137db613608565b5b828203905092915050565b600067ffffffffffffffff82169050919050565b6000613806826137e7565b9150613811836137e7565b92508267ffffffffffffffff0382111561382e5761382d613608565b5b828201905092915050565b600081905092915050565b600061384f82612d4e565b6138598185613839565b9350613869818560208601612d6a565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b60006138ab600583613839565b91506138b682613875565b600582019050919050565b60006138cd8285613844565b91506138d98284613844565b91506138e48261389e565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061394c602683612d59565b9150613957826138f0565b604082019050919050565b6000602082019050818103600083015261397b8161393f565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e6365000000600082015250565b60006139b8601d83612d59565b91506139c382613982565b602082019050919050565b600060208201905081810360008301526139e7816139ab565b9050919050565b600081905092915050565b50565b6000613a096000836139ee565b9150613a14826139f9565b600082019050919050565b6000613a2a826139fc565b9150819050919050565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b6000613a90603a83612d59565b9150613a9b82613a34565b604082019050919050565b60006020820190508181036000830152613abf81613a83565b9050919050565b7f455243323938313a20726f79616c7479206665652077696c6c2065786365656460008201527f2073616c65507269636500000000000000000000000000000000000000000000602082015250565b6000613b22602a83612d59565b9150613b2d82613ac6565b604082019050919050565b60006020820190508181036000830152613b5181613b15565b9050919050565b7f455243323938313a20696e76616c696420726563656976657200000000000000600082015250565b6000613b8e601983612d59565b9150613b9982613b58565b602082019050919050565b60006020820190508181036000830152613bbd81613b81565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000613beb82613bc4565b613bf58185613bcf565b9350613c05818560208601612d6a565b613c0e81612d9d565b840191505092915050565b6000608082019050613c2e6000830187612e94565b613c3b6020830186612e94565b613c486040830185612d24565b8181036060830152613c5a8184613be0565b905095945050505050565b600081519050613c7481612c8b565b92915050565b600060208284031215613c9057613c8f612c55565b5b6000613c9e84828501613c65565b91505092915050565b6000613cb282612d1a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613ce457613ce3613608565b5b600182019050919050565b6000613cfa82612d1a565b9150613d0583612d1a565b925082613d1557613d14613691565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220445e6bbf23bbf955bdadfb673bf9555cbdf05589bf26100d70974e26eae0d4f464736f6c634300080d0033

Deployed Bytecode

0x6080604052600436106101d85760003560e01c806363553e7c11610102578063a71bbebe11610095578063e985e9c511610064578063e985e9c5146106a0578063ef6b141a146106dd578063f2fde38b14610706578063fe54c29c1461072f576101d8565b8063a71bbebe146105f3578063b88d4fde1461060f578063c87b56dd14610638578063d4a6762314610675576101d8565b8063750521f5116100d1578063750521f51461054b5780638da5cb5b1461057457806395d89b411461059f578063a22cb465146105ca576101d8565b806363553e7c146104a3578063653a819e146104ce57806370a08231146104f7578063715018a614610534576101d8565b806322f4596f1161017a57806342842e0e1161014957806342842e0e146103d55780634df22a54146103fe5780634df8bb45146104295780636352211e14610466576101d8565b806322f4596f1461032c57806323b872dd146103575780632a55205a146103805780633ccfd60b146103be576101d8565b8063081812fc116101b6578063081812fc14610270578063095ea7b3146102ad5780630e2351e2146102d657806318160ddd14610301576101d8565b806301ffc9a7146101dd5780630387da421461021a57806306fdde0314610245575b600080fd5b3480156101e957600080fd5b5061020460048036038101906101ff9190612cb7565b610758565b6040516102119190612cff565b60405180910390f35b34801561022657600080fd5b5061022f61083a565b60405161023c9190612d33565b60405180910390f35b34801561025157600080fd5b5061025a61085e565b6040516102679190612de7565b60405180910390f35b34801561027c57600080fd5b5061029760048036038101906102929190612e35565b6108f0565b6040516102a49190612ea3565b60405180910390f35b3480156102b957600080fd5b506102d460048036038101906102cf9190612eea565b61096c565b005b3480156102e257600080fd5b506102eb610b12565b6040516102f89190612f49565b60405180910390f35b34801561030d57600080fd5b50610316610b36565b6040516103239190612d33565b60405180910390f35b34801561033857600080fd5b50610341610b4d565b60405161034e9190612f49565b60405180910390f35b34801561036357600080fd5b5061037e60048036038101906103799190612f64565b610b71565b005b34801561038c57600080fd5b506103a760048036038101906103a29190612fb7565b610b81565b6040516103b5929190612ff7565b60405180910390f35b3480156103ca57600080fd5b506103d3610d6b565b005b3480156103e157600080fd5b506103fc60048036038101906103f79190612f64565b610e12565b005b34801561040a57600080fd5b50610413610e32565b6040516104209190612cff565b60405180910390f35b34801561043557600080fd5b50610450600480360381019061044b9190613020565b610e45565b60405161045d9190613108565b60405180910390f35b34801561047257600080fd5b5061048d60048036038101906104889190612e35565b610f45565b60405161049a9190612ea3565b60405180910390f35b3480156104af57600080fd5b506104b8610f57565b6040516104c59190612f49565b60405180910390f35b3480156104da57600080fd5b506104f560048036038101906104f09190613167565b610f7b565b005b34801561050357600080fd5b5061051e60048036038101906105199190613020565b61100b565b60405161052b9190612d33565b60405180910390f35b34801561054057600080fd5b506105496110c3565b005b34801561055757600080fd5b50610572600480360381019061056d91906132c9565b61114b565b005b34801561058057600080fd5b506105896111e1565b6040516105969190612ea3565b60405180910390f35b3480156105ab57600080fd5b506105b461120b565b6040516105c19190612de7565b60405180910390f35b3480156105d657600080fd5b506105f160048036038101906105ec919061333e565b61129d565b005b61060d600480360381019061060891906133aa565b611414565b005b34801561061b57600080fd5b5061063660048036038101906106319190613478565b611693565b005b34801561064457600080fd5b5061065f600480360381019061065a9190612e35565b611706565b60405161066c9190612de7565b60405180910390f35b34801561068157600080fd5b5061068a611808565b6040516106979190612de7565b60405180910390f35b3480156106ac57600080fd5b506106c760048036038101906106c291906134fb565b611896565b6040516106d49190612cff565b60405180910390f35b3480156106e957600080fd5b5061070460048036038101906106ff919061353b565b61192a565b005b34801561071257600080fd5b5061072d60048036038101906107289190613020565b6119c3565b005b34801561073b57600080fd5b5061075660048036038101906107519190613568565b611aba565b005b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061082357507fc21b8f28000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610833575061083282611bc2565b5b9050919050565b7f000000000000000000000000000000000000000000000000001b5b1bf4c5400081565b60606004805461086d906135d7565b80601f0160208091040260200160405190810160405280929190818152602001828054610899906135d7565b80156108e65780601f106108bb576101008083540402835291602001916108e6565b820191906000526020600020905b8154815290600101906020018083116108c957829003601f168201915b5050505050905090565b60006108fb82611c54565b610931576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6008600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061097782611cb3565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036109de576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166109fd611d7f565b73ffffffffffffffffffffffffffffffffffffffff1614610a6057610a2981610a24611d7f565b611896565b610a5f576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826008600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b7f000000000000000000000000000000000000000000000000000000000000000f81565b6000610b40611d87565b6003546002540303905090565b7f000000000000000000000000000000000000000000000000000000000000271081565b610b7c838383611d8c565b505050565b6000806000600160008681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1603610d165760006040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b6000610d20612133565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff1686610d4c9190613637565b610d5691906136c0565b90508160000151819350935050509250929050565b610d7361213d565b73ffffffffffffffffffffffffffffffffffffffff16610d916111e1565b73ffffffffffffffffffffffffffffffffffffffff1614610de7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dde9061373d565b60405180910390fd5b610e10473373ffffffffffffffffffffffffffffffffffffffff1661214590919063ffffffff16565b565b610e2d83838360405180602001604052806000815250611693565b505050565b600a60149054906101000a900460ff1681565b610e4d612b4b565b6040518060e001604052807f000000000000000000000000000000000000000000000000001b5b1bf4c5400081526020017f000000000000000000000000000000000000000000000000000000000000000f63ffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000f63ffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000271063ffffffff168152602001610f0a612239565b63ffffffff168152602001610f1e8461224c565b63ffffffff168152602001600a60149054906101000a900460ff1615158152509050919050565b6000610f5082611cb3565b9050919050565b7f000000000000000000000000000000000000000000000000000000000000000f81565b610f8361213d565b73ffffffffffffffffffffffffffffffffffffffff16610fa16111e1565b73ffffffffffffffffffffffffffffffffffffffff1614610ff7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fee9061373d565b60405180910390fd5b6110086110026111e1565b82612299565b50565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611072576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6110cb61213d565b73ffffffffffffffffffffffffffffffffffffffff166110e96111e1565b73ffffffffffffffffffffffffffffffffffffffff161461113f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111369061373d565b60405180910390fd5b611149600061242d565b565b61115361213d565b73ffffffffffffffffffffffffffffffffffffffff166111716111e1565b73ffffffffffffffffffffffffffffffffffffffff16146111c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111be9061373d565b60405180910390fd5b80600b90805190602001906111dd929190612ba8565b5050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606005805461121a906135d7565b80601f0160208091040260200160405190810160405280929190818152602001828054611246906135d7565b80156112935780601f1061126857610100808354040283529160200191611293565b820191906000526020600020905b81548152906001019060200180831161127657829003601f168201915b5050505050905090565b6112a5611d7f565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611309576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060096000611316611d7f565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166113c3611d7f565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516114089190612cff565b60405180910390a35050565b600a60149054906101000a900460ff1661145a576040517f1e3177ee00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000271063ffffffff16611489612239565b8263ffffffff1661149a919061375d565b11156114d2576040517f57bb669800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000f63ffffffff168163ffffffff161115611538576040517f552d9c8300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f000000000000000000000000000000000000000000000000001b5b1bf4c540008263ffffffff1661156c9190613637565b905060006115793361224c565b905060008167ffffffffffffffff16036115bc577f000000000000000000000000000000000000000000000000001b5b1bf4c54000826115b991906137b3565b91505b8263ffffffff16816115ce91906137fb565b90506115da33826124f3565b7f000000000000000000000000000000000000000000000000000000000000000f63ffffffff168167ffffffffffffffff161115611644576040517f171b8e9400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8134101561167e576040517f9cb10c3c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61168e338463ffffffff166125a9565b505050565b61169e848484611d8c565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611700576116c9848484846125c7565b6116ff576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b606061171182611c54565b611747576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600b8054611756906135d7565b80601f0160208091040260200160405190810160405280929190818152602001828054611782906135d7565b80156117cf5780601f106117a4576101008083540402835291602001916117cf565b820191906000526020600020905b8154815290600101906020018083116117b257829003601f168201915b50505050509050806117e084612717565b6040516020016117f19291906138c1565b604051602081830303815290604052915050919050565b600b8054611815906135d7565b80601f0160208091040260200160405190810160405280929190818152602001828054611841906135d7565b801561188e5780601f106118635761010080835404028352916020019161188e565b820191906000526020600020905b81548152906001019060200180831161187157829003601f168201915b505050505081565b6000600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61193261213d565b73ffffffffffffffffffffffffffffffffffffffff166119506111e1565b73ffffffffffffffffffffffffffffffffffffffff16146119a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161199d9061373d565b60405180910390fd5b80600a60146101000a81548160ff02191690831515021790555050565b6119cb61213d565b73ffffffffffffffffffffffffffffffffffffffff166119e96111e1565b73ffffffffffffffffffffffffffffffffffffffff1614611a3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a369061373d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611aae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aa590613962565b60405180910390fd5b611ab78161242d565b50565b611ac261213d565b73ffffffffffffffffffffffffffffffffffffffff16611ae06111e1565b73ffffffffffffffffffffffffffffffffffffffff1614611b36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b2d9061373d565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000271063ffffffff16611b65612239565b8263ffffffff16611b76919061375d565b1115611bae576040517f57bb669800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611bbe828263ffffffff166125a9565b5050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611c1d57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611c4d5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600081611c5f611d87565b11158015611c6e575060025482105b8015611cac575060007c0100000000000000000000000000000000000000000000000000000000600660008581526020019081526020016000205416145b9050919050565b60008082905080611cc2611d87565b11611d4857600254811015611d475760006006600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603611d45575b60008103611d3b576006600083600190039350838152602001908152602001600020549050611d11565b8092505050611d7a565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600033905090565b600090565b6000611d9782611cb3565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611dfe576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff16611e1f611d7f565b73ffffffffffffffffffffffffffffffffffffffff161480611e4e5750611e4d85611e48611d7f565b611896565b5b80611e935750611e5c611d7f565b73ffffffffffffffffffffffffffffffffffffffff16611e7b846108f0565b73ffffffffffffffffffffffffffffffffffffffff16145b905080611ecc576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611f32576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f3f8585856001612877565b6008600084815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b61203c8661287d565b1717600660008581526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008316036120c457600060018401905060006006600083815260200190815260200160002054036120c25760025481146120c1578260066000838152602001908152602001600020819055505b5b505b828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461212c8585856001612887565b5050505050565b6000612710905090565b600033905090565b80471015612188576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161217f906139ce565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff16826040516121ae90613a1f565b60006040518083038185875af1925050503d80600081146121eb576040519150601f19603f3d011682016040523d82523d6000602084013e6121f0565b606091505b5050905080612234576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161222b90613aa6565b60405180910390fd5b505050565b6000612243611d87565b60025403905090565b600060c0600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c9050919050565b6122a1612133565b6bffffffffffffffffffffffff16816bffffffffffffffffffffffff1611156122ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122f690613b38565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361236e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161236590613ba4565b60405180910390fd5b60405180604001604052808373ffffffffffffffffffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff168152506000808201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055509050505050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600082905060c081901b77ffffffffffffffffffffffffffffffffffffffffffffffff831617915081600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050505050565b6125c382826040518060200160405280600081525061288d565b5050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026125ed611d7f565b8786866040518563ffffffff1660e01b815260040161260f9493929190613c19565b6020604051808303816000875af192505050801561264b57506040513d601f19601f820116820180604052508101906126489190613c7a565b60015b6126c4573d806000811461267b576040519150601f19603f3d011682016040523d82523d6000602084013e612680565b606091505b5060008151036126bc576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60606000820361275e576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612872565b600082905060005b6000821461279057808061277990613ca7565b915050600a8261278991906136c0565b9150612766565b60008167ffffffffffffffff8111156127ac576127ab61319e565b5b6040519080825280601f01601f1916602001820160405280156127de5781602001600182028036833780820191505090505b5090505b6000851461286b576001826127f791906137b3565b9150600a856128069190613cef565b6030612812919061375d565b60f81b81838151811061282857612827613d20565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561286491906136c0565b94506127e2565b8093505050505b919050565b50505050565b6000819050919050565b50505050565b60006002549050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036128fa576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008303612934576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6129416000858386612877565b600160406001901b178302600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e16129a660018514612b41565b901b60a042901b6129b68661287d565b1717600660008381526020019081526020016000208190555060008190506000848201905060008673ffffffffffffffffffffffffffffffffffffffff163b14612aba575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612a6a60008784806001019550876125c7565b612aa0576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8082106129fb578260025414612ab557600080fd5b612b25565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4808210612abb575b816002819055505050612b3b6000858386612887565b50505050565b6000819050919050565b6040518060e0016040528060008152602001600063ffffffff168152602001600063ffffffff168152602001600063ffffffff168152602001600063ffffffff168152602001600063ffffffff1681526020016000151581525090565b828054612bb4906135d7565b90600052602060002090601f016020900481019282612bd65760008555612c1d565b82601f10612bef57805160ff1916838001178555612c1d565b82800160010185558215612c1d579182015b82811115612c1c578251825591602001919060010190612c01565b5b509050612c2a9190612c2e565b5090565b5b80821115612c47576000816000905550600101612c2f565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612c9481612c5f565b8114612c9f57600080fd5b50565b600081359050612cb181612c8b565b92915050565b600060208284031215612ccd57612ccc612c55565b5b6000612cdb84828501612ca2565b91505092915050565b60008115159050919050565b612cf981612ce4565b82525050565b6000602082019050612d146000830184612cf0565b92915050565b6000819050919050565b612d2d81612d1a565b82525050565b6000602082019050612d486000830184612d24565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612d88578082015181840152602081019050612d6d565b83811115612d97576000848401525b50505050565b6000601f19601f8301169050919050565b6000612db982612d4e565b612dc38185612d59565b9350612dd3818560208601612d6a565b612ddc81612d9d565b840191505092915050565b60006020820190508181036000830152612e018184612dae565b905092915050565b612e1281612d1a565b8114612e1d57600080fd5b50565b600081359050612e2f81612e09565b92915050565b600060208284031215612e4b57612e4a612c55565b5b6000612e5984828501612e20565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612e8d82612e62565b9050919050565b612e9d81612e82565b82525050565b6000602082019050612eb86000830184612e94565b92915050565b612ec781612e82565b8114612ed257600080fd5b50565b600081359050612ee481612ebe565b92915050565b60008060408385031215612f0157612f00612c55565b5b6000612f0f85828601612ed5565b9250506020612f2085828601612e20565b9150509250929050565b600063ffffffff82169050919050565b612f4381612f2a565b82525050565b6000602082019050612f5e6000830184612f3a565b92915050565b600080600060608486031215612f7d57612f7c612c55565b5b6000612f8b86828701612ed5565b9350506020612f9c86828701612ed5565b9250506040612fad86828701612e20565b9150509250925092565b60008060408385031215612fce57612fcd612c55565b5b6000612fdc85828601612e20565b9250506020612fed85828601612e20565b9150509250929050565b600060408201905061300c6000830185612e94565b6130196020830184612d24565b9392505050565b60006020828403121561303657613035612c55565b5b600061304484828501612ed5565b91505092915050565b61305681612d1a565b82525050565b61306581612f2a565b82525050565b61307481612ce4565b82525050565b60e082016000820151613090600085018261304d565b5060208201516130a3602085018261305c565b5060408201516130b6604085018261305c565b5060608201516130c9606085018261305c565b5060808201516130dc608085018261305c565b5060a08201516130ef60a085018261305c565b5060c082015161310260c085018261306b565b50505050565b600060e08201905061311d600083018461307a565b92915050565b60006bffffffffffffffffffffffff82169050919050565b61314481613123565b811461314f57600080fd5b50565b6000813590506131618161313b565b92915050565b60006020828403121561317d5761317c612c55565b5b600061318b84828501613152565b91505092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6131d682612d9d565b810181811067ffffffffffffffff821117156131f5576131f461319e565b5b80604052505050565b6000613208612c4b565b905061321482826131cd565b919050565b600067ffffffffffffffff8211156132345761323361319e565b5b61323d82612d9d565b9050602081019050919050565b82818337600083830152505050565b600061326c61326784613219565b6131fe565b90508281526020810184848401111561328857613287613199565b5b61329384828561324a565b509392505050565b600082601f8301126132b0576132af613194565b5b81356132c0848260208601613259565b91505092915050565b6000602082840312156132df576132de612c55565b5b600082013567ffffffffffffffff8111156132fd576132fc612c5a565b5b6133098482850161329b565b91505092915050565b61331b81612ce4565b811461332657600080fd5b50565b60008135905061333881613312565b92915050565b6000806040838503121561335557613354612c55565b5b600061336385828601612ed5565b925050602061337485828601613329565b9150509250929050565b61338781612f2a565b811461339257600080fd5b50565b6000813590506133a48161337e565b92915050565b6000602082840312156133c0576133bf612c55565b5b60006133ce84828501613395565b91505092915050565b600067ffffffffffffffff8211156133f2576133f161319e565b5b6133fb82612d9d565b9050602081019050919050565b600061341b613416846133d7565b6131fe565b90508281526020810184848401111561343757613436613199565b5b61344284828561324a565b509392505050565b600082601f83011261345f5761345e613194565b5b813561346f848260208601613408565b91505092915050565b6000806000806080858703121561349257613491612c55565b5b60006134a087828801612ed5565b94505060206134b187828801612ed5565b93505060406134c287828801612e20565b925050606085013567ffffffffffffffff8111156134e3576134e2612c5a565b5b6134ef8782880161344a565b91505092959194509250565b6000806040838503121561351257613511612c55565b5b600061352085828601612ed5565b925050602061353185828601612ed5565b9150509250929050565b60006020828403121561355157613550612c55565b5b600061355f84828501613329565b91505092915050565b6000806040838503121561357f5761357e612c55565b5b600061358d85828601612ed5565b925050602061359e85828601613395565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806135ef57607f821691505b602082108103613602576136016135a8565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061364282612d1a565b915061364d83612d1a565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561368657613685613608565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006136cb82612d1a565b91506136d683612d1a565b9250826136e6576136e5613691565b5b828204905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613727602083612d59565b9150613732826136f1565b602082019050919050565b600060208201905081810360008301526137568161371a565b9050919050565b600061376882612d1a565b915061377383612d1a565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156137a8576137a7613608565b5b828201905092915050565b60006137be82612d1a565b91506137c983612d1a565b9250828210156137dc576137db613608565b5b828203905092915050565b600067ffffffffffffffff82169050919050565b6000613806826137e7565b9150613811836137e7565b92508267ffffffffffffffff0382111561382e5761382d613608565b5b828201905092915050565b600081905092915050565b600061384f82612d4e565b6138598185613839565b9350613869818560208601612d6a565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b60006138ab600583613839565b91506138b682613875565b600582019050919050565b60006138cd8285613844565b91506138d98284613844565b91506138e48261389e565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061394c602683612d59565b9150613957826138f0565b604082019050919050565b6000602082019050818103600083015261397b8161393f565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e6365000000600082015250565b60006139b8601d83612d59565b91506139c382613982565b602082019050919050565b600060208201905081810360008301526139e7816139ab565b9050919050565b600081905092915050565b50565b6000613a096000836139ee565b9150613a14826139f9565b600082019050919050565b6000613a2a826139fc565b9150819050919050565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b6000613a90603a83612d59565b9150613a9b82613a34565b604082019050919050565b60006020820190508181036000830152613abf81613a83565b9050919050565b7f455243323938313a20726f79616c7479206665652077696c6c2065786365656460008201527f2073616c65507269636500000000000000000000000000000000000000000000602082015250565b6000613b22602a83612d59565b9150613b2d82613ac6565b604082019050919050565b60006020820190508181036000830152613b5181613b15565b9050919050565b7f455243323938313a20696e76616c696420726563656976657200000000000000600082015250565b6000613b8e601983612d59565b9150613b9982613b58565b602082019050919050565b60006020820190508181036000830152613bbd81613b81565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000613beb82613bc4565b613bf58185613bcf565b9350613c05818560208601612d6a565b613c0e81612d9d565b840191505092915050565b6000608082019050613c2e6000830187612e94565b613c3b6020830186612e94565b613c486040830185612d24565b8181036060830152613c5a8184613be0565b905095945050505050565b600081519050613c7481612c8b565b92915050565b600060208284031215613c9057613c8f612c55565b5b6000613c9e84828501613c65565b91505092915050565b6000613cb282612d1a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613ce457613ce3613608565b5b600182019050919050565b6000613cfa82612d1a565b9150613d0583612d1a565b925082613d1557613d14613691565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220445e6bbf23bbf955bdadfb673bf9555cbdf05589bf26100d70974e26eae0d4f464736f6c634300080d0033

Deployed Bytecode Sourcemap

610:3149:12:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2807:300;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;770:50;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;9768:98:13;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;11769:200;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;11245:463;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;920:41:12;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3963:309:13;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;871:42:12;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;12629:164:13;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1671:432:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;3646:110:12;;;;;;;;;;;;;:::i;:::-;;12859:179:13;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;970:20:12;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2054:442;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;9564:142:13;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;827:37:12;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3308:125;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;5546:221:13;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1668:101:0;;;;;;;;;;;;;:::i;:::-;;3539:99:12;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1036:85:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;9930:102:13;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;12036:303;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1139:689:12;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;13104:385:13;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2504:295:12;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;997:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;12405:162:13;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3441:90:12;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1918:198:0;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3115:185:12;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2807:300;2910:4;2962:26;2947:41;;;:11;:41;;;;:99;;;;3020:26;3005:41;;;:11;:41;;;;2947:99;:152;;;;3063:36;3087:11;3063:23;:36::i;:::-;2947:152;2927:172;;2807:300;;;:::o;770:50::-;;;:::o;9768:98:13:-;9822:13;9854:5;9847:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9768:98;:::o;11769:200::-;11837:7;11861:16;11869:7;11861;:16::i;:::-;11856:64;;11886:34;;;;;;;;;;;;;;11856:64;11938:15;:24;11954:7;11938:24;;;;;;;;;;;;;;;;;;;;;11931:31;;11769:200;;;:::o;11245:463::-;11317:13;11349:27;11368:7;11349:18;:27::i;:::-;11317:61;;11398:5;11392:11;;:2;:11;;;11388:48;;11412:24;;;;;;;;;;;;;;11388:48;11474:5;11451:28;;:19;:17;:19::i;:::-;:28;;;11447:172;;11498:44;11515:5;11522:19;:17;:19::i;:::-;11498:16;:44::i;:::-;11493:126;;11569:35;;;;;;;;;;;;;;11493:126;11447:172;11656:2;11629:15;:24;11645:7;11629:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;11693:7;11689:2;11673:28;;11682:5;11673:28;;;;;;;;;;;;11307:401;11245:463;;:::o;920:41:12:-;;;:::o;3963:309:13:-;4016:7;4240:15;:13;:15::i;:::-;4225:12;;4209:13;;:28;:46;4202:53;;3963:309;:::o;871:42:12:-;;;:::o;12629:164:13:-;12758:28;12768:4;12774:2;12778:7;12758:9;:28::i;:::-;12629:164;;;:::o;1671:432:5:-;1768:7;1777;1796:26;1825:17;:27;1843:8;1825:27;;;;;;;;;;;1796:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1895:1;1867:30;;:7;:16;;;:30;;;1863:90;;1923:19;1913:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1863:90;1963:21;2028:17;:15;:17::i;:::-;1987:58;;2001:7;:23;;;1988:36;;:10;:36;;;;:::i;:::-;1987:58;;;;:::i;:::-;1963:82;;2064:7;:16;;;2082:13;2056:40;;;;;;1671:432;;;;;:::o;3646:110:12:-;1259:12:0;:10;:12::i;:::-;1248:23;;:7;:5;:7::i;:::-;:23;;;1240:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;3696:52:12::1;3726:21;3704:10;3696:29;;;;:52;;;;:::i;:::-;3646:110::o:0;12859:179:13:-;12992:39;13009:4;13015:2;13019:7;12992:39;;;;;;;;;;;;:16;:39::i;:::-;12859:179;;;:::o;970:20:12:-;;;;;;;;;;;;;:::o;2054:442::-;2109:12;;:::i;:::-;2154:334;;;;;;;;2190:10;2154:334;;;;2228:8;2154:334;;;;;;2268:12;2154:334;;;;;;2310:10;2154:334;;;;;;2359:22;:20;:22::i;:::-;2154:334;;;;;;2420:15;2428:6;2420:7;:15::i;:::-;2154:334;;;;;;2464:8;;;;;;;;;;;2154:334;;;;;2134:354;;2054:442;;;:::o;9564:142:13:-;9628:7;9670:27;9689:7;9670:18;:27::i;:::-;9647:52;;9564:142;;;:::o;827:37:12:-;;;:::o;3308:125::-;1259:12:0;:10;:12::i;:::-;1248:23;;:7;:5;:7::i;:::-;:23;;;1240:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;3384:41:12::1;3403:7;:5;:7::i;:::-;3412:12;3384:18;:41::i;:::-;3308:125:::0;:::o;5546:221:13:-;5610:7;5650:1;5633:19;;:5;:19;;;5629:60;;5661:28;;;;;;;;;;;;;;5629:60;1017:13;5706:18;:25;5725:5;5706:25;;;;;;;;;;;;;;;;:54;5699:61;;5546:221;;;:::o;1668:101:0:-;1259:12;:10;:12::i;:::-;1248:23;;:7;:5;:7::i;:::-;:23;;;1240:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;1732:30:::1;1759:1;1732:18;:30::i;:::-;1668:101::o:0;3539:99:12:-;1259:12:0;:10;:12::i;:::-;1248:23;;:7;:5;:7::i;:::-;:23;;;1240:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;3627:3:12::1;3612:12;:18;;;;;;;;;;;;:::i;:::-;;3539:99:::0;:::o;1036:85:0:-;1082:7;1108:6;;;;;;;;;;;1101:13;;1036:85;:::o;9930:102:13:-;9986:13;10018:7;10011:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9930:102;:::o;12036:303::-;12146:19;:17;:19::i;:::-;12134:31;;:8;:31;;;12130:61;;12174:17;;;;;;;;;;;;;;12130:61;12254:8;12202:18;:39;12221:19;:17;:19::i;:::-;12202:39;;;;;;;;;;;;;;;:49;12242:8;12202:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;12313:8;12277:55;;12292:19;:17;:19::i;:::-;12277:55;;;12323:8;12277:55;;;;;;:::i;:::-;;;;;;;;12036:303;;:::o;1139:689:12:-;1201:8;;;;;;;;;;;1196:43;;1218:21;;;;;;;;;;;;;;1196:43;1280:10;1254:36;;1263:14;:12;:14::i;:::-;1254:6;:23;;;;;;:::i;:::-;:36;1250:71;;;1299:22;;;;;;;;;;;;;;1250:71;1345:8;1336:17;;:6;:17;;;1332:59;;;1362:29;;;;;;;;;;;;;;1332:59;1404:21;1437:10;1428:6;:19;;;;;;:::i;:::-;1404:43;;1458:17;1478:19;1486:10;1478:7;:19::i;:::-;1458:39;;1526:1;1512:10;:15;;;1508:48;;1546:10;1529:27;;;;;:::i;:::-;;;1508:48;1583:6;1569:20;;;;;;;:::i;:::-;;;1600:31;1608:10;1620;1600:7;:31::i;:::-;1659:12;1646:25;;:10;:25;;;1642:62;;;1680:24;;;;;;;;;;;;;;1642:62;1733:13;1721:9;:25;1717:61;;;1755:23;;;;;;;;;;;;;;1717:61;1791:29;1801:10;1813:6;1791:29;;:9;:29::i;:::-;1185:643;;1139:689;:::o;13104:385:13:-;13265:28;13275:4;13281:2;13285:7;13265:9;:28::i;:::-;13325:1;13307:2;:14;;;:19;13303:180;;13345:56;13376:4;13382:2;13386:7;13395:5;13345:30;:56::i;:::-;13340:143;;13428:40;;;;;;;;;;;;;;13340:143;13303:180;13104:385;;;;:::o;2504:295:12:-;2577:13;2608:16;2616:7;2608;:16::i;:::-;2603:59;;2633:29;;;;;;;;;;;;;;2603:59;2675:21;2699:12;2675:36;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2753:7;2762:18;:7;:16;:18::i;:::-;2736:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;2722:69;;;2504:295;;;:::o;997:31::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;12405:162:13:-;12502:4;12525:18;:25;12544:5;12525:25;;;;;;;;;;;;;;;:35;12551:8;12525:35;;;;;;;;;;;;;;;;;;;;;;;;;12518:42;;12405:162;;;;:::o;3441:90:12:-;1259:12:0;:10;:12::i;:::-;1248:23;;:7;:5;:7::i;:::-;:23;;;1240:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;3516:7:12::1;3505:8;;:18;;;;;;;;;;;;;;;;;;3441:90:::0;:::o;1918:198:0:-;1259:12;:10;:12::i;:::-;1248:23;;:7;:5;:7::i;:::-;:23;;;1240:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;2026:1:::1;2006:22;;:8;:22;;::::0;1998:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;2081:28;2100:8;2081:18;:28::i;:::-;1918:198:::0;:::o;3115:185:12:-;1259:12:0;:10;:12::i;:::-;1248:23;;:7;:5;:7::i;:::-;:23;;;1240:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;3219:10:12::1;3193:36;;3202:14;:12;:14::i;:::-;3193:6;:23;;;;;;:::i;:::-;:36;3189:71;;;3238:22;;;;;;;;;;;;;;3189:71;3271:21;3281:2;3285:6;3271:21;;:9;:21::i;:::-;3115:185:::0;;:::o;4880:607:13:-;4965:4;5275:10;5260:25;;:11;:25;;;;:101;;;;5351:10;5336:25;;:11;:25;;;;5260:101;:177;;;;5427:10;5412:25;;:11;:25;;;;5260:177;5241:196;;4880:607;;;:::o;13735:268::-;13792:4;13846:7;13827:15;:13;:15::i;:::-;:26;;:65;;;;;13879:13;;13869:7;:23;13827:65;:150;;;;;13976:1;1769:8;13929:17;:26;13947:7;13929:26;;;;;;;;;;;;:43;:48;13827:150;13808:169;;13735:268;;;:::o;7141:1105::-;7208:7;7227:12;7242:7;7227:22;;7307:4;7288:15;:13;:15::i;:::-;:23;7284:898;;7340:13;;7333:4;:20;7329:853;;;7377:14;7394:17;:23;7412:4;7394:23;;;;;;;;;;;;7377:40;;7508:1;1769:8;7481:6;:23;:28;7477:687;;7992:111;8009:1;7999:6;:11;7992:111;;8051:17;:25;8069:6;;;;;;;8051:25;;;;;;;;;;;;8042:34;;7992:111;;;8135:6;8128:13;;;;;;7477:687;7355:827;7329:853;7284:898;8208:31;;;;;;;;;;;;;;7141:1105;;;;:::o;27360:103::-;27420:7;27446:10;27439:17;;27360:103;:::o;3502:90::-;3558:7;3502:90;:::o;18835:2460::-;18945:27;18975;18994:7;18975:18;:27::i;:::-;18945:57;;19058:4;19017:45;;19033:19;19017:45;;;19013:86;;19071:28;;;;;;;;;;;;;;19013:86;19110:22;19159:4;19136:27;;:19;:17;:19::i;:::-;:27;;;:86;;;;19179:43;19196:4;19202:19;:17;:19::i;:::-;19179:16;:43::i;:::-;19136:86;:145;;;;19262:19;:17;:19::i;:::-;19238:43;;:20;19250:7;19238:11;:20::i;:::-;:43;;;19136:145;19110:172;;19298:17;19293:66;;19324:35;;;;;;;;;;;;;;19293:66;19387:1;19373:16;;:2;:16;;;19369:52;;19398:23;;;;;;;;;;;;;;19369:52;19432:43;19454:4;19460:2;19464:7;19473:1;19432:21;:43::i;:::-;19545:15;:24;19561:7;19545:24;;;;;;;;;;;;19538:31;;;;;;;;;;;19930:18;:24;19949:4;19930:24;;;;;;;;;;;;;;;;19928:26;;;;;;;;;;;;19998:18;:22;20017:2;19998:22;;;;;;;;;;;;;;;;19996:24;;;;;;;;;;;2045:8;1656:3;20370:15;:41;;20329:21;20347:2;20329:17;:21::i;:::-;:83;:126;20284:17;:26;20302:7;20284:26;;;;;;;;;;;:171;;;;20622:1;2045:8;20572:19;:46;:51;20568:616;;20643:19;20675:1;20665:7;:11;20643:33;;20830:1;20796:17;:30;20814:11;20796:30;;;;;;;;;;;;:35;20792:378;;20932:13;;20917:11;:28;20913:239;;21110:19;21077:17;:30;21095:11;21077:30;;;;;;;;;;;:52;;;;20913:239;20792:378;20625:559;20568:616;21228:7;21224:2;21209:27;;21218:4;21209:27;;;;;;;;;;;;21246:42;21267:4;21273:2;21277:7;21286:1;21246:20;:42::i;:::-;18935:2360;;18835:2460;;;:::o;2378:95:5:-;2436:6;2461:5;2454:12;;2378:95;:::o;640:96:7:-;693:7;719:10;712:17;;640:96;:::o;2412:312:6:-;2526:6;2501:21;:31;;2493:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;2578:12;2596:9;:14;;2618:6;2596:33;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2577:52;;;2647:7;2639:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;2483:241;2412:312;;:::o;4365:279:13:-;4412:7;4612:15;:13;:15::i;:::-;4596:13;;:31;4589:38;;4365:279;:::o;6398:134::-;6453:6;1379:3;6485:18;:25;6504:5;6485:25;;;;;;;;;;;;;;;;:39;;6471:54;;6398:134;;;:::o;2734:327:5:-;2852:17;:15;:17::i;:::-;2836:33;;:12;:33;;;;2828:88;;;;;;;;;;;;:::i;:::-;;;;;;;;;2954:1;2934:22;;:8;:22;;;2926:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;3019:35;;;;;;;;3031:8;3019:35;;;;;;3041:12;3019:35;;;;;2997:19;:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2734:327;;:::o;2270:187:0:-;2343:16;2362:6;;;;;;;;;;;2343:25;;2387:8;2378:6;;:17;;;;;;;;;;;;;;;;;;2441:8;2410:40;;2431:8;2410:40;;;;;;;;;;;;2333:124;2270:187;:::o;6714:350:13:-;6777:14;6794:18;:25;6813:5;6794:25;;;;;;;;;;;;;;;;6777:42;;6829:17;6921:3;6908:16;;1379:3;6989:9;:23;;1520:14;6953:6;:31;6952:61;6943:70;;7051:6;7023:18;:25;7042:5;7023:25;;;;;;;;;;;;;;;:34;;;;6767:297;;6714:350;;:::o;14082:102::-;14150:27;14160:2;14164:8;14150:27;;;;;;;;;;;;:9;:27::i;:::-;14082:102;;:::o;24900:697::-;25058:4;25103:2;25078:45;;;25124:19;:17;:19::i;:::-;25145:4;25151:7;25160:5;25078:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;25074:517;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25373:1;25356:6;:13;:18;25352:229;;25401:40;;;;;;;;;;;;;;25352:229;25541:6;25535:13;25526:6;25522:2;25518:15;25511:38;25074:517;25244:54;;;25234:64;;;:6;:64;;;;25227:71;;;24900:697;;;;;;:::o;328:703:8:-;384:13;610:1;601:5;:10;597:51;;627:10;;;;;;;;;;;;;;;;;;;;;597:51;657:12;672:5;657:20;;687:14;711:75;726:1;718:4;:9;711:75;;743:8;;;;;:::i;:::-;;;;773:2;765:10;;;;;:::i;:::-;;;711:75;;;795:19;827:6;817:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;795:39;;844:150;860:1;851:5;:10;844:150;;887:1;877:11;;;;;:::i;:::-;;;953:2;945:5;:10;;;;:::i;:::-;932:2;:24;;;;:::i;:::-;919:39;;902:6;909;902:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;981:2;972:11;;;;;:::i;:::-;;;844:150;;;1017:6;1003:21;;;;;328:703;;;;:::o;26228:154:13:-;;;;;:::o;10824:144::-;10888:14;10947:5;10937:15;;10824:144;;;:::o;27023:153::-;;;;;:::o;14544:2184::-;14662:20;14685:13;;14662:36;;14726:1;14712:16;;:2;:16;;;14708:48;;14737:19;;;;;;;;;;;;;;14708:48;14782:1;14770:8;:13;14766:44;;14792:18;;;;;;;;;;;;;;14766:44;14821:61;14851:1;14855:2;14859:12;14873:8;14821:21;:61::i;:::-;15414:1;1151:2;15385:1;:25;;15384:31;15372:8;:44;15346:18;:22;15365:2;15346:22;;;;;;;;;;;;;;;;:70;;;;;;;;;;;1913:3;15805:29;15832:1;15820:8;:13;15805:14;:29::i;:::-;:56;;1656:3;15743:15;:41;;15702:21;15720:2;15702:17;:21::i;:::-;:83;:160;15652:17;:31;15670:12;15652:31;;;;;;;;;;;:210;;;;15877:20;15900:12;15877:35;;15926:11;15955:8;15940:12;:23;15926:37;;16000:1;15982:2;:14;;;:19;15978:622;;16021:308;16076:12;16072:2;16051:38;;16068:1;16051:38;;;;;;;;;;;;16116:69;16155:1;16159:2;16163:14;;;;;;16179:5;16116:30;:69::i;:::-;16111:172;;16220:40;;;;;;;;;;;;;;16111:172;16324:3;16309:12;:18;16021:308;;16408:12;16391:13;;:29;16387:43;;16422:8;;;16387:43;15978:622;;;16469:117;16524:14;;;;;;16520:2;16499:40;;16516:1;16499:40;;;;;;;;;;;;16581:3;16566:12;:18;16469:117;;15978:622;16629:12;16613:13;:28;;;;15129:1523;;16661:60;16690:1;16694:2;16698:12;16712:8;16661:20;:60::i;:::-;14652:2076;14544:2184;;;:::o;11050:138::-;11108:14;11167:5;11157:15;;11050:138;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:75:15:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:77::-;1555:7;1584:5;1573:16;;1518:77;;;:::o;1601:118::-;1688:24;1706:5;1688:24;:::i;:::-;1683:3;1676:37;1601:118;;:::o;1725:222::-;1818:4;1856:2;1845:9;1841:18;1833:26;;1869:71;1937:1;1926:9;1922:17;1913:6;1869:71;:::i;:::-;1725:222;;;;:::o;1953:99::-;2005:6;2039:5;2033:12;2023:22;;1953:99;;;:::o;2058:169::-;2142:11;2176:6;2171:3;2164:19;2216:4;2211:3;2207:14;2192:29;;2058:169;;;;:::o;2233:307::-;2301:1;2311:113;2325:6;2322:1;2319:13;2311:113;;;2410:1;2405:3;2401:11;2395:18;2391:1;2386:3;2382:11;2375:39;2347:2;2344:1;2340:10;2335:15;;2311:113;;;2442:6;2439:1;2436:13;2433:101;;;2522:1;2513:6;2508:3;2504:16;2497:27;2433:101;2282:258;2233:307;;;:::o;2546:102::-;2587:6;2638:2;2634:7;2629:2;2622:5;2618:14;2614:28;2604:38;;2546:102;;;:::o;2654:364::-;2742:3;2770:39;2803:5;2770:39;:::i;:::-;2825:71;2889:6;2884:3;2825:71;:::i;:::-;2818:78;;2905:52;2950:6;2945:3;2938:4;2931:5;2927:16;2905:52;:::i;:::-;2982:29;3004:6;2982:29;:::i;:::-;2977:3;2973:39;2966:46;;2746:272;2654:364;;;;:::o;3024:313::-;3137:4;3175:2;3164:9;3160:18;3152:26;;3224:9;3218:4;3214:20;3210:1;3199:9;3195:17;3188:47;3252:78;3325:4;3316:6;3252:78;:::i;:::-;3244:86;;3024:313;;;;:::o;3343:122::-;3416:24;3434:5;3416:24;:::i;:::-;3409:5;3406:35;3396:63;;3455:1;3452;3445:12;3396:63;3343:122;:::o;3471:139::-;3517:5;3555:6;3542:20;3533:29;;3571:33;3598:5;3571:33;:::i;:::-;3471:139;;;;:::o;3616:329::-;3675:6;3724:2;3712:9;3703:7;3699:23;3695:32;3692:119;;;3730:79;;:::i;:::-;3692:119;3850:1;3875:53;3920:7;3911:6;3900:9;3896:22;3875:53;:::i;:::-;3865:63;;3821:117;3616:329;;;;:::o;3951:126::-;3988:7;4028:42;4021:5;4017:54;4006:65;;3951:126;;;:::o;4083:96::-;4120:7;4149:24;4167:5;4149:24;:::i;:::-;4138:35;;4083:96;;;:::o;4185:118::-;4272:24;4290:5;4272:24;:::i;:::-;4267:3;4260:37;4185:118;;:::o;4309:222::-;4402:4;4440:2;4429:9;4425:18;4417:26;;4453:71;4521:1;4510:9;4506:17;4497:6;4453:71;:::i;:::-;4309:222;;;;:::o;4537:122::-;4610:24;4628:5;4610:24;:::i;:::-;4603:5;4600:35;4590:63;;4649:1;4646;4639:12;4590:63;4537:122;:::o;4665:139::-;4711:5;4749:6;4736:20;4727:29;;4765:33;4792:5;4765:33;:::i;:::-;4665:139;;;;:::o;4810:474::-;4878:6;4886;4935:2;4923:9;4914:7;4910:23;4906:32;4903:119;;;4941:79;;:::i;:::-;4903:119;5061:1;5086:53;5131:7;5122:6;5111:9;5107:22;5086:53;:::i;:::-;5076:63;;5032:117;5188:2;5214:53;5259:7;5250:6;5239:9;5235:22;5214:53;:::i;:::-;5204:63;;5159:118;4810:474;;;;;:::o;5290:93::-;5326:7;5366:10;5359:5;5355:22;5344:33;;5290:93;;;:::o;5389:115::-;5474:23;5491:5;5474:23;:::i;:::-;5469:3;5462:36;5389:115;;:::o;5510:218::-;5601:4;5639:2;5628:9;5624:18;5616:26;;5652:69;5718:1;5707:9;5703:17;5694:6;5652:69;:::i;:::-;5510:218;;;;:::o;5734:619::-;5811:6;5819;5827;5876:2;5864:9;5855:7;5851:23;5847:32;5844:119;;;5882:79;;:::i;:::-;5844:119;6002:1;6027:53;6072:7;6063:6;6052:9;6048:22;6027:53;:::i;:::-;6017:63;;5973:117;6129:2;6155:53;6200:7;6191:6;6180:9;6176:22;6155:53;:::i;:::-;6145:63;;6100:118;6257:2;6283:53;6328:7;6319:6;6308:9;6304:22;6283:53;:::i;:::-;6273:63;;6228:118;5734:619;;;;;:::o;6359:474::-;6427:6;6435;6484:2;6472:9;6463:7;6459:23;6455:32;6452:119;;;6490:79;;:::i;:::-;6452:119;6610:1;6635:53;6680:7;6671:6;6660:9;6656:22;6635:53;:::i;:::-;6625:63;;6581:117;6737:2;6763:53;6808:7;6799:6;6788:9;6784:22;6763:53;:::i;:::-;6753:63;;6708:118;6359:474;;;;;:::o;6839:332::-;6960:4;6998:2;6987:9;6983:18;6975:26;;7011:71;7079:1;7068:9;7064:17;7055:6;7011:71;:::i;:::-;7092:72;7160:2;7149:9;7145:18;7136:6;7092:72;:::i;:::-;6839:332;;;;;:::o;7177:329::-;7236:6;7285:2;7273:9;7264:7;7260:23;7256:32;7253:119;;;7291:79;;:::i;:::-;7253:119;7411:1;7436:53;7481:7;7472:6;7461:9;7457:22;7436:53;:::i;:::-;7426:63;;7382:117;7177:329;;;;:::o;7512:108::-;7589:24;7607:5;7589:24;:::i;:::-;7584:3;7577:37;7512:108;;:::o;7626:105::-;7701:23;7718:5;7701:23;:::i;:::-;7696:3;7689:36;7626:105;;:::o;7737:99::-;7808:21;7823:5;7808:21;:::i;:::-;7803:3;7796:34;7737:99;;:::o;7900:1393::-;8043:4;8038:3;8034:14;8135:4;8128:5;8124:16;8118:23;8154:63;8211:4;8206:3;8202:14;8188:12;8154:63;:::i;:::-;8058:169;8312:4;8305:5;8301:16;8295:23;8331:61;8386:4;8381:3;8377:14;8363:12;8331:61;:::i;:::-;8237:165;8491:4;8484:5;8480:16;8474:23;8510:61;8565:4;8560:3;8556:14;8542:12;8510:61;:::i;:::-;8412:169;8668:4;8661:5;8657:16;8651:23;8687:61;8742:4;8737:3;8733:14;8719:12;8687:61;:::i;:::-;8591:167;8847:4;8840:5;8836:16;8830:23;8866:61;8921:4;8916:3;8912:14;8898:12;8866:61;:::i;:::-;8768:169;9025:4;9018:5;9014:16;9008:23;9044:61;9099:4;9094:3;9090:14;9076:12;9044:61;:::i;:::-;8947:168;9200:4;9193:5;9189:16;9183:23;9219:57;9270:4;9265:3;9261:14;9247:12;9219:57;:::i;:::-;9125:161;8012:1281;7900:1393;;:::o;9299:315::-;9438:4;9476:3;9465:9;9461:19;9453:27;;9490:117;9604:1;9593:9;9589:17;9580:6;9490:117;:::i;:::-;9299:315;;;;:::o;9620:109::-;9656:7;9696:26;9689:5;9685:38;9674:49;;9620:109;;;:::o;9735:120::-;9807:23;9824:5;9807:23;:::i;:::-;9800:5;9797:34;9787:62;;9845:1;9842;9835:12;9787:62;9735:120;:::o;9861:137::-;9906:5;9944:6;9931:20;9922:29;;9960:32;9986:5;9960:32;:::i;:::-;9861:137;;;;:::o;10004:327::-;10062:6;10111:2;10099:9;10090:7;10086:23;10082:32;10079:119;;;10117:79;;:::i;:::-;10079:119;10237:1;10262:52;10306:7;10297:6;10286:9;10282:22;10262:52;:::i;:::-;10252:62;;10208:116;10004:327;;;;:::o;10337:117::-;10446:1;10443;10436:12;10460:117;10569:1;10566;10559:12;10583:180;10631:77;10628:1;10621:88;10728:4;10725:1;10718:15;10752:4;10749:1;10742:15;10769:281;10852:27;10874:4;10852:27;:::i;:::-;10844:6;10840:40;10982:6;10970:10;10967:22;10946:18;10934:10;10931:34;10928:62;10925:88;;;10993:18;;:::i;:::-;10925:88;11033:10;11029:2;11022:22;10812:238;10769:281;;:::o;11056:129::-;11090:6;11117:20;;:::i;:::-;11107:30;;11146:33;11174:4;11166:6;11146:33;:::i;:::-;11056:129;;;:::o;11191:308::-;11253:4;11343:18;11335:6;11332:30;11329:56;;;11365:18;;:::i;:::-;11329:56;11403:29;11425:6;11403:29;:::i;:::-;11395:37;;11487:4;11481;11477:15;11469:23;;11191:308;;;:::o;11505:154::-;11589:6;11584:3;11579;11566:30;11651:1;11642:6;11637:3;11633:16;11626:27;11505:154;;;:::o;11665:412::-;11743:5;11768:66;11784:49;11826:6;11784:49;:::i;:::-;11768:66;:::i;:::-;11759:75;;11857:6;11850:5;11843:21;11895:4;11888:5;11884:16;11933:3;11924:6;11919:3;11915:16;11912:25;11909:112;;;11940:79;;:::i;:::-;11909:112;12030:41;12064:6;12059:3;12054;12030:41;:::i;:::-;11749:328;11665:412;;;;;:::o;12097:340::-;12153:5;12202:3;12195:4;12187:6;12183:17;12179:27;12169:122;;12210:79;;:::i;:::-;12169:122;12327:6;12314:20;12352:79;12427:3;12419:6;12412:4;12404:6;12400:17;12352:79;:::i;:::-;12343:88;;12159:278;12097:340;;;;:::o;12443:509::-;12512:6;12561:2;12549:9;12540:7;12536:23;12532:32;12529:119;;;12567:79;;:::i;:::-;12529:119;12715:1;12704:9;12700:17;12687:31;12745:18;12737:6;12734:30;12731:117;;;12767:79;;:::i;:::-;12731:117;12872:63;12927:7;12918:6;12907:9;12903:22;12872:63;:::i;:::-;12862:73;;12658:287;12443:509;;;;:::o;12958:116::-;13028:21;13043:5;13028:21;:::i;:::-;13021:5;13018:32;13008:60;;13064:1;13061;13054:12;13008:60;12958:116;:::o;13080:133::-;13123:5;13161:6;13148:20;13139:29;;13177:30;13201:5;13177:30;:::i;:::-;13080:133;;;;:::o;13219:468::-;13284:6;13292;13341:2;13329:9;13320:7;13316:23;13312:32;13309:119;;;13347:79;;:::i;:::-;13309:119;13467:1;13492:53;13537:7;13528:6;13517:9;13513:22;13492:53;:::i;:::-;13482:63;;13438:117;13594:2;13620:50;13662:7;13653:6;13642:9;13638:22;13620:50;:::i;:::-;13610:60;;13565:115;13219:468;;;;;:::o;13693:120::-;13765:23;13782:5;13765:23;:::i;:::-;13758:5;13755:34;13745:62;;13803:1;13800;13793:12;13745:62;13693:120;:::o;13819:137::-;13864:5;13902:6;13889:20;13880:29;;13918:32;13944:5;13918:32;:::i;:::-;13819:137;;;;:::o;13962:327::-;14020:6;14069:2;14057:9;14048:7;14044:23;14040:32;14037:119;;;14075:79;;:::i;:::-;14037:119;14195:1;14220:52;14264:7;14255:6;14244:9;14240:22;14220:52;:::i;:::-;14210:62;;14166:116;13962:327;;;;:::o;14295:307::-;14356:4;14446:18;14438:6;14435:30;14432:56;;;14468:18;;:::i;:::-;14432:56;14506:29;14528:6;14506:29;:::i;:::-;14498:37;;14590:4;14584;14580:15;14572:23;;14295:307;;;:::o;14608:410::-;14685:5;14710:65;14726:48;14767:6;14726:48;:::i;:::-;14710:65;:::i;:::-;14701:74;;14798:6;14791:5;14784:21;14836:4;14829:5;14825:16;14874:3;14865:6;14860:3;14856:16;14853:25;14850:112;;;14881:79;;:::i;:::-;14850:112;14971:41;15005:6;15000:3;14995;14971:41;:::i;:::-;14691:327;14608:410;;;;;:::o;15037:338::-;15092:5;15141:3;15134:4;15126:6;15122:17;15118:27;15108:122;;15149:79;;:::i;:::-;15108:122;15266:6;15253:20;15291:78;15365:3;15357:6;15350:4;15342:6;15338:17;15291:78;:::i;:::-;15282:87;;15098:277;15037:338;;;;:::o;15381:943::-;15476:6;15484;15492;15500;15549:3;15537:9;15528:7;15524:23;15520:33;15517:120;;;15556:79;;:::i;:::-;15517:120;15676:1;15701:53;15746:7;15737:6;15726:9;15722:22;15701:53;:::i;:::-;15691:63;;15647:117;15803:2;15829:53;15874:7;15865:6;15854:9;15850:22;15829:53;:::i;:::-;15819:63;;15774:118;15931:2;15957:53;16002:7;15993:6;15982:9;15978:22;15957:53;:::i;:::-;15947:63;;15902:118;16087:2;16076:9;16072:18;16059:32;16118:18;16110:6;16107:30;16104:117;;;16140:79;;:::i;:::-;16104:117;16245:62;16299:7;16290:6;16279:9;16275:22;16245:62;:::i;:::-;16235:72;;16030:287;15381:943;;;;;;;:::o;16330:474::-;16398:6;16406;16455:2;16443:9;16434:7;16430:23;16426:32;16423:119;;;16461:79;;:::i;:::-;16423:119;16581:1;16606:53;16651:7;16642:6;16631:9;16627:22;16606:53;:::i;:::-;16596:63;;16552:117;16708:2;16734:53;16779:7;16770:6;16759:9;16755:22;16734:53;:::i;:::-;16724:63;;16679:118;16330:474;;;;;:::o;16810:323::-;16866:6;16915:2;16903:9;16894:7;16890:23;16886:32;16883:119;;;16921:79;;:::i;:::-;16883:119;17041:1;17066:50;17108:7;17099:6;17088:9;17084:22;17066:50;:::i;:::-;17056:60;;17012:114;16810:323;;;;:::o;17139:472::-;17206:6;17214;17263:2;17251:9;17242:7;17238:23;17234:32;17231:119;;;17269:79;;:::i;:::-;17231:119;17389:1;17414:53;17459:7;17450:6;17439:9;17435:22;17414:53;:::i;:::-;17404:63;;17360:117;17516:2;17542:52;17586:7;17577:6;17566:9;17562:22;17542:52;:::i;:::-;17532:62;;17487:117;17139:472;;;;;:::o;17617:180::-;17665:77;17662:1;17655:88;17762:4;17759:1;17752:15;17786:4;17783:1;17776:15;17803:320;17847:6;17884:1;17878:4;17874:12;17864:22;;17931:1;17925:4;17921:12;17952:18;17942:81;;18008:4;18000:6;17996:17;17986:27;;17942:81;18070:2;18062:6;18059:14;18039:18;18036:38;18033:84;;18089:18;;:::i;:::-;18033:84;17854:269;17803:320;;;:::o;18129:180::-;18177:77;18174:1;18167:88;18274:4;18271:1;18264:15;18298:4;18295:1;18288:15;18315:348;18355:7;18378:20;18396:1;18378:20;:::i;:::-;18373:25;;18412:20;18430:1;18412:20;:::i;:::-;18407:25;;18600:1;18532:66;18528:74;18525:1;18522:81;18517:1;18510:9;18503:17;18499:105;18496:131;;;18607:18;;:::i;:::-;18496:131;18655:1;18652;18648:9;18637:20;;18315:348;;;;:::o;18669:180::-;18717:77;18714:1;18707:88;18814:4;18811:1;18804:15;18838:4;18835:1;18828:15;18855:185;18895:1;18912:20;18930:1;18912:20;:::i;:::-;18907:25;;18946:20;18964:1;18946:20;:::i;:::-;18941:25;;18985:1;18975:35;;18990:18;;:::i;:::-;18975:35;19032:1;19029;19025:9;19020:14;;18855:185;;;;:::o;19046:182::-;19186:34;19182:1;19174:6;19170:14;19163:58;19046:182;:::o;19234:366::-;19376:3;19397:67;19461:2;19456:3;19397:67;:::i;:::-;19390:74;;19473:93;19562:3;19473:93;:::i;:::-;19591:2;19586:3;19582:12;19575:19;;19234:366;;;:::o;19606:419::-;19772:4;19810:2;19799:9;19795:18;19787:26;;19859:9;19853:4;19849:20;19845:1;19834:9;19830:17;19823:47;19887:131;20013:4;19887:131;:::i;:::-;19879:139;;19606:419;;;:::o;20031:305::-;20071:3;20090:20;20108:1;20090:20;:::i;:::-;20085:25;;20124:20;20142:1;20124:20;:::i;:::-;20119:25;;20278:1;20210:66;20206:74;20203:1;20200:81;20197:107;;;20284:18;;:::i;:::-;20197:107;20328:1;20325;20321:9;20314:16;;20031:305;;;;:::o;20342:191::-;20382:4;20402:20;20420:1;20402:20;:::i;:::-;20397:25;;20436:20;20454:1;20436:20;:::i;:::-;20431:25;;20475:1;20472;20469:8;20466:34;;;20480:18;;:::i;:::-;20466:34;20525:1;20522;20518:9;20510:17;;20342:191;;;;:::o;20539:101::-;20575:7;20615:18;20608:5;20604:30;20593:41;;20539:101;;;:::o;20646:254::-;20685:3;20704:19;20721:1;20704:19;:::i;:::-;20699:24;;20737:19;20754:1;20737:19;:::i;:::-;20732:24;;20842:1;20822:18;20818:26;20815:1;20812:33;20809:59;;;20848:18;;:::i;:::-;20809:59;20892:1;20889;20885:9;20878:16;;20646:254;;;;:::o;20906:148::-;21008:11;21045:3;21030:18;;20906:148;;;;:::o;21060:377::-;21166:3;21194:39;21227:5;21194:39;:::i;:::-;21249:89;21331:6;21326:3;21249:89;:::i;:::-;21242:96;;21347:52;21392:6;21387:3;21380:4;21373:5;21369:16;21347:52;:::i;:::-;21424:6;21419:3;21415:16;21408:23;;21170:267;21060:377;;;;:::o;21443:155::-;21583:7;21579:1;21571:6;21567:14;21560:31;21443:155;:::o;21604:400::-;21764:3;21785:84;21867:1;21862:3;21785:84;:::i;:::-;21778:91;;21878:93;21967:3;21878:93;:::i;:::-;21996:1;21991:3;21987:11;21980:18;;21604:400;;;:::o;22010:701::-;22291:3;22313:95;22404:3;22395:6;22313:95;:::i;:::-;22306:102;;22425:95;22516:3;22507:6;22425:95;:::i;:::-;22418:102;;22537:148;22681:3;22537:148;:::i;:::-;22530:155;;22702:3;22695:10;;22010:701;;;;;:::o;22717:225::-;22857:34;22853:1;22845:6;22841:14;22834:58;22926:8;22921:2;22913:6;22909:15;22902:33;22717:225;:::o;22948:366::-;23090:3;23111:67;23175:2;23170:3;23111:67;:::i;:::-;23104:74;;23187:93;23276:3;23187:93;:::i;:::-;23305:2;23300:3;23296:12;23289:19;;22948:366;;;:::o;23320:419::-;23486:4;23524:2;23513:9;23509:18;23501:26;;23573:9;23567:4;23563:20;23559:1;23548:9;23544:17;23537:47;23601:131;23727:4;23601:131;:::i;:::-;23593:139;;23320:419;;;:::o;23745:179::-;23885:31;23881:1;23873:6;23869:14;23862:55;23745:179;:::o;23930:366::-;24072:3;24093:67;24157:2;24152:3;24093:67;:::i;:::-;24086:74;;24169:93;24258:3;24169:93;:::i;:::-;24287:2;24282:3;24278:12;24271:19;;23930:366;;;:::o;24302:419::-;24468:4;24506:2;24495:9;24491:18;24483:26;;24555:9;24549:4;24545:20;24541:1;24530:9;24526:17;24519:47;24583:131;24709:4;24583:131;:::i;:::-;24575:139;;24302:419;;;:::o;24727:147::-;24828:11;24865:3;24850:18;;24727:147;;;;:::o;24880:114::-;;:::o;25000:398::-;25159:3;25180:83;25261:1;25256:3;25180:83;:::i;:::-;25173:90;;25272:93;25361:3;25272:93;:::i;:::-;25390:1;25385:3;25381:11;25374:18;;25000:398;;;:::o;25404:379::-;25588:3;25610:147;25753:3;25610:147;:::i;:::-;25603:154;;25774:3;25767:10;;25404:379;;;:::o;25789:245::-;25929:34;25925:1;25917:6;25913:14;25906:58;25998:28;25993:2;25985:6;25981:15;25974:53;25789:245;:::o;26040:366::-;26182:3;26203:67;26267:2;26262:3;26203:67;:::i;:::-;26196:74;;26279:93;26368:3;26279:93;:::i;:::-;26397:2;26392:3;26388:12;26381:19;;26040:366;;;:::o;26412:419::-;26578:4;26616:2;26605:9;26601:18;26593:26;;26665:9;26659:4;26655:20;26651:1;26640:9;26636:17;26629:47;26693:131;26819:4;26693:131;:::i;:::-;26685:139;;26412:419;;;:::o;26837:229::-;26977:34;26973:1;26965:6;26961:14;26954:58;27046:12;27041:2;27033:6;27029:15;27022:37;26837:229;:::o;27072:366::-;27214:3;27235:67;27299:2;27294:3;27235:67;:::i;:::-;27228:74;;27311:93;27400:3;27311:93;:::i;:::-;27429:2;27424:3;27420:12;27413:19;;27072:366;;;:::o;27444:419::-;27610:4;27648:2;27637:9;27633:18;27625:26;;27697:9;27691:4;27687:20;27683:1;27672:9;27668:17;27661:47;27725:131;27851:4;27725:131;:::i;:::-;27717:139;;27444:419;;;:::o;27869:175::-;28009:27;28005:1;27997:6;27993:14;27986:51;27869:175;:::o;28050:366::-;28192:3;28213:67;28277:2;28272:3;28213:67;:::i;:::-;28206:74;;28289:93;28378:3;28289:93;:::i;:::-;28407:2;28402:3;28398:12;28391:19;;28050:366;;;:::o;28422:419::-;28588:4;28626:2;28615:9;28611:18;28603:26;;28675:9;28669:4;28665:20;28661:1;28650:9;28646:17;28639:47;28703:131;28829:4;28703:131;:::i;:::-;28695:139;;28422:419;;;:::o;28847:98::-;28898:6;28932:5;28926:12;28916:22;;28847:98;;;:::o;28951:168::-;29034:11;29068:6;29063:3;29056:19;29108:4;29103:3;29099:14;29084:29;;28951:168;;;;:::o;29125:360::-;29211:3;29239:38;29271:5;29239:38;:::i;:::-;29293:70;29356:6;29351:3;29293:70;:::i;:::-;29286:77;;29372:52;29417:6;29412:3;29405:4;29398:5;29394:16;29372:52;:::i;:::-;29449:29;29471:6;29449:29;:::i;:::-;29444:3;29440:39;29433:46;;29215:270;29125:360;;;;:::o;29491:640::-;29686:4;29724:3;29713:9;29709:19;29701:27;;29738:71;29806:1;29795:9;29791:17;29782:6;29738:71;:::i;:::-;29819:72;29887:2;29876:9;29872:18;29863:6;29819:72;:::i;:::-;29901;29969:2;29958:9;29954:18;29945:6;29901:72;:::i;:::-;30020:9;30014:4;30010:20;30005:2;29994:9;29990:18;29983:48;30048:76;30119:4;30110:6;30048:76;:::i;:::-;30040:84;;29491:640;;;;;;;:::o;30137:141::-;30193:5;30224:6;30218:13;30209:22;;30240:32;30266:5;30240:32;:::i;:::-;30137:141;;;;:::o;30284:349::-;30353:6;30402:2;30390:9;30381:7;30377:23;30373:32;30370:119;;;30408:79;;:::i;:::-;30370:119;30528:1;30553:63;30608:7;30599:6;30588:9;30584:22;30553:63;:::i;:::-;30543:73;;30499:127;30284:349;;;;:::o;30639:233::-;30678:3;30701:24;30719:5;30701:24;:::i;:::-;30692:33;;30747:66;30740:5;30737:77;30734:103;;30817:18;;:::i;:::-;30734:103;30864:1;30857:5;30853:13;30846:20;;30639:233;;;:::o;30878:176::-;30910:1;30927:20;30945:1;30927:20;:::i;:::-;30922:25;;30961:20;30979:1;30961:20;:::i;:::-;30956:25;;31000:1;30990:35;;31005:18;;:::i;:::-;30990:35;31046:1;31043;31039:9;31034:14;;30878:176;;;;:::o;31060:180::-;31108:77;31105:1;31098:88;31205:4;31202:1;31195:15;31229:4;31226:1;31219:15

Swarm Source

ipfs://445e6bbf23bbf955bdadfb673bf9555cbdf05589bf26100d70974e26eae0d4f4
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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