ETH Price: $3,917.57 (+6.85%)

Token

Creator (CRTR)
 

Overview

Max Total Supply

1,676 CRTR

Holders

122

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 CRTR
0x2d3f37d68720fd8142572ff08ec322a312e9525f
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:
Creator

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 2 of 12: Creator.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "./ERC721AQueryable.sol";
import "./IERC721Enumerable.sol";
import "./Ownable.sol";
import "./SafeMath.sol";
import "./Strings.sol";

contract Creator is ERC721AQueryable, Ownable {
    using Strings for uint256;
    using SafeMath for uint256;

    // Events
    event TokenMinted(address owner, uint256 qtyTokens);
    event RewardClaimed(address owner, uint256 qtyTokens);

    IERC721Enumerable public FRANKIE_CONTRACT = IERC721Enumerable(0xa9e739bA9e691FAcC90900D16629f4814805c6ea);

    // Provenance number
    string public provenance = "";

    // Max amount of token to purchase per account each time
    uint public maxPurchase = 20;

    // Max supply
    uint256 public maxTokens = 8888;

    // Mint price.
    uint256 public mintPrice = 0;

    // Max supply
    uint256 public claimRewardDueDate = 1673654399; // Friday 13, January 2023 23:59:59 GTM 0

    // Max qty tokens to claim per request.
    uint256 public maxQtyClaimPerRequest = 100;

    // Rewards Claimed
    mapping(uint256 => bool) private claimedRewards;

    // Define if claim is active
    bool public claimRewardIsActive = true;

    // Define if sale is active
    bool public saleIsActive = false;

    // Base URI
    string private baseURI;

    string public baseExtension = ".json";

    /**
     * Contract constructor
     */
    constructor(string memory _name, string memory _symbol, string memory _uri) ERC721A(_name, _symbol) {
        setBaseURI(_uri);
    }

    /*
     * Set Frankie contract address
     */
    function setFrankieContract(address _contractAddress) public onlyOwner {
        FRANKIE_CONTRACT = IERC721Enumerable(_contractAddress);
    }

    /*
     * Set provenance once it's calculated
     */
    function setProvenanceHash(string memory _provenanceHash) public onlyOwner {
        provenance = _provenanceHash;
    }

    /*
     * Claim reward is enabled
     */
    function setClaimRewardState(bool _newState) public onlyOwner {
        claimRewardIsActive = _newState;
    }

    /*
     * Pause sale if active, make active if paused
     */
    function setSaleState(bool _newState) public onlyOwner {
        saleIsActive = _newState;
    }

    /*
     * Set max purchase
     */
    function setMaxPurchase(uint256 _qty) public onlyOwner {
        maxPurchase = _qty;
    }

    /**
     * Set Max Tokens to mint
     */
    function setMaxTokens(uint256 _qty) public onlyOwner {
        maxTokens = _qty;
    }

    /**
     * Set Max qty tokens to claim per request
     */
    function setMaxQtyClaimPerRequest(uint256 _qty) public onlyOwner {
        maxQtyClaimPerRequest = _qty;
    }

    /**
     * Set the mint price
     */
    function setMintPrice(uint256 _newPrice) public onlyOwner {
        mintPrice = _newPrice;
    }

    /*
     * Set Claim Reward Due Date
     */
    function setClaimRewardDueDate(uint256 _newDate) public onlyOwner {
        claimRewardDueDate = _newDate;
    }

    /*
     * Set Base extension
     */
    function setBaseExtension(string memory _baseExtension) public onlyOwner {
        baseExtension = _baseExtension;
    }

    /**
     * @dev Changes the base URI if we want to move things in the future (Callable by owner only)
     */
    function setBaseURI(string memory BaseURI) onlyOwner public {
        baseURI = BaseURI;
    }

    /**
     * @dev Base URI for computing {tokenURI}. Empty by default, can be overriden
     * in child contracts.
     */
    function _baseURI() internal view virtual override returns(string memory) {
        return baseURI;
    }

    /**
     * Get the token URI with the metadata extension
     */
    function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) {
        require(_exists(_tokenId), "ERC721Metadata: URI query for nonexistent token");

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

    /**
     * Withdraw
     */
    function withdraw() public onlyOwner {
        uint balance = address(this).balance;
        payable(msg.sender).transfer(balance);
    }

    function _startTokenId() internal view virtual override returns (uint256) {
        return 1;
    }

    /**
     * Reserve tokens
     */
    function reserveTokens(uint _qtyTokens) public onlyOwner {
        require(totalSupply().add(_qtyTokens) <= maxTokens, "Reserve tokens would exceed max supply");

        _safeMint(msg.sender, _qtyTokens);
    }

    /**
     * Mint token for owners
     */
    function mintToWallets(address[] memory _owners, uint256 _qty) public onlyOwner {
        require(totalSupply().add(_owners.length.mul(_qty)) <= maxTokens, "Purchase would exceed max supply");
        
        for (uint i = 0; i < _owners.length; i++) {
            _safeMint(_owners[i], _qty);
            emit TokenMinted(_owners[i], _qty);
        }
    }

    /**
    * Mint tokens
    */
    function mint(uint _qty) public payable {
        require(saleIsActive, "Mint is not available right now");
        require(_qty <= maxPurchase, "Can only mint 20 tokens at a time");
        require(totalSupply().add(_qty) <= maxTokens, "Purchase would exceed max supply");
        require(mintPrice.mul(_qty) <= msg.value, "Value sent is not correct");
        
        _safeMint(msg.sender, _qty);
        emit TokenMinted(msg.sender, _qty);
    }

    /**
     * Claim all Rewards
     */
    function claimAllRewards(uint256[] memory _tokensId) external {
        require(claimRewardIsActive, "Claim reward is not available right now");
        require(claimRewardDueDate >= block.timestamp, "Time to claim rewards is over");
        require(_tokensId.length <= maxQtyClaimPerRequest, "The number of tokens to claim rewards exceeds the maximum allowed");

        uint256 ownerBalance = _tokensId.length;
        uint256 qtyToClaim = 0;

        for(uint i = 0; i < ownerBalance; i++) {
            if (FRANKIE_CONTRACT.ownerOf(_tokensId[i]) == msg.sender && !claimedRewards[_tokensId[i]]) {
                claimedRewards[_tokensId[i]] = true;
                qtyToClaim = qtyToClaim.add(1);
            }
        }

        require(qtyToClaim > 0, "You don't have rewards to claim");
        require(totalSupply().add(qtyToClaim) <= maxTokens, "Claim reward would exceed max supply");

        _safeMint(msg.sender, qtyToClaim);

        emit RewardClaimed(msg.sender, qtyToClaim);
    }

    /**
    * Claim Reward by Token Id
    */
    function claimReward(uint256 _frankieTokenId) external {
        require(claimRewardIsActive, "Claim reward must be active");
        require(claimRewardDueDate >= block.timestamp, "Time to claim reward is over");

        require(!claimedRewards[_frankieTokenId], "Token Reward was claimed");
        require(FRANKIE_CONTRACT.ownerOf(_frankieTokenId) == msg.sender, "You are not the token owner");
        require(totalSupply().add(1) <= maxTokens, "Claim reward would exceed max supply");

        claimedRewards[_frankieTokenId] = true;
        _safeMint(msg.sender, 1);

        emit RewardClaimed(msg.sender, 1);
    }

    /**
    * get Frankie tokens pending to claim for an owner
    */
    function getPendingRewards(address _owner) public view returns(uint256[] memory) {
        require(claimRewardIsActive, "Claim reward is not available right now");
        require(claimRewardDueDate >= block.timestamp, "Time to claim rewards is over");

        uint256 frankieTokenId;
        uint ownerBalance = FRANKIE_CONTRACT.balanceOf(_owner);
        uint256[] memory tokensId = new uint256[](ownerBalance);
        
        for(uint i = 0; i < ownerBalance; i++){
            frankieTokenId = FRANKIE_CONTRACT.tokenOfOwnerByIndex(_owner, i);
            if (!claimedRewards[frankieTokenId]) {
                tokensId[i] = frankieTokenId;
            }else{
                tokensId[i] = 0;
            }
        }

        return tokensId;
    }

    /**
     * Get total rewards available for an owner
     */
    function getTotalRewardsToClaim(address _owner) public view returns(uint256) {
        require(claimRewardIsActive, "Claim reward is not available right now");

        uint256 qtyToClaim = 0;
        uint256 frankieTokenId;
        uint256 ownerBalance = FRANKIE_CONTRACT.balanceOf(_owner);

        for(uint i = 0; i < ownerBalance; i++) {
            frankieTokenId = FRANKIE_CONTRACT.tokenOfOwnerByIndex(_owner, i);
            if (!claimedRewards[frankieTokenId]) {
                qtyToClaim = qtyToClaim.add(1);
            }
        }
        return qtyToClaim;
    }

    /**
     * Frankie has reward pending to claim
     */
    function frankieHasReward(uint256 _frankieTokenId) public view returns(bool) {
        require(_frankieTokenId > 0 && _frankieTokenId <= maxTokens, "Invalid Token Id");

        return !claimedRewards[_frankieTokenId];
    }

    /**
     * Get owners list
     */
    function getOwners(uint256 _offset, uint256 _limit) public view returns(address[] memory) {
        uint tokenCount = totalSupply();

        if (_offset.add(_limit) < tokenCount) {
            tokenCount = _offset.add(_limit);
        }

        address[] memory owners = new address[](tokenCount);
        for (uint i = _offset; i < tokenCount; i++) {
            owners[i] = ownerOf(i + 1);
        }

        return owners;
    }
}

File 1 of 12: Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

File 3 of 12: ERC721A.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721A.sol';

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

/**
 * @title ERC721A
 *
 * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721)
 * Non-Fungible Token Standard, including the Metadata extension.
 * Optimized for lower gas during batch mints.
 *
 * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...)
 * starting from `_startTokenId()`.
 *
 * Assumptions:
 *
 * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364).
    struct TokenApprovalRef {
        address value;
    }

    // =============================================================
    //                           CONSTANTS
    // =============================================================

    // 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 bit position of `extraData` in packed ownership.
    uint256 private constant _BITPOS_EXTRA_DATA = 232;

    // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`.
    uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1;

    // The mask of the lower 160 bits for addresses.
    uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;

    // The maximum `quantity` that can be minted with {_mintERC2309}.
    // This limit is to prevent overflows on the address data entries.
    // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309}
    // is required to cause an overflow, which is unrealistic.
    uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000;

    // The `Transfer` event signature is given by:
    // `keccak256(bytes("Transfer(address,address,uint256)"))`.
    bytes32 private constant _TRANSFER_EVENT_SIGNATURE =
        0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;

    // =============================================================
    //                            STORAGE
    // =============================================================

    // The next token ID 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`
    // - [232..255] `extraData`
    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 => TokenApprovalRef) private _tokenApprovals;

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

    // =============================================================
    //                          CONSTRUCTOR
    // =============================================================

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

    // =============================================================
    //                   TOKEN COUNTING OPERATIONS
    // =============================================================

    /**
     * @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 virtual 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 virtual 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 virtual 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 virtual returns (uint256) {
        return _burnCounter;
    }

    // =============================================================
    //                    ADDRESS DATA OPERATIONS
    // =============================================================

    /**
     * @dev Returns the number of tokens in `owner`'s account.
     */
    function balanceOf(address owner) public view virtual 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 auxiliary 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 auxiliary 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 virtual {
        uint256 packed = _packedAddressData[owner];
        uint256 auxCasted;
        // Cast `aux` with assembly to avoid redundant masking.
        assembly {
            auxCasted := aux
        }
        packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX);
        _packedAddressData[owner] = packed;
    }

    // =============================================================
    //                            IERC165
    // =============================================================

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30000 gas.
     */
    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: [ERC165](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.
    }

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

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

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    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, it can be overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return '';
    }

    // =============================================================
    //                     OWNERSHIPS OPERATIONS
    // =============================================================

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        return address(uint160(_packedOwnershipOf(tokenId)));
    }

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

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

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

    /**
     * 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 initialized ownership slot
                        // (i.e. `ownership.addr != address(0) && ownership.burned == false`)
                        // before an unintialized ownership slot
                        // (i.e. `ownership.addr == address(0) && ownership.burned == false`)
                        // Hence, `curr` will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed will be zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * @dev 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;
        ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA);
    }

    /**
     * @dev Packs ownership data into a single uint256.
     */
    function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, _BITMASK_ADDRESS)
            // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`.
            result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags))
        }
    }

    /**
     * @dev Returns the `nextInitialized` flag set if `quantity` equals 1.
     */
    function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) {
        // For branchless setting of the `nextInitialized` flag.
        assembly {
            // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`.
            result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1))
        }
    }

    // =============================================================
    //                      APPROVAL OPERATIONS
    // =============================================================

    /**
     * @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) public payable virtual override {
        address owner = ownerOf(tokenId);

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

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

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId].value;
    }

    /**
     * @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) public virtual override {
        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
    }

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

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

    /**
     * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`.
     */
    function _isSenderApprovedOrOwner(
        address approvedAddress,
        address owner,
        address msgSender
    ) private pure returns (bool result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, _BITMASK_ADDRESS)
            // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean.
            msgSender := and(msgSender, _BITMASK_ADDRESS)
            // `msgSender == owner || msgSender == approvedAddress`.
            result := or(eq(msgSender, owner), eq(msgSender, approvedAddress))
        }
    }

    /**
     * @dev Returns the storage slot and value for the approved address of `tokenId`.
     */
    function _getApprovedSlotAndAddress(uint256 tokenId)
        private
        view
        returns (uint256 approvedAddressSlot, address approvedAddress)
    {
        TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId];
        // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`.
        assembly {
            approvedAddressSlot := tokenApproval.slot
            approvedAddress := sload(approvedAddressSlot)
        }
    }

    // =============================================================
    //                      TRANSFER OPERATIONS
    // =============================================================

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

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

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);

        // The nested ifs save around 20+ gas over a compound boolean condition.
        if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
            if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();

        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // 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] = _packOwnershipData(
                to,
                _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked)
            );

            // 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 `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable virtual override {
        safeTransferFrom(from, to, tokenId, '');
    }

    /**
     * @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 memory _data
    ) public payable virtual override {
        transferFrom(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

    /**
     * @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 Private function to invoke {IERC721Receiver-onERC721Received} on a target contract.
     *
     * `from` - Previous owner of the given token ID.
     * `to` - Target address that will receive the token.
     * `tokenId` - Token ID to be transferred.
     * `_data` - Optional data to send along with the call.
     *
     * Returns 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))
                }
            }
        }
    }

    // =============================================================
    //                        MINT OPERATIONS
    // =============================================================

    /**
     * @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 for each mint.
     */
    function _mint(address to, uint256 quantity) internal virtual {
        uint256 startTokenId = _currentIndex;
        if (quantity == 0) revert MintZeroQuantity();

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

        // Overflows are incredibly unrealistic.
        // `balance` and `numberMinted` have a maximum limit of 2**64.
        // `tokenId` has a maximum limit of 2**256.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _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] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            uint256 toMasked;
            uint256 end = startTokenId + quantity;

            // Use assembly to loop and emit the `Transfer` event for gas savings.
            // The duplicated `log4` removes an extra check and reduces stack juggling.
            // The assembly, together with the surrounding Solidity code, have been
            // delicately arranged to nudge the compiler into producing optimized opcodes.
            assembly {
                // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
                toMasked := and(to, _BITMASK_ADDRESS)
                // Emit the `Transfer` event.
                log4(
                    0, // Start of data (0, since no data).
                    0, // End of data (0, since no data).
                    _TRANSFER_EVENT_SIGNATURE, // Signature.
                    0, // `address(0)`.
                    toMasked, // `to`.
                    startTokenId // `tokenId`.
                )

                // The `iszero(eq(,))` check ensures that large values of `quantity`
                // that overflows uint256 will make the loop run out of gas.
                // The compiler will optimize the `iszero` away for performance.
                for {
                    let tokenId := add(startTokenId, 1)
                } iszero(eq(tokenId, end)) {
                    tokenId := add(tokenId, 1)
                } {
                    // Emit the `Transfer` event. Similar to above.
                    log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId)
                }
            }
            if (toMasked == 0) revert MintToZeroAddress();

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

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * This function is intended for efficient minting only during contract creation.
     *
     * It emits only one {ConsecutiveTransfer} as defined in
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309),
     * instead of a sequence of {Transfer} event(s).
     *
     * Calling this function outside of contract creation WILL make your contract
     * non-compliant with the ERC721 standard.
     * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309
     * {ConsecutiveTransfer} event is only permissible during contract creation.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {ConsecutiveTransfer} event.
     */
    function _mintERC2309(address to, uint256 quantity) internal virtual {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();
        if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit();

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

        // Overflows are unrealistic due to the above check for `quantity` to be below the limit.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _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] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to);

            _currentIndex = startTokenId + quantity;
        }
        _afterTokenTransfers(address(0), to, startTokenId, 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.
     *
     * See {_mint}.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal virtual {
        _mint(to, quantity);

        unchecked {
            if (to.code.length != 0) {
                uint256 end = _currentIndex;
                uint256 index = end - quantity;
                do {
                    if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (index < end);
                // Reentrancy protection.
                if (_currentIndex != end) revert();
            }
        }
    }

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

    // =============================================================
    //                        BURN OPERATIONS
    // =============================================================

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

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);

        if (approvalCheck) {
            // The nested ifs save around 20+ gas over a compound boolean condition.
            if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
                if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
        }

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

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // 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] = _packOwnershipData(
                from,
                (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked)
            );

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

    // =============================================================
    //                     EXTRA DATA OPERATIONS
    // =============================================================

    /**
     * @dev Directly sets the extra data for the ownership data `index`.
     */
    function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual {
        uint256 packed = _packedOwnerships[index];
        if (packed == 0) revert OwnershipNotInitializedForExtraData();
        uint256 extraDataCasted;
        // Cast `extraData` with assembly to avoid redundant masking.
        assembly {
            extraDataCasted := extraData
        }
        packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA);
        _packedOwnerships[index] = packed;
    }

    /**
     * @dev Called during each token transfer to set the 24bit `extraData` field.
     * Intended to be overridden by the cosumer contract.
     *
     * `previousExtraData` - the value of `extraData` before transfer.
     *
     * 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 _extraData(
        address from,
        address to,
        uint24 previousExtraData
    ) internal view virtual returns (uint24) {}

    /**
     * @dev Returns the next extra data for the packed ownership data.
     * The returned result is shifted into position.
     */
    function _nextExtraData(
        address from,
        address to,
        uint256 prevOwnershipPacked
    ) private view returns (uint256) {
        uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA);
        return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA;
    }

    // =============================================================
    //                       OTHER OPERATIONS
    // =============================================================

    /**
     * @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 virtual returns (string memory str) {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit), but
            // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
            // We will need 1 word for the trailing zeros padding, 1 word for the length,
            // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0.
            let m := add(mload(0x40), 0xa0)
            // Update the free memory pointer to allocate.
            mstore(0x40, m)
            // Assign the `str` to the end.
            str := sub(m, 0x20)
            // Zeroize the slot after the string.
            mstore(str, 0)

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

            // We write the string from rightmost digit to leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // prettier-ignore
            for { let temp := value } 1 {} {
                str := sub(str, 1)
                // Write the character to the pointer.
                // The ASCII index of the '0' character is 48.
                mstore8(str, add(48, mod(temp, 10)))
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
                // prettier-ignore
                if iszero(temp) { break }
            }

            let length := sub(end, str)
            // Move the pointer 32 bytes leftwards to make room for the length.
            str := sub(str, 0x20)
            // Store the length.
            mstore(str, length)
        }
    }
}

File 4 of 12: ERC721AQueryable.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721AQueryable.sol';
import './ERC721A.sol';

/**
 * @title ERC721AQueryable.
 *
 * @dev ERC721A subclass with convenience query functions.
 */
abstract contract ERC721AQueryable is ERC721A, IERC721AQueryable {
    /**
     * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
     *
     * If the `tokenId` is out of bounds:
     *
     * - `addr = address(0)`
     * - `startTimestamp = 0`
     * - `burned = false`
     * - `extraData = 0`
     *
     * If the `tokenId` is burned:
     *
     * - `addr = <Address of owner before token was burned>`
     * - `startTimestamp = <Timestamp when token was burned>`
     * - `burned = true`
     * - `extraData = <Extra data when token was burned>`
     *
     * Otherwise:
     *
     * - `addr = <Address of owner>`
     * - `startTimestamp = <Timestamp of start of ownership>`
     * - `burned = false`
     * - `extraData = <Extra data at start of ownership>`
     */
    function explicitOwnershipOf(uint256 tokenId) public view virtual override returns (TokenOwnership memory) {
        TokenOwnership memory ownership;
        if (tokenId < _startTokenId() || tokenId >= _nextTokenId()) {
            return ownership;
        }
        ownership = _ownershipAt(tokenId);
        if (ownership.burned) {
            return ownership;
        }
        return _ownershipOf(tokenId);
    }

    /**
     * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order.
     * See {ERC721AQueryable-explicitOwnershipOf}
     */
    function explicitOwnershipsOf(uint256[] calldata tokenIds)
        external
        view
        virtual
        override
        returns (TokenOwnership[] memory)
    {
        unchecked {
            uint256 tokenIdsLength = tokenIds.length;
            TokenOwnership[] memory ownerships = new TokenOwnership[](tokenIdsLength);
            for (uint256 i; i != tokenIdsLength; ++i) {
                ownerships[i] = explicitOwnershipOf(tokenIds[i]);
            }
            return ownerships;
        }
    }

    /**
     * @dev Returns an array of token IDs owned by `owner`,
     * in the range [`start`, `stop`)
     * (i.e. `start <= tokenId < stop`).
     *
     * This function allows for tokens to be queried if the collection
     * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
     *
     * Requirements:
     *
     * - `start < stop`
     */
    function tokensOfOwnerIn(
        address owner,
        uint256 start,
        uint256 stop
    ) external view virtual override returns (uint256[] memory) {
        unchecked {
            if (start >= stop) revert InvalidQueryRange();
            uint256 tokenIdsIdx;
            uint256 stopLimit = _nextTokenId();
            // Set `start = max(start, _startTokenId())`.
            if (start < _startTokenId()) {
                start = _startTokenId();
            }
            // Set `stop = min(stop, stopLimit)`.
            if (stop > stopLimit) {
                stop = stopLimit;
            }
            uint256 tokenIdsMaxLength = balanceOf(owner);
            // Set `tokenIdsMaxLength = min(balanceOf(owner), stop - start)`,
            // to cater for cases where `balanceOf(owner)` is too big.
            if (start < stop) {
                uint256 rangeLength = stop - start;
                if (rangeLength < tokenIdsMaxLength) {
                    tokenIdsMaxLength = rangeLength;
                }
            } else {
                tokenIdsMaxLength = 0;
            }
            uint256[] memory tokenIds = new uint256[](tokenIdsMaxLength);
            if (tokenIdsMaxLength == 0) {
                return tokenIds;
            }
            // We need to call `explicitOwnershipOf(start)`,
            // because the slot at `start` may not be initialized.
            TokenOwnership memory ownership = explicitOwnershipOf(start);
            address currOwnershipAddr;
            // If the starting slot exists (i.e. not burned), initialize `currOwnershipAddr`.
            // `ownership.address` will not be zero, as `start` is clamped to the valid token ID range.
            if (!ownership.burned) {
                currOwnershipAddr = ownership.addr;
            }
            for (uint256 i = start; i != stop && tokenIdsIdx != tokenIdsMaxLength; ++i) {
                ownership = _ownershipAt(i);
                if (ownership.burned) {
                    continue;
                }
                if (ownership.addr != address(0)) {
                    currOwnershipAddr = ownership.addr;
                }
                if (currOwnershipAddr == owner) {
                    tokenIds[tokenIdsIdx++] = i;
                }
            }
            // Downsize the array to fit.
            assembly {
                mstore(tokenIds, tokenIdsIdx)
            }
            return tokenIds;
        }
    }

    /**
     * @dev Returns an array of token IDs owned by `owner`.
     *
     * This function scans the ownership mapping and is O(`totalSupply`) in complexity.
     * It is meant to be called off-chain.
     *
     * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
     * multiple smaller scans if the collection is large enough to cause
     * an out-of-gas error (10K collections should be fine).
     */
    function tokensOfOwner(address owner) external view virtual override returns (uint256[] memory) {
        unchecked {
            uint256 tokenIdsIdx;
            address currOwnershipAddr;
            uint256 tokenIdsLength = balanceOf(owner);
            uint256[] memory tokenIds = new uint256[](tokenIdsLength);
            TokenOwnership memory ownership;
            for (uint256 i = _startTokenId(); tokenIdsIdx != tokenIdsLength; ++i) {
                ownership = _ownershipAt(i);
                if (ownership.burned) {
                    continue;
                }
                if (ownership.addr != address(0)) {
                    currOwnershipAddr = ownership.addr;
                }
                if (currOwnershipAddr == owner) {
                    tokenIds[tokenIdsIdx++] = i;
                }
            }
            return tokenIds;
        }
    }
}

File 5 of 12: IERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

File 6 of 12: IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

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

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

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

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

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

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

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

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

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

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

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

File 7 of 12: IERC721A.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

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

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

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

    /**
     * The `quantity` minted with ERC2309 exceeds the safety limit.
     */
    error MintERC2309QuantityExceedsLimit();

    /**
     * The `extraData` cannot be set on an unintialized ownership slot.
     */
    error OwnershipNotInitializedForExtraData();

    // =============================================================
    //                            STRUCTS
    // =============================================================

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Stores the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
        // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}.
        uint24 extraData;
    }

    // =============================================================
    //                         TOKEN COUNTERS
    // =============================================================

    /**
     * @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() external view returns (uint256);

    // =============================================================
    //                            IERC165
    // =============================================================

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30000 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`,
     * 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,
        bytes calldata data
    ) external payable;

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

    /**
     * @dev Transfers `tokenId` 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 payable;

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

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

    // =============================================================
    //                           IERC2309
    // =============================================================

    /**
     * @dev Emitted when tokens in `fromTokenId` to `toTokenId`
     * (inclusive) is transferred from `from` to `to`, as defined in the
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard.
     *
     * See {_mintERC2309} for more details.
     */
    event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}

File 8 of 12: IERC721AQueryable.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721A.sol';

/**
 * @dev Interface of ERC721AQueryable.
 */
interface IERC721AQueryable is IERC721A {
    /**
     * Invalid query range (`start` >= `stop`).
     */
    error InvalidQueryRange();

    /**
     * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
     *
     * If the `tokenId` is out of bounds:
     *
     * - `addr = address(0)`
     * - `startTimestamp = 0`
     * - `burned = false`
     * - `extraData = 0`
     *
     * If the `tokenId` is burned:
     *
     * - `addr = <Address of owner before token was burned>`
     * - `startTimestamp = <Timestamp when token was burned>`
     * - `burned = true`
     * - `extraData = <Extra data when token was burned>`
     *
     * Otherwise:
     *
     * - `addr = <Address of owner>`
     * - `startTimestamp = <Timestamp of start of ownership>`
     * - `burned = false`
     * - `extraData = <Extra data at start of ownership>`
     */
    function explicitOwnershipOf(uint256 tokenId) external view returns (TokenOwnership memory);

    /**
     * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order.
     * See {ERC721AQueryable-explicitOwnershipOf}
     */
    function explicitOwnershipsOf(uint256[] memory tokenIds) external view returns (TokenOwnership[] memory);

    /**
     * @dev Returns an array of token IDs owned by `owner`,
     * in the range [`start`, `stop`)
     * (i.e. `start <= tokenId < stop`).
     *
     * This function allows for tokens to be queried if the collection
     * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
     *
     * Requirements:
     *
     * - `start < stop`
     */
    function tokensOfOwnerIn(
        address owner,
        uint256 start,
        uint256 stop
    ) external view returns (uint256[] memory);

    /**
     * @dev Returns an array of token IDs owned by `owner`.
     *
     * This function scans the ownership mapping and is O(`totalSupply`) in complexity.
     * It is meant to be called off-chain.
     *
     * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
     * multiple smaller scans if the collection is large enough to cause
     * an out-of-gas error (10K collections should be fine).
     */
    function tokensOfOwner(address owner) external view returns (uint256[] memory);
}

File 9 of 12: IERC721Enumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

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

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

File 10 of 12: Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./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 () {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), 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 {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

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

File 11 of 12: SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

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

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

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

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

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

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

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

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant alphabet = "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] = alphabet[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"string","name":"_uri","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","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":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"qtyTokens","type":"uint256"}],"name":"RewardClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"qtyTokens","type":"uint256"}],"name":"TokenMinted","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":"FRANKIE_CONTRACT","outputs":[{"internalType":"contract IERC721Enumerable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokensId","type":"uint256[]"}],"name":"claimAllRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_frankieTokenId","type":"uint256"}],"name":"claimReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimRewardDueDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimRewardIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"explicitOwnershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"explicitOwnershipsOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_frankieTokenId","type":"uint256"}],"name":"frankieHasReward","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_offset","type":"uint256"},{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"getOwners","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"getPendingRewards","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"getTotalRewardsToClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPurchase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxQtyClaimPerRequest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_qty","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_owners","type":"address[]"},{"internalType":"uint256","name":"_qty","type":"uint256"}],"name":"mintToWallets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"provenance","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_qtyTokens","type":"uint256"}],"name":"reserveTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","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":"payable","type":"function"},{"inputs":[],"name":"saleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseExtension","type":"string"}],"name":"setBaseExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"BaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newDate","type":"uint256"}],"name":"setClaimRewardDueDate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_newState","type":"bool"}],"name":"setClaimRewardState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contractAddress","type":"address"}],"name":"setFrankieContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_qty","type":"uint256"}],"name":"setMaxPurchase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_qty","type":"uint256"}],"name":"setMaxQtyClaimPerRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_qty","type":"uint256"}],"name":"setMaxTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_provenanceHash","type":"string"}],"name":"setProvenanceHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_newState","type":"bool"}],"name":"setSaleState","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":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"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":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

600980546001600160a01b03191673a9e739ba9e691facc90900d16629f4814805c6ea17905560a06040819052600060808190526200004191600a91620001d4565b506014600b556122b8600c556000600d556363c1f07f600e556064600f556011805461ffff1916600117905560408051808201909152600580825264173539b7b760d91b60209092019182526200009b91601391620001d4565b50348015620000a957600080fd5b50604051620039e4380380620039e4833981016040819052620000cc916200032d565b825183908390620000e5906002906020850190620001d4565b508051620000fb906003906020840190620001d4565b505060016000908155600880546001600160a01b031916339081179091556040519092508291907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35062000153816200015c565b5050506200040d565b6008546001600160a01b03163314620001bb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640160405180910390fd5b8051620001d0906012906020840190620001d4565b5050565b828054620001e290620003ba565b90600052602060002090601f01602090048101928262000206576000855562000251565b82601f106200022157805160ff191683800117855562000251565b8280016001018555821562000251579182015b828111156200025157825182559160200191906001019062000234565b506200025f92915062000263565b5090565b5b808211156200025f576000815560010162000264565b600082601f8301126200028b578081fd5b81516001600160401b0380821115620002a857620002a8620003f7565b604051601f8301601f19908116603f01168101908282118183101715620002d357620002d3620003f7565b81604052838152602092508683858801011115620002ef578485fd5b8491505b83821015620003125785820183015181830184015290820190620002f3565b838211156200032357848385830101525b9695505050505050565b60008060006060848603121562000342578283fd5b83516001600160401b038082111562000359578485fd5b62000367878388016200027a565b945060208601519150808211156200037d578384fd5b6200038b878388016200027a565b93506040860151915080821115620003a1578283fd5b50620003b0868287016200027a565b9150509250925092565b600181811c90821680620003cf57607f821691505b60208210811415620003f157634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b6135c7806200041d6000396000f3fe6080604052600436106102ff5760003560e01c80638da5cb5b11610190578063c87b56dd116100dc578063e985e9c511610095578063ed22ee811161006f578063ed22ee81146108e2578063f2fde38b14610902578063f4a0a52814610922578063f6ed20171461094257600080fd5b8063e985e9c51461085a578063eb8d2444146108a3578063eba890f7146108c257600080fd5b8063c87b56dd146107aa578063d031370b146107ca578063d5f0c9c0146107ea578063da3ef23f1461080a578063e51b41ac1461082a578063e83157421461084457600080fd5b8063a22cb46511610149578063b88d4fde11610123578063b88d4fde14610735578063c23dc68f14610748578063c4e3709514610775578063c66828621461079557600080fd5b8063a22cb465146106d5578063a2beb510146106f5578063ae169a501461071557600080fd5b80638da5cb5b1461064357806395d89b4114610661578063977b055b1461067657806399a2557a1461068c5780639c469d0d146106ac578063a0712d68146106c257600080fd5b8063299983311161024f5780636352211e1161020857806371189742116101e257806371189742146105c1578063715018a6146105e1578063844458b6146105f65780638462151c1461061657600080fd5b80636352211e1461056b5780636817c76c1461058b57806370a08231146105a157600080fd5b806329998331146104c05780633ccfd60b146104e057806342842e0e146104f55780634cfc21071461050857806355f804b31461051e5780635bbb21771461053e57600080fd5b80630f7309e8116102bc57806318160ddd1161029657806318160ddd1461044a5780631ff389111461046d57806322ae67911461048d57806323b872dd146104ad57600080fd5b80630f7309e8146103f5578063109695231461040a57806311e776fe1461042a57600080fd5b806301ffc9a714610304578063048220581461033957806306fdde0314610366578063081812fc14610388578063095ea7b3146103c057806309f368ee146103d5575b600080fd5b34801561031057600080fd5b5061032461031f366004613008565b610962565b60405190151581526020015b60405180910390f35b34801561034557600080fd5b506103596103543660046130b5565b6109b4565b604051610330919061323d565b34801561037257600080fd5b5061037b610a9f565b60405161033091906132f8565b34801561039457600080fd5b506103a86103a3366004613085565b610b31565b6040516001600160a01b039091168152602001610330565b6103d36103ce366004612de8565b610b75565b005b3480156103e157600080fd5b506103d36103f0366004612e47565b610c15565b34801561040157600080fd5b5061037b610d7f565b34801561041657600080fd5b506103d3610425366004613040565b610e0d565b34801561043657600080fd5b506103d3610445366004613085565b610e4e565b34801561045657600080fd5b5061045f610e7d565b604051908152602001610330565b34801561047957600080fd5b506103d3610488366004613085565b610e8b565b34801561049957600080fd5b506009546103a8906001600160a01b031681565b6103d36104bb366004612cf8565b610eba565b3480156104cc57600080fd5b5061045f6104db366004612c88565b61104b565b3480156104ec57600080fd5b506103d36111c8565b6103d3610503366004612cf8565b611221565b34801561051457600080fd5b5061045f600e5481565b34801561052a57600080fd5b506103d3610539366004613040565b61123c565b34801561054a57600080fd5b5061055e610559366004612eed565b611279565b604051610330919061327e565b34801561057757600080fd5b506103a8610586366004613085565b611365565b34801561059757600080fd5b5061045f600d5481565b3480156105ad57600080fd5b5061045f6105bc366004612c88565b611370565b3480156105cd57600080fd5b506103d36105dc366004613085565b6113be565b3480156105ed57600080fd5b506103d36113ed565b34801561060257600080fd5b50610324610611366004613085565b611461565b34801561062257600080fd5b50610636610631366004612c88565b6114ca565b60405161033091906132c0565b34801561064f57600080fd5b506008546001600160a01b03166103a8565b34801561066d57600080fd5b5061037b6115f5565b34801561068257600080fd5b5061045f600b5481565b34801561069857600080fd5b506106366106a7366004612e13565b611604565b3480156106b857600080fd5b5061045f600f5481565b6103d36106d0366004613085565b6117ab565b3480156106e157600080fd5b506103d36106f0366004612db4565b61195f565b34801561070157600080fd5b506103d3610710366004612f5c565b6119cb565b34801561072157600080fd5b506103d3610730366004613085565b611d0c565b6103d3610743366004612d38565b611f6c565b34801561075457600080fd5b50610768610763366004613085565b611fb6565b60405161033091906133cb565b34801561078157600080fd5b506103d3610790366004612fee565b61203e565b3480156107a157600080fd5b5061037b612082565b3480156107b657600080fd5b5061037b6107c5366004613085565b61208f565b3480156107d657600080fd5b506103d36107e5366004613085565b61215c565b3480156107f657600080fd5b506103d3610805366004612fee565b6121ff565b34801561081657600080fd5b506103d3610825366004613040565b61223c565b34801561083657600080fd5b506011546103249060ff1681565b34801561085057600080fd5b5061045f600c5481565b34801561086657600080fd5b50610324610875366004612cc0565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b3480156108af57600080fd5b5060115461032490610100900460ff1681565b3480156108ce57600080fd5b506103d36108dd366004613085565b612279565b3480156108ee57600080fd5b506103d36108fd366004612c88565b6122a8565b34801561090e57600080fd5b506103d361091d366004612c88565b6122f4565b34801561092e57600080fd5b506103d361093d366004613085565b6123df565b34801561094e57600080fd5b5061063661095d366004612c88565b61240e565b60006301ffc9a760e01b6001600160e01b03198316148061099357506380ac58cd60e01b6001600160e01b03198316145b806109ae5750635b5e139f60e01b6001600160e01b03198316145b92915050565b606060006109c0610e7d565b9050806109cd8585612677565b10156109e0576109dd8484612677565b90505b6000816001600160401b03811115610a0857634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610a31578160200160208202803683370190505b509050845b82811015610a9657610a4c61058682600161342c565b828281518110610a6c57634e487b7160e01b600052603260045260246000fd5b6001600160a01b039092166020928302919091019091015280610a8e816134f5565b915050610a36565b50949350505050565b606060028054610aae906134ba565b80601f0160208091040260200160405190810160405280929190818152602001828054610ada906134ba565b8015610b275780601f10610afc57610100808354040283529160200191610b27565b820191906000526020600020905b815481529060010190602001808311610b0a57829003601f168201915b5050505050905090565b6000610b3c82612683565b610b59576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6000610b8082611365565b9050336001600160a01b03821614610bb957610b9c8133610875565b610bb9576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6008546001600160a01b03163314610c485760405162461bcd60e51b8152600401610c3f9061334f565b60405180910390fd5b600c548251610c6990610c5b90846126b8565b610c63610e7d565b90612677565b1115610cb75760405162461bcd60e51b815260206004820181905260248201527f507572636861736520776f756c6420657863656564206d617820737570706c796044820152606401610c3f565b60005b8251811015610d7a57610cf4838281518110610ce657634e487b7160e01b600052603260045260246000fd5b6020026020010151836126c4565b7fb9144c96c86541f6fa89c9f2f02495cccf4b08cd6643e26d34ee00aa586558a8838281518110610d3557634e487b7160e01b600052603260045260246000fd5b602002602001015183604051610d609291906001600160a01b03929092168252602082015260400190565b60405180910390a180610d72816134f5565b915050610cba565b505050565b600a8054610d8c906134ba565b80601f0160208091040260200160405190810160405280929190818152602001828054610db8906134ba565b8015610e055780601f10610dda57610100808354040283529160200191610e05565b820191906000526020600020905b815481529060010190602001808311610de857829003601f168201915b505050505081565b6008546001600160a01b03163314610e375760405162461bcd60e51b8152600401610c3f9061334f565b8051610e4a90600a906020840190612b83565b5050565b6008546001600160a01b03163314610e785760405162461bcd60e51b8152600401610c3f9061334f565b600c55565b600154600054036000190190565b6008546001600160a01b03163314610eb55760405162461bcd60e51b8152600401610c3f9061334f565b600f55565b6000610ec5826126de565b9050836001600160a01b0316816001600160a01b031614610ef85760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417610f4557610f288633610875565b610f4557604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038516610f6c57604051633a954ecd60e21b815260040160405180910390fd5b8015610f7757600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260046020526040902055600160e11b831661100257600184016000818152600460205260409020546110005760005481146110005760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b60115460009060ff166110705760405162461bcd60e51b8152600401610c3f90613384565b6009546040516370a0823160e01b81526001600160a01b03848116600483015260009283928392909116906370a082319060240160206040518083038186803b1580156110bc57600080fd5b505afa1580156110d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f4919061309d565b905060005b818110156111be57600954604051632f745c5960e01b81526001600160a01b0388811660048301526024820184905290911690632f745c599060440160206040518083038186803b15801561114d57600080fd5b505afa158015611161573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611185919061309d565b60008181526010602052604090205490935060ff166111ac576111a9846001612677565b93505b806111b6816134f5565b9150506110f9565b5091949350505050565b6008546001600160a01b031633146111f25760405162461bcd60e51b8152600401610c3f9061334f565b6040514790339082156108fc029083906000818181858888f19350505050158015610e4a573d6000803e3d6000fd5b610d7a83838360405180602001604052806000815250611f6c565b6008546001600160a01b031633146112665760405162461bcd60e51b8152600401610c3f9061334f565b8051610e4a906012906020840190612b83565b6060816000816001600160401b038111156112a457634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156112f657816020015b6040805160808101825260008082526020808301829052928201819052606082015282526000199092019101816112c25790505b50905060005b828114610a965761133286868381811061132657634e487b7160e01b600052603260045260246000fd5b90506020020135611fb6565b82828151811061135257634e487b7160e01b600052603260045260246000fd5b60209081029190910101526001016112fc565b60006109ae826126de565b60006001600160a01b038216611399576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6008546001600160a01b031633146113e85760405162461bcd60e51b8152600401610c3f9061334f565b600b55565b6008546001600160a01b031633146114175760405162461bcd60e51b8152600401610c3f9061334f565b6008546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600880546001600160a01b0319169055565b600080821180156114745750600c548211155b6114b35760405162461bcd60e51b815260206004820152601060248201526f125b9d985b1a5908151bdad95b88125960821b6044820152606401610c3f565b5060009081526010602052604090205460ff161590565b606060008060006114da85611370565b90506000816001600160401b0381111561150457634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561152d578160200160208202803683370190505b50905061155a60408051608081018252600080825260208201819052918101829052606081019190915290565b60015b8386146115e95761156d81612747565b915081604001511561157e576115e1565b81516001600160a01b03161561159357815194505b876001600160a01b0316856001600160a01b031614156115e157808387806001019850815181106115d457634e487b7160e01b600052603260045260246000fd5b6020026020010181815250505b60010161155d565b50909695505050505050565b606060038054610aae906134ba565b606081831061162657604051631960ccad60e11b815260040160405180910390fd5b60008061163260005490565b9050600185101561164257600194505b8084111561164e578093505b600061165987611370565b9050848610156116785785850381811015611672578091505b5061167c565b5060005b6000816001600160401b038111156116a457634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156116cd578160200160208202803683370190505b509050816116e05793506117a492505050565b60006116eb88611fb6565b9050600081604001516116fc575080515b885b88811415801561170e5750848714155b156117985761171c81612747565b925082604001511561172d57611790565b82516001600160a01b03161561174257825191505b8a6001600160a01b0316826001600160a01b03161415611790578084888060010199508151811061178357634e487b7160e01b600052603260045260246000fd5b6020026020010181815250505b6001016116fe565b50505092835250909150505b9392505050565b601154610100900460ff166118025760405162461bcd60e51b815260206004820152601f60248201527f4d696e74206973206e6f7420617661696c61626c65207269676874206e6f77006044820152606401610c3f565b600b5481111561185e5760405162461bcd60e51b815260206004820152602160248201527f43616e206f6e6c79206d696e7420323020746f6b656e7320617420612074696d6044820152606560f81b6064820152608401610c3f565b600c5461186d82610c63610e7d565b11156118bb5760405162461bcd60e51b815260206004820181905260248201527f507572636861736520776f756c6420657863656564206d617820737570706c796044820152606401610c3f565b600d5434906118ca90836126b8565b11156119185760405162461bcd60e51b815260206004820152601960248201527f56616c75652073656e74206973206e6f7420636f7272656374000000000000006044820152606401610c3f565b61192233826126c4565b60408051338152602081018390527fb9144c96c86541f6fa89c9f2f02495cccf4b08cd6643e26d34ee00aa586558a891015b60405180910390a150565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60115460ff166119ed5760405162461bcd60e51b8152600401610c3f90613384565b42600e541015611a3f5760405162461bcd60e51b815260206004820152601d60248201527f54696d6520746f20636c61696d2072657761726473206973206f7665720000006044820152606401610c3f565b600f5481511115611ac25760405162461bcd60e51b815260206004820152604160248201527f546865206e756d626572206f6620746f6b656e7320746f20636c61696d20726560448201527f7761726473206578636565647320746865206d6178696d756d20616c6c6f77656064820152601960fa1b608482015260a401610c3f565b80516000805b82811015611c4657600954845133916001600160a01b031690636352211e90879085908110611b0757634e487b7160e01b600052603260045260246000fd5b60200260200101516040518263ffffffff1660e01b8152600401611b2d91815260200190565b60206040518083038186803b158015611b4557600080fd5b505afa158015611b59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b7d9190612ca4565b6001600160a01b0316148015611bd2575060106000858381518110611bb257634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205460ff16155b15611c3457600160106000868481518110611bfd57634e487b7160e01b600052603260045260246000fd5b6020908102919091018101518252810191909152604001600020805460ff1916911515919091179055611c31826001612677565b91505b80611c3e816134f5565b915050611ac8565b5060008111611c975760405162461bcd60e51b815260206004820152601f60248201527f596f7520646f6e27742068617665207265776172647320746f20636c61696d006044820152606401610c3f565b600c54611ca682610c63610e7d565b1115611cc45760405162461bcd60e51b8152600401610c3f9061330b565b611cce33826126c4565b60408051338152602081018390527f106f923f993c2149d49b4255ff723acafa1f2d94393f561d3eda32ae348f7241910160405180910390a1505050565b60115460ff16611d5e5760405162461bcd60e51b815260206004820152601b60248201527f436c61696d20726577617264206d7573742062652061637469766500000000006044820152606401610c3f565b42600e541015611db05760405162461bcd60e51b815260206004820152601c60248201527f54696d6520746f20636c61696d20726577617264206973206f766572000000006044820152606401610c3f565b60008181526010602052604090205460ff1615611e0f5760405162461bcd60e51b815260206004820152601860248201527f546f6b656e205265776172642077617320636c61696d656400000000000000006044820152606401610c3f565b6009546040516331a9108f60e11b81526004810183905233916001600160a01b031690636352211e9060240160206040518083038186803b158015611e5357600080fd5b505afa158015611e67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e8b9190612ca4565b6001600160a01b031614611ee15760405162461bcd60e51b815260206004820152601b60248201527f596f7520617265206e6f742074686520746f6b656e206f776e657200000000006044820152606401610c3f565b600c54611ef16001610c63610e7d565b1115611f0f5760405162461bcd60e51b8152600401610c3f9061330b565b6000818152601060205260409020805460ff19166001908117909155611f369033906126c4565b60408051338152600160208201527f106f923f993c2149d49b4255ff723acafa1f2d94393f561d3eda32ae348f72419101611954565b611f77848484610eba565b6001600160a01b0383163b15611fb057611f9384848484612783565b611fb0576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b604080516080810182526000808252602082018190529181018290526060810191909152604080516080810182526000808252602082018190529181018290526060810191909152600183108061200f57506000548310155b1561201a5792915050565b61202383612747565b90508060400151156120355792915050565b6117a48361287b565b6008546001600160a01b031633146120685760405162461bcd60e51b8152600401610c3f9061334f565b601180549115156101000261ff0019909216919091179055565b60138054610d8c906134ba565b606061209a82612683565b6120fe5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610c3f565b60006121086128b0565b9050600081511161212857604051806020016040528060008152506117a4565b80612132846128bf565b60136040516020016121469392919061313e565b6040516020818303038152906040529392505050565b6008546001600160a01b031633146121865760405162461bcd60e51b8152600401610c3f9061334f565b600c5461219582610c63610e7d565b11156121f25760405162461bcd60e51b815260206004820152602660248201527f5265736572766520746f6b656e7320776f756c6420657863656564206d617820604482015265737570706c7960d01b6064820152608401610c3f565b6121fc33826126c4565b50565b6008546001600160a01b031633146122295760405162461bcd60e51b8152600401610c3f9061334f565b6011805460ff1916911515919091179055565b6008546001600160a01b031633146122665760405162461bcd60e51b8152600401610c3f9061334f565b8051610e4a906013906020840190612b83565b6008546001600160a01b031633146122a35760405162461bcd60e51b8152600401610c3f9061334f565b600e55565b6008546001600160a01b031633146122d25760405162461bcd60e51b8152600401610c3f9061334f565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6008546001600160a01b0316331461231e5760405162461bcd60e51b8152600401610c3f9061334f565b6001600160a01b0381166123835760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c3f565b6008546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600880546001600160a01b0319166001600160a01b0392909216919091179055565b6008546001600160a01b031633146124095760405162461bcd60e51b8152600401610c3f9061334f565b600d55565b60115460609060ff166124335760405162461bcd60e51b8152600401610c3f90613384565b42600e5410156124855760405162461bcd60e51b815260206004820152601d60248201527f54696d6520746f20636c61696d2072657761726473206973206f7665720000006044820152606401610c3f565b6009546040516370a0823160e01b81526001600160a01b03848116600483015260009283929116906370a082319060240160206040518083038186803b1580156124ce57600080fd5b505afa1580156124e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612506919061309d565b90506000816001600160401b0381111561253057634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612559578160200160208202803683370190505b50905060005b82811015610a9657600954604051632f745c5960e01b81526001600160a01b0388811660048301526024820184905290911690632f745c599060440160206040518083038186803b1580156125b357600080fd5b505afa1580156125c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125eb919061309d565b60008181526010602052604090205490945060ff16612636578382828151811061262557634e487b7160e01b600052603260045260246000fd5b602002602001018181525050612665565b600082828151811061265857634e487b7160e01b600052603260045260246000fd5b6020026020010181815250505b8061266f816134f5565b91505061255f565b60006117a4828461342c565b600081600111158015612697575060005482105b80156109ae575050600090815260046020526040902054600160e01b161590565b60006117a48284613458565b610e4a8282604051806020016040528060008152506129d8565b6000818060011161272e5760005481101561272e57600081815260046020526040902054600160e01b811661272c575b806117a457506000190160008181526004602052604090205461270e565b505b604051636f96cda160e11b815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091526000828152600460205260409020546109ae90612a45565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906127b8903390899088908890600401613200565b602060405180830381600087803b1580156127d257600080fd5b505af1925050508015612802575060408051601f3d908101601f191682019092526127ff91810190613024565b60015b61285d573d808015612830576040519150601f19603f3d011682016040523d82523d6000602084013e612835565b606091505b508051612855576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b6040805160808101825260008082526020820181905291810182905260608101919091526109ae6128ab836126de565b612a45565b606060128054610aae906134ba565b6060816128e35750506040805180820190915260018152600360fc1b602082015290565b8160005b811561290d57806128f7816134f5565b91506129069050600a83613444565b91506128e7565b6000816001600160401b0381111561293557634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561295f576020820181803683370190505b5090505b841561287357612974600183613477565b9150612981600a86613510565b61298c90603061342c565b60f81b8183815181106129af57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506129d1600a86613444565b9450612963565b6129e28383612a8c565b6001600160a01b0383163b15610d7a576000548281035b612a0c6000868380600101945086612783565b612a29576040516368d2bf6b60e11b815260040160405180910390fd5b8181106129f9578160005414612a3e57600080fd5b5050505050565b604080516080810182526001600160a01b038316815260a083901c6001600160401b03166020820152600160e01b831615159181019190915260e89190911c606082015290565b60005481612aad5760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b03831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b818114612b5c57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101612b24565b5081612b7a57604051622e076360e81b815260040160405180910390fd5b60005550505050565b828054612b8f906134ba565b90600052602060002090601f016020900481019282612bb15760008555612bf7565b82601f10612bca57805160ff1916838001178555612bf7565b82800160010185558215612bf7579182015b82811115612bf7578251825591602001919060010190612bdc565b50612c03929150612c07565b5090565b5b80821115612c035760008155600101612c08565b60006001600160401b03831115612c3557612c35613550565b612c48601f8401601f19166020016133d9565b9050828152838383011115612c5c57600080fd5b828260208301376000602084830101529392505050565b80358015158114612c8357600080fd5b919050565b600060208284031215612c99578081fd5b81356117a481613566565b600060208284031215612cb5578081fd5b81516117a481613566565b60008060408385031215612cd2578081fd5b8235612cdd81613566565b91506020830135612ced81613566565b809150509250929050565b600080600060608486031215612d0c578081fd5b8335612d1781613566565b92506020840135612d2781613566565b929592945050506040919091013590565b60008060008060808587031215612d4d578081fd5b8435612d5881613566565b93506020850135612d6881613566565b92506040850135915060608501356001600160401b03811115612d89578182fd5b8501601f81018713612d99578182fd5b612da887823560208401612c1c565b91505092959194509250565b60008060408385031215612dc6578182fd5b8235612dd181613566565b9150612ddf60208401612c73565b90509250929050565b60008060408385031215612dfa578182fd5b8235612e0581613566565b946020939093013593505050565b600080600060608486031215612e27578081fd5b8335612e3281613566565b95602085013595506040909401359392505050565b60008060408385031215612e59578182fd5b82356001600160401b03811115612e6e578283fd5b8301601f81018513612e7e578283fd5b80356020612e93612e8e83613409565b6133d9565b80838252828201915082850189848660051b8801011115612eb2578788fd5b8795505b84861015612edd578035612ec981613566565b835260019590950194918301918301612eb6565b5098969091013596505050505050565b60008060208385031215612eff578182fd5b82356001600160401b0380821115612f15578384fd5b818501915085601f830112612f28578384fd5b813581811115612f36578485fd5b8660208260051b8501011115612f4a578485fd5b60209290920196919550909350505050565b60006020808385031215612f6e578182fd5b82356001600160401b03811115612f83578283fd5b8301601f81018513612f93578283fd5b8035612fa1612e8e82613409565b80828252848201915084840188868560051b8701011115612fc0578687fd5b8694505b83851015612fe2578035835260019490940193918501918501612fc4565b50979650505050505050565b600060208284031215612fff578081fd5b6117a482612c73565b600060208284031215613019578081fd5b81356117a48161357b565b600060208284031215613035578081fd5b81516117a48161357b565b600060208284031215613051578081fd5b81356001600160401b03811115613066578182fd5b8201601f81018413613076578182fd5b61287384823560208401612c1c565b600060208284031215613096578081fd5b5035919050565b6000602082840312156130ae578081fd5b5051919050565b600080604083850312156130c7578182fd5b50508035926020909101359150565b600081518084526130ee81602086016020860161348e565b601f01601f19169290920160200192915050565b80516001600160a01b031682526020808201516001600160401b03169083015260408082015115159083015260609081015162ffffff16910152565b6000845160206131518285838a0161348e565b8551918401916131648184848a0161348e565b85549201918390600181811c908083168061318057607f831692505b85831081141561319e57634e487b7160e01b88526022600452602488fd5b8080156131b257600181146131c3576131ef565b60ff198516885283880195506131ef565b60008b815260209020895b858110156131e75781548a8201529084019088016131ce565b505083880195505b50939b9a5050505050505050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090613233908301846130d6565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156115e95783516001600160a01b031683529284019291840191600101613259565b6020808252825182820181905260009190848201906040850190845b818110156115e9576132ad838551613102565b928401926080929092019160010161329a565b6020808252825182820181905260009190848201906040850190845b818110156115e9578351835292840192918401916001016132dc565b6020815260006117a460208301846130d6565b60208082526024908201527f436c61696d2072657761726420776f756c6420657863656564206d617820737560408201526370706c7960e01b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526027908201527f436c61696d20726577617264206973206e6f7420617661696c61626c65207269604082015266676874206e6f7760c81b606082015260800190565b608081016109ae8284613102565b604051601f8201601f191681016001600160401b038111828210171561340157613401613550565b604052919050565b60006001600160401b0382111561342257613422613550565b5060051b60200190565b6000821982111561343f5761343f613524565b500190565b6000826134535761345361353a565b500490565b600081600019048311821515161561347257613472613524565b500290565b60008282101561348957613489613524565b500390565b60005b838110156134a9578181015183820152602001613491565b83811115611fb05750506000910152565b600181811c908216806134ce57607f821691505b602082108114156134ef57634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561350957613509613524565b5060010190565b60008261351f5761351f61353a565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146121fc57600080fd5b6001600160e01b0319811681146121fc57600080fdfea2646970667358221220ccc4f7f0676e81d97097de98e5c3140f53eb68bad62a8d71f7ff6d2d3f506baa64736f6c63430008040033000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000743726561746f720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044352545200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003668747470733a2f2f6170702e6672616e6b6965736d616e73696f6e2e636f6d2f63726561746f722f6d696e742f6d657461646174612f00000000000000000000

Deployed Bytecode

0x6080604052600436106102ff5760003560e01c80638da5cb5b11610190578063c87b56dd116100dc578063e985e9c511610095578063ed22ee811161006f578063ed22ee81146108e2578063f2fde38b14610902578063f4a0a52814610922578063f6ed20171461094257600080fd5b8063e985e9c51461085a578063eb8d2444146108a3578063eba890f7146108c257600080fd5b8063c87b56dd146107aa578063d031370b146107ca578063d5f0c9c0146107ea578063da3ef23f1461080a578063e51b41ac1461082a578063e83157421461084457600080fd5b8063a22cb46511610149578063b88d4fde11610123578063b88d4fde14610735578063c23dc68f14610748578063c4e3709514610775578063c66828621461079557600080fd5b8063a22cb465146106d5578063a2beb510146106f5578063ae169a501461071557600080fd5b80638da5cb5b1461064357806395d89b4114610661578063977b055b1461067657806399a2557a1461068c5780639c469d0d146106ac578063a0712d68146106c257600080fd5b8063299983311161024f5780636352211e1161020857806371189742116101e257806371189742146105c1578063715018a6146105e1578063844458b6146105f65780638462151c1461061657600080fd5b80636352211e1461056b5780636817c76c1461058b57806370a08231146105a157600080fd5b806329998331146104c05780633ccfd60b146104e057806342842e0e146104f55780634cfc21071461050857806355f804b31461051e5780635bbb21771461053e57600080fd5b80630f7309e8116102bc57806318160ddd1161029657806318160ddd1461044a5780631ff389111461046d57806322ae67911461048d57806323b872dd146104ad57600080fd5b80630f7309e8146103f5578063109695231461040a57806311e776fe1461042a57600080fd5b806301ffc9a714610304578063048220581461033957806306fdde0314610366578063081812fc14610388578063095ea7b3146103c057806309f368ee146103d5575b600080fd5b34801561031057600080fd5b5061032461031f366004613008565b610962565b60405190151581526020015b60405180910390f35b34801561034557600080fd5b506103596103543660046130b5565b6109b4565b604051610330919061323d565b34801561037257600080fd5b5061037b610a9f565b60405161033091906132f8565b34801561039457600080fd5b506103a86103a3366004613085565b610b31565b6040516001600160a01b039091168152602001610330565b6103d36103ce366004612de8565b610b75565b005b3480156103e157600080fd5b506103d36103f0366004612e47565b610c15565b34801561040157600080fd5b5061037b610d7f565b34801561041657600080fd5b506103d3610425366004613040565b610e0d565b34801561043657600080fd5b506103d3610445366004613085565b610e4e565b34801561045657600080fd5b5061045f610e7d565b604051908152602001610330565b34801561047957600080fd5b506103d3610488366004613085565b610e8b565b34801561049957600080fd5b506009546103a8906001600160a01b031681565b6103d36104bb366004612cf8565b610eba565b3480156104cc57600080fd5b5061045f6104db366004612c88565b61104b565b3480156104ec57600080fd5b506103d36111c8565b6103d3610503366004612cf8565b611221565b34801561051457600080fd5b5061045f600e5481565b34801561052a57600080fd5b506103d3610539366004613040565b61123c565b34801561054a57600080fd5b5061055e610559366004612eed565b611279565b604051610330919061327e565b34801561057757600080fd5b506103a8610586366004613085565b611365565b34801561059757600080fd5b5061045f600d5481565b3480156105ad57600080fd5b5061045f6105bc366004612c88565b611370565b3480156105cd57600080fd5b506103d36105dc366004613085565b6113be565b3480156105ed57600080fd5b506103d36113ed565b34801561060257600080fd5b50610324610611366004613085565b611461565b34801561062257600080fd5b50610636610631366004612c88565b6114ca565b60405161033091906132c0565b34801561064f57600080fd5b506008546001600160a01b03166103a8565b34801561066d57600080fd5b5061037b6115f5565b34801561068257600080fd5b5061045f600b5481565b34801561069857600080fd5b506106366106a7366004612e13565b611604565b3480156106b857600080fd5b5061045f600f5481565b6103d36106d0366004613085565b6117ab565b3480156106e157600080fd5b506103d36106f0366004612db4565b61195f565b34801561070157600080fd5b506103d3610710366004612f5c565b6119cb565b34801561072157600080fd5b506103d3610730366004613085565b611d0c565b6103d3610743366004612d38565b611f6c565b34801561075457600080fd5b50610768610763366004613085565b611fb6565b60405161033091906133cb565b34801561078157600080fd5b506103d3610790366004612fee565b61203e565b3480156107a157600080fd5b5061037b612082565b3480156107b657600080fd5b5061037b6107c5366004613085565b61208f565b3480156107d657600080fd5b506103d36107e5366004613085565b61215c565b3480156107f657600080fd5b506103d3610805366004612fee565b6121ff565b34801561081657600080fd5b506103d3610825366004613040565b61223c565b34801561083657600080fd5b506011546103249060ff1681565b34801561085057600080fd5b5061045f600c5481565b34801561086657600080fd5b50610324610875366004612cc0565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b3480156108af57600080fd5b5060115461032490610100900460ff1681565b3480156108ce57600080fd5b506103d36108dd366004613085565b612279565b3480156108ee57600080fd5b506103d36108fd366004612c88565b6122a8565b34801561090e57600080fd5b506103d361091d366004612c88565b6122f4565b34801561092e57600080fd5b506103d361093d366004613085565b6123df565b34801561094e57600080fd5b5061063661095d366004612c88565b61240e565b60006301ffc9a760e01b6001600160e01b03198316148061099357506380ac58cd60e01b6001600160e01b03198316145b806109ae5750635b5e139f60e01b6001600160e01b03198316145b92915050565b606060006109c0610e7d565b9050806109cd8585612677565b10156109e0576109dd8484612677565b90505b6000816001600160401b03811115610a0857634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610a31578160200160208202803683370190505b509050845b82811015610a9657610a4c61058682600161342c565b828281518110610a6c57634e487b7160e01b600052603260045260246000fd5b6001600160a01b039092166020928302919091019091015280610a8e816134f5565b915050610a36565b50949350505050565b606060028054610aae906134ba565b80601f0160208091040260200160405190810160405280929190818152602001828054610ada906134ba565b8015610b275780601f10610afc57610100808354040283529160200191610b27565b820191906000526020600020905b815481529060010190602001808311610b0a57829003601f168201915b5050505050905090565b6000610b3c82612683565b610b59576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6000610b8082611365565b9050336001600160a01b03821614610bb957610b9c8133610875565b610bb9576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6008546001600160a01b03163314610c485760405162461bcd60e51b8152600401610c3f9061334f565b60405180910390fd5b600c548251610c6990610c5b90846126b8565b610c63610e7d565b90612677565b1115610cb75760405162461bcd60e51b815260206004820181905260248201527f507572636861736520776f756c6420657863656564206d617820737570706c796044820152606401610c3f565b60005b8251811015610d7a57610cf4838281518110610ce657634e487b7160e01b600052603260045260246000fd5b6020026020010151836126c4565b7fb9144c96c86541f6fa89c9f2f02495cccf4b08cd6643e26d34ee00aa586558a8838281518110610d3557634e487b7160e01b600052603260045260246000fd5b602002602001015183604051610d609291906001600160a01b03929092168252602082015260400190565b60405180910390a180610d72816134f5565b915050610cba565b505050565b600a8054610d8c906134ba565b80601f0160208091040260200160405190810160405280929190818152602001828054610db8906134ba565b8015610e055780601f10610dda57610100808354040283529160200191610e05565b820191906000526020600020905b815481529060010190602001808311610de857829003601f168201915b505050505081565b6008546001600160a01b03163314610e375760405162461bcd60e51b8152600401610c3f9061334f565b8051610e4a90600a906020840190612b83565b5050565b6008546001600160a01b03163314610e785760405162461bcd60e51b8152600401610c3f9061334f565b600c55565b600154600054036000190190565b6008546001600160a01b03163314610eb55760405162461bcd60e51b8152600401610c3f9061334f565b600f55565b6000610ec5826126de565b9050836001600160a01b0316816001600160a01b031614610ef85760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417610f4557610f288633610875565b610f4557604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038516610f6c57604051633a954ecd60e21b815260040160405180910390fd5b8015610f7757600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260046020526040902055600160e11b831661100257600184016000818152600460205260409020546110005760005481146110005760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b60115460009060ff166110705760405162461bcd60e51b8152600401610c3f90613384565b6009546040516370a0823160e01b81526001600160a01b03848116600483015260009283928392909116906370a082319060240160206040518083038186803b1580156110bc57600080fd5b505afa1580156110d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f4919061309d565b905060005b818110156111be57600954604051632f745c5960e01b81526001600160a01b0388811660048301526024820184905290911690632f745c599060440160206040518083038186803b15801561114d57600080fd5b505afa158015611161573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611185919061309d565b60008181526010602052604090205490935060ff166111ac576111a9846001612677565b93505b806111b6816134f5565b9150506110f9565b5091949350505050565b6008546001600160a01b031633146111f25760405162461bcd60e51b8152600401610c3f9061334f565b6040514790339082156108fc029083906000818181858888f19350505050158015610e4a573d6000803e3d6000fd5b610d7a83838360405180602001604052806000815250611f6c565b6008546001600160a01b031633146112665760405162461bcd60e51b8152600401610c3f9061334f565b8051610e4a906012906020840190612b83565b6060816000816001600160401b038111156112a457634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156112f657816020015b6040805160808101825260008082526020808301829052928201819052606082015282526000199092019101816112c25790505b50905060005b828114610a965761133286868381811061132657634e487b7160e01b600052603260045260246000fd5b90506020020135611fb6565b82828151811061135257634e487b7160e01b600052603260045260246000fd5b60209081029190910101526001016112fc565b60006109ae826126de565b60006001600160a01b038216611399576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6008546001600160a01b031633146113e85760405162461bcd60e51b8152600401610c3f9061334f565b600b55565b6008546001600160a01b031633146114175760405162461bcd60e51b8152600401610c3f9061334f565b6008546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600880546001600160a01b0319169055565b600080821180156114745750600c548211155b6114b35760405162461bcd60e51b815260206004820152601060248201526f125b9d985b1a5908151bdad95b88125960821b6044820152606401610c3f565b5060009081526010602052604090205460ff161590565b606060008060006114da85611370565b90506000816001600160401b0381111561150457634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561152d578160200160208202803683370190505b50905061155a60408051608081018252600080825260208201819052918101829052606081019190915290565b60015b8386146115e95761156d81612747565b915081604001511561157e576115e1565b81516001600160a01b03161561159357815194505b876001600160a01b0316856001600160a01b031614156115e157808387806001019850815181106115d457634e487b7160e01b600052603260045260246000fd5b6020026020010181815250505b60010161155d565b50909695505050505050565b606060038054610aae906134ba565b606081831061162657604051631960ccad60e11b815260040160405180910390fd5b60008061163260005490565b9050600185101561164257600194505b8084111561164e578093505b600061165987611370565b9050848610156116785785850381811015611672578091505b5061167c565b5060005b6000816001600160401b038111156116a457634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156116cd578160200160208202803683370190505b509050816116e05793506117a492505050565b60006116eb88611fb6565b9050600081604001516116fc575080515b885b88811415801561170e5750848714155b156117985761171c81612747565b925082604001511561172d57611790565b82516001600160a01b03161561174257825191505b8a6001600160a01b0316826001600160a01b03161415611790578084888060010199508151811061178357634e487b7160e01b600052603260045260246000fd5b6020026020010181815250505b6001016116fe565b50505092835250909150505b9392505050565b601154610100900460ff166118025760405162461bcd60e51b815260206004820152601f60248201527f4d696e74206973206e6f7420617661696c61626c65207269676874206e6f77006044820152606401610c3f565b600b5481111561185e5760405162461bcd60e51b815260206004820152602160248201527f43616e206f6e6c79206d696e7420323020746f6b656e7320617420612074696d6044820152606560f81b6064820152608401610c3f565b600c5461186d82610c63610e7d565b11156118bb5760405162461bcd60e51b815260206004820181905260248201527f507572636861736520776f756c6420657863656564206d617820737570706c796044820152606401610c3f565b600d5434906118ca90836126b8565b11156119185760405162461bcd60e51b815260206004820152601960248201527f56616c75652073656e74206973206e6f7420636f7272656374000000000000006044820152606401610c3f565b61192233826126c4565b60408051338152602081018390527fb9144c96c86541f6fa89c9f2f02495cccf4b08cd6643e26d34ee00aa586558a891015b60405180910390a150565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60115460ff166119ed5760405162461bcd60e51b8152600401610c3f90613384565b42600e541015611a3f5760405162461bcd60e51b815260206004820152601d60248201527f54696d6520746f20636c61696d2072657761726473206973206f7665720000006044820152606401610c3f565b600f5481511115611ac25760405162461bcd60e51b815260206004820152604160248201527f546865206e756d626572206f6620746f6b656e7320746f20636c61696d20726560448201527f7761726473206578636565647320746865206d6178696d756d20616c6c6f77656064820152601960fa1b608482015260a401610c3f565b80516000805b82811015611c4657600954845133916001600160a01b031690636352211e90879085908110611b0757634e487b7160e01b600052603260045260246000fd5b60200260200101516040518263ffffffff1660e01b8152600401611b2d91815260200190565b60206040518083038186803b158015611b4557600080fd5b505afa158015611b59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b7d9190612ca4565b6001600160a01b0316148015611bd2575060106000858381518110611bb257634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205460ff16155b15611c3457600160106000868481518110611bfd57634e487b7160e01b600052603260045260246000fd5b6020908102919091018101518252810191909152604001600020805460ff1916911515919091179055611c31826001612677565b91505b80611c3e816134f5565b915050611ac8565b5060008111611c975760405162461bcd60e51b815260206004820152601f60248201527f596f7520646f6e27742068617665207265776172647320746f20636c61696d006044820152606401610c3f565b600c54611ca682610c63610e7d565b1115611cc45760405162461bcd60e51b8152600401610c3f9061330b565b611cce33826126c4565b60408051338152602081018390527f106f923f993c2149d49b4255ff723acafa1f2d94393f561d3eda32ae348f7241910160405180910390a1505050565b60115460ff16611d5e5760405162461bcd60e51b815260206004820152601b60248201527f436c61696d20726577617264206d7573742062652061637469766500000000006044820152606401610c3f565b42600e541015611db05760405162461bcd60e51b815260206004820152601c60248201527f54696d6520746f20636c61696d20726577617264206973206f766572000000006044820152606401610c3f565b60008181526010602052604090205460ff1615611e0f5760405162461bcd60e51b815260206004820152601860248201527f546f6b656e205265776172642077617320636c61696d656400000000000000006044820152606401610c3f565b6009546040516331a9108f60e11b81526004810183905233916001600160a01b031690636352211e9060240160206040518083038186803b158015611e5357600080fd5b505afa158015611e67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e8b9190612ca4565b6001600160a01b031614611ee15760405162461bcd60e51b815260206004820152601b60248201527f596f7520617265206e6f742074686520746f6b656e206f776e657200000000006044820152606401610c3f565b600c54611ef16001610c63610e7d565b1115611f0f5760405162461bcd60e51b8152600401610c3f9061330b565b6000818152601060205260409020805460ff19166001908117909155611f369033906126c4565b60408051338152600160208201527f106f923f993c2149d49b4255ff723acafa1f2d94393f561d3eda32ae348f72419101611954565b611f77848484610eba565b6001600160a01b0383163b15611fb057611f9384848484612783565b611fb0576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b604080516080810182526000808252602082018190529181018290526060810191909152604080516080810182526000808252602082018190529181018290526060810191909152600183108061200f57506000548310155b1561201a5792915050565b61202383612747565b90508060400151156120355792915050565b6117a48361287b565b6008546001600160a01b031633146120685760405162461bcd60e51b8152600401610c3f9061334f565b601180549115156101000261ff0019909216919091179055565b60138054610d8c906134ba565b606061209a82612683565b6120fe5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610c3f565b60006121086128b0565b9050600081511161212857604051806020016040528060008152506117a4565b80612132846128bf565b60136040516020016121469392919061313e565b6040516020818303038152906040529392505050565b6008546001600160a01b031633146121865760405162461bcd60e51b8152600401610c3f9061334f565b600c5461219582610c63610e7d565b11156121f25760405162461bcd60e51b815260206004820152602660248201527f5265736572766520746f6b656e7320776f756c6420657863656564206d617820604482015265737570706c7960d01b6064820152608401610c3f565b6121fc33826126c4565b50565b6008546001600160a01b031633146122295760405162461bcd60e51b8152600401610c3f9061334f565b6011805460ff1916911515919091179055565b6008546001600160a01b031633146122665760405162461bcd60e51b8152600401610c3f9061334f565b8051610e4a906013906020840190612b83565b6008546001600160a01b031633146122a35760405162461bcd60e51b8152600401610c3f9061334f565b600e55565b6008546001600160a01b031633146122d25760405162461bcd60e51b8152600401610c3f9061334f565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6008546001600160a01b0316331461231e5760405162461bcd60e51b8152600401610c3f9061334f565b6001600160a01b0381166123835760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c3f565b6008546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600880546001600160a01b0319166001600160a01b0392909216919091179055565b6008546001600160a01b031633146124095760405162461bcd60e51b8152600401610c3f9061334f565b600d55565b60115460609060ff166124335760405162461bcd60e51b8152600401610c3f90613384565b42600e5410156124855760405162461bcd60e51b815260206004820152601d60248201527f54696d6520746f20636c61696d2072657761726473206973206f7665720000006044820152606401610c3f565b6009546040516370a0823160e01b81526001600160a01b03848116600483015260009283929116906370a082319060240160206040518083038186803b1580156124ce57600080fd5b505afa1580156124e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612506919061309d565b90506000816001600160401b0381111561253057634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612559578160200160208202803683370190505b50905060005b82811015610a9657600954604051632f745c5960e01b81526001600160a01b0388811660048301526024820184905290911690632f745c599060440160206040518083038186803b1580156125b357600080fd5b505afa1580156125c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125eb919061309d565b60008181526010602052604090205490945060ff16612636578382828151811061262557634e487b7160e01b600052603260045260246000fd5b602002602001018181525050612665565b600082828151811061265857634e487b7160e01b600052603260045260246000fd5b6020026020010181815250505b8061266f816134f5565b91505061255f565b60006117a4828461342c565b600081600111158015612697575060005482105b80156109ae575050600090815260046020526040902054600160e01b161590565b60006117a48284613458565b610e4a8282604051806020016040528060008152506129d8565b6000818060011161272e5760005481101561272e57600081815260046020526040902054600160e01b811661272c575b806117a457506000190160008181526004602052604090205461270e565b505b604051636f96cda160e11b815260040160405180910390fd5b6040805160808101825260008082526020820181905291810182905260608101919091526000828152600460205260409020546109ae90612a45565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906127b8903390899088908890600401613200565b602060405180830381600087803b1580156127d257600080fd5b505af1925050508015612802575060408051601f3d908101601f191682019092526127ff91810190613024565b60015b61285d573d808015612830576040519150601f19603f3d011682016040523d82523d6000602084013e612835565b606091505b508051612855576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b6040805160808101825260008082526020820181905291810182905260608101919091526109ae6128ab836126de565b612a45565b606060128054610aae906134ba565b6060816128e35750506040805180820190915260018152600360fc1b602082015290565b8160005b811561290d57806128f7816134f5565b91506129069050600a83613444565b91506128e7565b6000816001600160401b0381111561293557634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561295f576020820181803683370190505b5090505b841561287357612974600183613477565b9150612981600a86613510565b61298c90603061342c565b60f81b8183815181106129af57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506129d1600a86613444565b9450612963565b6129e28383612a8c565b6001600160a01b0383163b15610d7a576000548281035b612a0c6000868380600101945086612783565b612a29576040516368d2bf6b60e11b815260040160405180910390fd5b8181106129f9578160005414612a3e57600080fd5b5050505050565b604080516080810182526001600160a01b038316815260a083901c6001600160401b03166020820152600160e01b831615159181019190915260e89190911c606082015290565b60005481612aad5760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b03831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b818114612b5c57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101612b24565b5081612b7a57604051622e076360e81b815260040160405180910390fd5b60005550505050565b828054612b8f906134ba565b90600052602060002090601f016020900481019282612bb15760008555612bf7565b82601f10612bca57805160ff1916838001178555612bf7565b82800160010185558215612bf7579182015b82811115612bf7578251825591602001919060010190612bdc565b50612c03929150612c07565b5090565b5b80821115612c035760008155600101612c08565b60006001600160401b03831115612c3557612c35613550565b612c48601f8401601f19166020016133d9565b9050828152838383011115612c5c57600080fd5b828260208301376000602084830101529392505050565b80358015158114612c8357600080fd5b919050565b600060208284031215612c99578081fd5b81356117a481613566565b600060208284031215612cb5578081fd5b81516117a481613566565b60008060408385031215612cd2578081fd5b8235612cdd81613566565b91506020830135612ced81613566565b809150509250929050565b600080600060608486031215612d0c578081fd5b8335612d1781613566565b92506020840135612d2781613566565b929592945050506040919091013590565b60008060008060808587031215612d4d578081fd5b8435612d5881613566565b93506020850135612d6881613566565b92506040850135915060608501356001600160401b03811115612d89578182fd5b8501601f81018713612d99578182fd5b612da887823560208401612c1c565b91505092959194509250565b60008060408385031215612dc6578182fd5b8235612dd181613566565b9150612ddf60208401612c73565b90509250929050565b60008060408385031215612dfa578182fd5b8235612e0581613566565b946020939093013593505050565b600080600060608486031215612e27578081fd5b8335612e3281613566565b95602085013595506040909401359392505050565b60008060408385031215612e59578182fd5b82356001600160401b03811115612e6e578283fd5b8301601f81018513612e7e578283fd5b80356020612e93612e8e83613409565b6133d9565b80838252828201915082850189848660051b8801011115612eb2578788fd5b8795505b84861015612edd578035612ec981613566565b835260019590950194918301918301612eb6565b5098969091013596505050505050565b60008060208385031215612eff578182fd5b82356001600160401b0380821115612f15578384fd5b818501915085601f830112612f28578384fd5b813581811115612f36578485fd5b8660208260051b8501011115612f4a578485fd5b60209290920196919550909350505050565b60006020808385031215612f6e578182fd5b82356001600160401b03811115612f83578283fd5b8301601f81018513612f93578283fd5b8035612fa1612e8e82613409565b80828252848201915084840188868560051b8701011115612fc0578687fd5b8694505b83851015612fe2578035835260019490940193918501918501612fc4565b50979650505050505050565b600060208284031215612fff578081fd5b6117a482612c73565b600060208284031215613019578081fd5b81356117a48161357b565b600060208284031215613035578081fd5b81516117a48161357b565b600060208284031215613051578081fd5b81356001600160401b03811115613066578182fd5b8201601f81018413613076578182fd5b61287384823560208401612c1c565b600060208284031215613096578081fd5b5035919050565b6000602082840312156130ae578081fd5b5051919050565b600080604083850312156130c7578182fd5b50508035926020909101359150565b600081518084526130ee81602086016020860161348e565b601f01601f19169290920160200192915050565b80516001600160a01b031682526020808201516001600160401b03169083015260408082015115159083015260609081015162ffffff16910152565b6000845160206131518285838a0161348e565b8551918401916131648184848a0161348e565b85549201918390600181811c908083168061318057607f831692505b85831081141561319e57634e487b7160e01b88526022600452602488fd5b8080156131b257600181146131c3576131ef565b60ff198516885283880195506131ef565b60008b815260209020895b858110156131e75781548a8201529084019088016131ce565b505083880195505b50939b9a5050505050505050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090613233908301846130d6565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156115e95783516001600160a01b031683529284019291840191600101613259565b6020808252825182820181905260009190848201906040850190845b818110156115e9576132ad838551613102565b928401926080929092019160010161329a565b6020808252825182820181905260009190848201906040850190845b818110156115e9578351835292840192918401916001016132dc565b6020815260006117a460208301846130d6565b60208082526024908201527f436c61696d2072657761726420776f756c6420657863656564206d617820737560408201526370706c7960e01b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526027908201527f436c61696d20726577617264206973206e6f7420617661696c61626c65207269604082015266676874206e6f7760c81b606082015260800190565b608081016109ae8284613102565b604051601f8201601f191681016001600160401b038111828210171561340157613401613550565b604052919050565b60006001600160401b0382111561342257613422613550565b5060051b60200190565b6000821982111561343f5761343f613524565b500190565b6000826134535761345361353a565b500490565b600081600019048311821515161561347257613472613524565b500290565b60008282101561348957613489613524565b500390565b60005b838110156134a9578181015183820152602001613491565b83811115611fb05750506000910152565b600181811c908216806134ce57607f821691505b602082108114156134ef57634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561350957613509613524565b5060010190565b60008261351f5761351f61353a565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146121fc57600080fd5b6001600160e01b0319811681146121fc57600080fdfea2646970667358221220ccc4f7f0676e81d97097de98e5c3140f53eb68bad62a8d71f7ff6d2d3f506baa64736f6c63430008040033

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

000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000743726561746f720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044352545200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003668747470733a2f2f6170702e6672616e6b6965736d616e73696f6e2e636f6d2f63726561746f722f6d696e742f6d657461646174612f00000000000000000000

-----Decoded View---------------
Arg [0] : _name (string): Creator
Arg [1] : _symbol (string): CRTR
Arg [2] : _uri (string): https://app.frankiesmansion.com/creator/mint/metadata/

-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [4] : 43726561746f7200000000000000000000000000000000000000000000000000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [6] : 4352545200000000000000000000000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000036
Arg [8] : 68747470733a2f2f6170702e6672616e6b6965736d616e73696f6e2e636f6d2f
Arg [9] : 63726561746f722f6d696e742f6d657461646174612f00000000000000000000


Deployed Bytecode Sourcemap

198:9278:1:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9155:630:2;;;;;;;;;;-1:-1:-1;9155:630:2;;;;;:::i;:::-;;:::i;:::-;;;14081:14:12;;14074:22;14056:41;;14044:2;14029:18;9155:630:2;;;;;;;;9041:433:1;;;;;;;;;;-1:-1:-1;9041:433:1;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;10039:98:2:-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;16360:214::-;;;;;;;;;;-1:-1:-1;16360:214:2;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;10775:32:12;;;10757:51;;10745:2;10730:18;16360:214:2;10712:102:12;15812:398:2;;;;;;:::i;:::-;;:::i;:::-;;4667:358:1;;;;;;;;;;-1:-1:-1;4667:358:1;;;;;:::i;:::-;;:::i;582:29::-;;;;;;;;;;;;;:::i;1785:120::-;;;;;;;;;;-1:-1:-1;1785:120:1;;;;;:::i;:::-;;:::i;2422:86::-;;;;;;;;;;-1:-1:-1;2422:86:1;;;;;:::i;:::-;;:::i;5894:317:2:-;;;;;;;;;;;;;:::i;:::-;;;21825:25:12;;;21813:2;21798:18;5894:317:2;21780:76:12;2577:110:1;;;;;;;;;;-1:-1:-1;2577:110:1;;;;;:::i;:::-;;:::i;445:105::-;;;;;;;;;;-1:-1:-1;445:105:1;;;;-1:-1:-1;;;;;445:105:1;;;19903:2764:2;;;;;;:::i;:::-;;:::i;8132:575:1:-;;;;;;;;;;-1:-1:-1;8132:575:1;;;;;:::i;:::-;;:::i;4119:137::-;;;;;;;;;;;;;:::i;22758:187:2:-;;;;;;:::i;:::-;;:::i;842:46:1:-;;;;;;;;;;;;;;;;3284:94;;;;;;;;;;-1:-1:-1;3284:94:1;;;;;:::i;:::-;;:::i;1640:513:3:-;;;;;;;;;;-1:-1:-1;1640:513:3;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;11391:150:2:-;;;;;;;;;;-1:-1:-1;11391:150:2;;;;;:::i;:::-;;:::i;789:28:1:-;;;;;;;;;;;;;;;;7045:230:2;;;;;;;;;;-1:-1:-1;7045:230:2;;;;;:::i;:::-;;:::i;2280:90:1:-;;;;;;;;;;-1:-1:-1;2280:90:1;;;;;:::i;:::-;;:::i;1693:145:9:-;;;;;;;;;;;;;:::i;8772:224:1:-;;;;;;;;;;-1:-1:-1;8772:224:1;;;;;:::i;:::-;;:::i;5416:879:3:-;;;;;;;;;;-1:-1:-1;5416:879:3;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1061:85:9:-;;;;;;;;;;-1:-1:-1;1133:6:9;;-1:-1:-1;;;;;1133:6:9;1061:85;;10208:102:2;;;;;;;;;;;;;:::i;679:28:1:-;;;;;;;;;;;;;;;;2527:2454:3;;;;;;;;;;-1:-1:-1;2527:2454:3;;;;;:::i;:::-;;:::i;981:42:1:-;;;;;;;;;;;;;;;;5064:449;;;;;;:::i;:::-;;:::i;16901:231:2:-;;;;;;;;;;-1:-1:-1;16901:231:2;;;;;:::i;:::-;;:::i;5560:997:1:-;;;;;;;;;;-1:-1:-1;5560:997:1;;;;;:::i;:::-;;:::i;6609:623::-;;;;;;;;;;-1:-1:-1;6609:623:1;;;;;:::i;:::-;;:::i;23526:396:2:-;;;;;;:::i;:::-;;:::i;1069:418:3:-;;;;;;;;;;-1:-1:-1;1069:418:3;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;2139:96:1:-;;;;;;;;;;-1:-1:-1;2139:96:1;;;;;:::i;:::-;;:::i;1301:37::-;;;;;;;;;;;;;:::i;3689:392::-;;;;;;;;;;-1:-1:-1;3689:392:1;;;;;:::i;:::-;;:::i;4405:211::-;;;;;;;;;;-1:-1:-1;4405:211:1;;;;;:::i;:::-;;:::i;1957:110::-;;;;;;;;;;-1:-1:-1;1957:110:1;;;;;:::i;:::-;;:::i;3044:120::-;;;;;;;;;;-1:-1:-1;3044:120:1;;;;;:::i;:::-;;:::i;1140:38::-;;;;;;;;;;-1:-1:-1;1140:38:1;;;;;;;;732:31;;;;;;;;;;;;;;;;17282:162:2;;;;;;;;;;-1:-1:-1;17282:162:2;;;;;:::i;:::-;-1:-1:-1;;;;;17402:25:2;;;17379:4;17402:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;17282:162;1217:32:1;;;;;;;;;;-1:-1:-1;1217:32:1;;;;;;;;;;;2885:112;;;;;;;;;;-1:-1:-1;2885:112:1;;;;;:::i;:::-;;:::i;1579:142::-;;;;;;;;;;-1:-1:-1;1579:142:1;;;;;:::i;:::-;;:::i;1987:240:9:-;;;;;;;;;;-1:-1:-1;1987:240:9;;;;;:::i;:::-;;:::i;2735:96:1:-;;;;;;;;;;-1:-1:-1;2735:96:1;;;;;:::i;:::-;;:::i;7308:754::-;;;;;;;;;;-1:-1:-1;7308:754:1;;;;;:::i;:::-;;:::i;9155:630:2:-;9240:4;-1:-1:-1;;;;;;;;;9558:25:2;;;;:101;;-1:-1:-1;;;;;;;;;;9634:25:2;;;9558:101;:177;;;-1:-1:-1;;;;;;;;;;9710:25:2;;;9558:177;9539:196;9155:630;-1:-1:-1;;9155:630:2:o;9041:433:1:-;9113:16;9141:15;9159:13;:11;:13::i;:::-;9141:31;-1:-1:-1;9141:31:1;9187:19;:7;9199:6;9187:11;:19::i;:::-;:32;9183:95;;;9248:19;:7;9260:6;9248:11;:19::i;:::-;9235:32;;9183:95;9288:23;9328:10;-1:-1:-1;;;;;9314:25:1;;;;;-1:-1:-1;;;9314:25:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9314:25:1;-1:-1:-1;9288:51:1;-1:-1:-1;9363:7:1;9349:95;9376:10;9372:1;:14;9349:95;;;9419:14;9427:5;:1;9431;9427:5;:::i;9419:14::-;9407:6;9414:1;9407:9;;;;;;-1:-1:-1;;;9407:9:1;;;;;;;;;-1:-1:-1;;;;;9407:26:1;;;:9;;;;;;;;;;;:26;9388:3;;;;:::i;:::-;;;;9349:95;;;-1:-1:-1;9461:6:1;9041:433;-1:-1:-1;;;;9041:433:1:o;10039:98:2:-;10093:13;10125:5;10118:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10039:98;:::o;16360:214::-;16436:7;16460:16;16468:7;16460;:16::i;:::-;16455:64;;16485:34;;-1:-1:-1;;;16485:34:2;;;;;;;;;;;16455:64;-1:-1:-1;16537:24:2;;;;:15;:24;;;;;:30;-1:-1:-1;;;;;16537:30:2;;16360:214::o;15812:398::-;15900:13;15916:16;15924:7;15916;:16::i;:::-;15900:32;-1:-1:-1;39523:10:2;-1:-1:-1;;;;;15947:28:2;;;15943:172;;15994:44;16011:5;39523:10;17282:162;:::i;15994:44::-;15989:126;;16065:35;;-1:-1:-1;;;16065:35:2;;;;;;;;;;;15989:126;16125:24;;;;:15;:24;;;;;;:35;;-1:-1:-1;;;;;;16125:35:2;-1:-1:-1;;;;;16125:35:2;;;;;;;;;16175:28;;16125:24;;16175:28;;;;;;;15812:398;;;:::o;4667:358:1:-;1133:6:9;;-1:-1:-1;;;;;1133:6:9;39523:10:2;1273:23:9;1265:68;;;;-1:-1:-1;;;1265:68:9;;;;;;;:::i;:::-;;;;;;;;;4812:9:1::1;::::0;4783:14;;4765:43:::1;::::0;4783:24:::1;::::0;4802:4;4783:18:::1;:24::i;:::-;4765:13;:11;:13::i;:::-;:17:::0;::::1;:43::i;:::-;:56;;4757:101;;;::::0;-1:-1:-1;;;4757:101:1;;17755:2:12;4757:101:1::1;::::0;::::1;17737:21:12::0;;;17774:18;;;17767:30;17833:34;17813:18;;;17806:62;17885:18;;4757:101:1::1;17727:182:12::0;4757:101:1::1;4882:6;4877:142;4898:7;:14;4894:1;:18;4877:142;;;4933:27;4943:7;4951:1;4943:10;;;;;;-1:-1:-1::0;;;4943:10:1::1;;;;;;;;;;;;;;;4955:4;4933:9;:27::i;:::-;4979:29;4991:7;4999:1;4991:10;;;;;;-1:-1:-1::0;;;4991:10:1::1;;;;;;;;;;;;;;;5003:4;4979:29;;;;;;-1:-1:-1::0;;;;;11512:32:12;;;;11494:51;;11576:2;11561:18;;11554:34;11482:2;11467:18;;11449:145;4979:29:1::1;;;;;;;;4914:3:::0;::::1;::::0;::::1;:::i;:::-;;;;4877:142;;;;4667:358:::0;;:::o;582:29::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1785:120::-;1133:6:9;;-1:-1:-1;;;;;1133:6:9;39523:10:2;1273:23:9;1265:68;;;;-1:-1:-1;;;1265:68:9;;;;;;;:::i;:::-;1870:28:1;;::::1;::::0;:10:::1;::::0;:28:::1;::::0;::::1;::::0;::::1;:::i;:::-;;1785:120:::0;:::o;2422:86::-;1133:6:9;;-1:-1:-1;;;;;1133:6:9;39523:10:2;1273:23:9;1265:68;;;;-1:-1:-1;;;1265:68:9;;;;;;;:::i;:::-;2485:9:1::1;:16:::0;2422:86::o;5894:317:2:-;4353:1:1;6164:12:2;5955:7;6148:13;:28;-1:-1:-1;;6148:46:2;;5894:317::o;2577:110:1:-;1133:6:9;;-1:-1:-1;;;;;1133:6:9;39523:10:2;1273:23:9;1265:68;;;;-1:-1:-1;;;1265:68:9;;;;;;;:::i;:::-;2652:21:1::1;:28:::0;2577:110::o;19903:2764:2:-;20040:27;20070;20089:7;20070:18;:27::i;:::-;20040:57;;20153:4;-1:-1:-1;;;;;20112:45:2;20128:19;-1:-1:-1;;;;;20112:45:2;;20108:86;;20166:28;;-1:-1:-1;;;20166:28:2;;;;;;;;;;;20108:86;20206:27;19036:24;;;:15;:24;;;;;19260:26;;39523:10;18673:30;;;-1:-1:-1;;;;;18370:28:2;;18651:20;;;18648:56;20389:179;;20481:43;20498:4;39523:10;17282:162;:::i;20481:43::-;20476:92;;20533:35;;-1:-1:-1;;;20533:35:2;;;;;;;;;;;20476:92;-1:-1:-1;;;;;20583:16:2;;20579:52;;20608:23;;-1:-1:-1;;;20608:23:2;;;;;;;;;;;20579:52;20774:15;20771:2;;;20912:1;20891:19;20884:30;20771:2;-1:-1:-1;;;;;21300:24:2;;;;;;;:18;:24;;;;;;21298:26;;-1:-1:-1;;21298:26:2;;;21368:22;;;;;;;;;21366:24;;-1:-1:-1;21366:24:2;;;14703:11;14678:23;14674:41;14661:63;-1:-1:-1;;;14661:63:2;21654:26;;;;:17;:26;;;;;:172;-1:-1:-1;;;21943:47:2;;21939:617;;22047:1;22037:11;;22015:19;22168:30;;;:17;:30;;;;;;22164:378;;22304:13;;22289:11;:28;22285:239;;22449:30;;;;:17;:30;;;;;:52;;;22285:239;21939:617;;22600:7;22596:2;-1:-1:-1;;;;;22581:27:2;22590:4;-1:-1:-1;;;;;22581:27:2;;;;;;;;;;;19903:2764;;;;;;:::o;8132:575:1:-;8227:19;;8200:7;;8227:19;;8219:71;;;;-1:-1:-1;;;8219:71:1;;;;;;;:::i;:::-;8388:16;;:34;;-1:-1:-1;;;8388:34:1;;-1:-1:-1;;;;;10775:32:12;;;8388:34:1;;;10757:51:12;8301:18:1;;;;;;8388:16;;;;:26;;10730:18:12;;8388:34:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8365:57;;8437:6;8433:241;8453:12;8449:1;:16;8433:241;;;8503:16;;:47;;-1:-1:-1;;;8503:47:1;;-1:-1:-1;;;;;11512:32:12;;;8503:47:1;;;11494:51:12;11561:18;;;11554:34;;;8503:16:1;;;;:36;;11467:18:12;;8503:47:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8569:30;;;;:14;:30;;;;;;8486:64;;-1:-1:-1;8569:30:1;;8564:100;;8632:17;:10;8647:1;8632:14;:17::i;:::-;8619:30;;8564:100;8467:3;;;;:::i;:::-;;;;8433:241;;;-1:-1:-1;8690:10:1;;8132:575;-1:-1:-1;;;;8132:575:1:o;4119:137::-;1133:6:9;;-1:-1:-1;;;;;1133:6:9;39523:10:2;1273:23:9;1265:68;;;;-1:-1:-1;;;1265:68:9;;;;;;;:::i;:::-;4212:37:1::1;::::0;4181:21:::1;::::0;4220:10:::1;::::0;4212:37;::::1;;;::::0;4181:21;;4166:12:::1;4212:37:::0;4166:12;4212:37;4181:21;4220:10;4212:37;::::1;;;;;;;;;;;;;::::0;::::1;;;;22758:187:2::0;22899:39;22916:4;22922:2;22926:7;22899:39;;;;;;;;;;;;:16;:39::i;3284:94:1:-;1133:6:9;;-1:-1:-1;;;;;1133:6:9;39523:10:2;1273:23:9;1265:68;;;;-1:-1:-1;;;1265:68:9;;;;;;;:::i;:::-;3354:17:1;;::::1;::::0;:7:::1;::::0;:17:::1;::::0;::::1;::::0;::::1;:::i;1640:513:3:-:0;1779:23;1867:8;1842:22;1867:8;-1:-1:-1;;;;;1933:36:3;;;;;-1:-1:-1;;;1933:36:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1933:36:3;;-1:-1:-1;;1933:36:3;;;;;;;;;;;;1896:73;;1988:9;1983:123;2004:14;1999:1;:19;1983:123;;2059:32;2079:8;;2088:1;2079:11;;;;;-1:-1:-1;;;2079:11:3;;;;;;;;;;;;;;;2059:19;:32::i;:::-;2043:10;2054:1;2043:13;;;;;;-1:-1:-1;;;2043:13:3;;;;;;;;;;;;;;;;;;:48;2020:3;;1983:123;;11391:150:2;11463:7;11505:27;11524:7;11505:18;:27::i;7045:230::-;7117:7;-1:-1:-1;;;;;7140:19:2;;7136:60;;7168:28;;-1:-1:-1;;;7168:28:2;;;;;;;;;;;7136:60;-1:-1:-1;;;;;;7213:25:2;;;;;:18;:25;;;;;;-1:-1:-1;;;;;7213:55:2;;7045:230::o;2280:90:1:-;1133:6:9;;-1:-1:-1;;;;;1133:6:9;39523:10:2;1273:23:9;1265:68;;;;-1:-1:-1;;;1265:68:9;;;;;;;:::i;:::-;2345:11:1::1;:18:::0;2280:90::o;1693:145:9:-;1133:6;;-1:-1:-1;;;;;1133:6:9;39523:10:2;1273:23:9;1265:68;;;;-1:-1:-1;;;1265:68:9;;;;;;;:::i;:::-;1783:6:::1;::::0;1762:40:::1;::::0;1799:1:::1;::::0;-1:-1:-1;;;;;1783:6:9::1;::::0;1762:40:::1;::::0;1799:1;;1762:40:::1;1812:6;:19:::0;;-1:-1:-1;;;;;;1812:19:9::1;::::0;;1693:145::o;8772:224:1:-;8843:4;8885:1;8867:15;:19;:51;;;;;8909:9;;8890:15;:28;;8867:51;8859:80;;;;-1:-1:-1;;;8859:80:1;;17056:2:12;8859:80:1;;;17038:21:12;17095:2;17075:18;;;17068:30;-1:-1:-1;;;17114:18:12;;;17107:46;17170:18;;8859:80:1;17028:166:12;8859:80:1;-1:-1:-1;8958:31:1;;;;:14;:31;;;;;;;;8957:32;;8772:224::o;5416:879:3:-;5494:16;5546:19;5579:25;5618:22;5643:16;5653:5;5643:9;:16::i;:::-;5618:41;;5673:25;5715:14;-1:-1:-1;;;;;5701:29:3;;;;;-1:-1:-1;;;5701:29:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5701:29:3;;5673:57;;5744:31;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5744:31:3;4353:1:1;5789:461:3;5838:14;5823:11;:29;5789:461;;5889:15;5902:1;5889:12;:15::i;:::-;5877:27;;5926:9;:16;;;5922:71;;;5966:8;;5922:71;6014:14;;-1:-1:-1;;;;;6014:28:3;;6010:109;;6086:14;;;-1:-1:-1;6010:109:3;6161:5;-1:-1:-1;;;;;6140:26:3;:17;-1:-1:-1;;;;;6140:26:3;;6136:100;;;6216:1;6190:8;6199:13;;;;;;6190:23;;;;;;-1:-1:-1;;;6190:23:3;;;;;;;;;;;;;;:27;;;;;6136:100;5854:3;;5789:461;;;-1:-1:-1;6270:8:3;;5416:879;-1:-1:-1;;;;;;5416:879:3:o;10208:102:2:-;10264:13;10296:7;10289:14;;;;;:::i;2527:2454:3:-;2666:16;2731:4;2722:5;:13;2718:45;;2744:19;;-1:-1:-1;;;2744:19:3;;;;;;;;;;;2718:45;2777:19;2810:17;2830:14;5645:7:2;5671:13;;5590:101;2830:14:3;2810:34;-1:-1:-1;4353:1:1;2920:5:3;:23;2916:85;;;4353:1:1;2963:23:3;;2916:85;3075:9;3068:4;:16;3064:71;;;3111:9;3104:16;;3064:71;3148:25;3176:16;3186:5;3176:9;:16::i;:::-;3148:44;;3367:4;3359:5;:12;3355:271;;;3413:12;;;3447:31;;;3443:109;;;3522:11;3502:31;;3443:109;3355:271;;;;-1:-1:-1;3610:1:3;3355:271;3639:25;3681:17;-1:-1:-1;;;;;3667:32:3;;;;;-1:-1:-1;;;3667:32:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3667:32:3;-1:-1:-1;3639:60:3;-1:-1:-1;3717:22:3;3713:76;;3766:8;-1:-1:-1;3759:15:3;;-1:-1:-1;;;3759:15:3;3713:76;3930:31;3964:26;3984:5;3964:19;:26::i;:::-;3930:60;;4004:25;4246:9;:16;;;4241:90;;-1:-1:-1;4302:14:3;;4241:90;4361:5;4344:467;4373:4;4368:1;:9;;:45;;;;;4396:17;4381:11;:32;;4368:45;4344:467;;;4450:15;4463:1;4450:12;:15::i;:::-;4438:27;;4487:9;:16;;;4483:71;;;4527:8;;4483:71;4575:14;;-1:-1:-1;;;;;4575:28:3;;4571:109;;4647:14;;;-1:-1:-1;4571:109:3;4722:5;-1:-1:-1;;;;;4701:26:3;:17;-1:-1:-1;;;;;4701:26:3;;4697:100;;;4777:1;4751:8;4760:13;;;;;;4751:23;;;;;;-1:-1:-1;;;4751:23:3;;;;;;;;;;;;;;:27;;;;;4697:100;4415:3;;4344:467;;;-1:-1:-1;;;4893:29:3;;;-1:-1:-1;4900:8:3;;-1:-1:-1;;2527:2454:3;;;;;;:::o;5064:449:1:-;5122:12;;;;;;;5114:56;;;;-1:-1:-1;;;5114:56:1;;16294:2:12;5114:56:1;;;16276:21:12;16333:2;16313:18;;;16306:30;16372:33;16352:18;;;16345:61;16423:18;;5114:56:1;16266:181:12;5114:56:1;5196:11;;5188:4;:19;;5180:65;;;;-1:-1:-1;;;5180:65:1;;16654:2:12;5180:65:1;;;16636:21:12;16693:2;16673:18;;;16666:30;16732:34;16712:18;;;16705:62;-1:-1:-1;;;16783:18:12;;;16776:31;16824:19;;5180:65:1;16626:223:12;5180:65:1;5290:9;;5263:23;5281:4;5263:13;:11;:13::i;:23::-;:36;;5255:81;;;;-1:-1:-1;;;5255:81:1;;17755:2:12;5255:81:1;;;17737:21:12;;;17774:18;;;17767:30;17833:34;17813:18;;;17806:62;17885:18;;5255:81:1;17727:182:12;5255:81:1;5354:9;;5377;;5354:19;;5368:4;5354:13;:19::i;:::-;:32;;5346:70;;;;-1:-1:-1;;;5346:70:1;;17401:2:12;5346:70:1;;;17383:21:12;17440:2;17420:18;;;17413:30;17479:27;17459:18;;;17452:55;17524:18;;5346:70:1;17373:175:12;5346:70:1;5435:27;5445:10;5457:4;5435:9;:27::i;:::-;5477:29;;;5489:10;11494:51:12;;11576:2;11561:18;;11554:34;;;5477:29:1;;11467:18:12;5477:29:1;;;;;;;;5064:449;:::o;16901:231:2:-;39523:10;16995:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;16995:49:2;;;;;;;;;;;;:60;;-1:-1:-1;;16995:60:2;;;;;;;;;;17070:55;;14056:41:12;;;16995:49:2;;39523:10;17070:55;;14029:18:12;17070:55:2;;;;;;;16901:231;;:::o;5560:997:1:-;5640:19;;;;5632:71;;;;-1:-1:-1;;;5632:71:1;;;;;;;:::i;:::-;5743:15;5721:18;;:37;;5713:79;;;;-1:-1:-1;;;5713:79:1;;15936:2:12;5713:79:1;;;15918:21:12;15975:2;15955:18;;;15948:30;16014:31;15994:18;;;15987:59;16063:18;;5713:79:1;15908:179:12;5713:79:1;5830:21;;5810:9;:16;:41;;5802:119;;;;-1:-1:-1;;;5802:119:1;;21134:2:12;5802:119:1;;;21116:21:12;21173:2;21153:18;;;21146:30;21212:34;21192:18;;;21185:62;21283:34;21263:18;;;21256:62;-1:-1:-1;;;21334:19:12;;;21327:32;21376:19;;5802:119:1;21106:295:12;5802:119:1;5955:16;;5932:20;;6014:270;6034:12;6030:1;:16;6014:270;;;6071:16;;6096:12;;6113:10;;-1:-1:-1;;;;;6071:16:1;;:24;;6096:9;;6106:1;;6096:12;;;;-1:-1:-1;;;6096:12:1;;;;;;;;;;;;;;;6071:38;;;;;;;;;;;;;21825:25:12;;21813:2;21798:18;;21780:76;6071:38:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;6071:52:1;;:85;;;;;6128:14;:28;6143:9;6153:1;6143:12;;;;;;-1:-1:-1;;;6143:12:1;;;;;;;;;;;;;;;;;;;;6128:28;;;;;;;;;;-1:-1:-1;6128:28:1;;;;6127:29;6071:85;6067:207;;;6207:4;6176:14;:28;6191:9;6201:1;6191:12;;;;;;-1:-1:-1;;;6191:12:1;;;;;;;;;;;;;;;;;;;;6176:28;;;;;;;;;;-1:-1:-1;6176:28:1;:35;;-1:-1:-1;;6176:35:1;;;;;;;;;;6242:17;:10;-1:-1:-1;6242:14:1;:17::i;:::-;6229:30;;6067:207;6048:3;;;;:::i;:::-;;;;6014:270;;;;6315:1;6302:10;:14;6294:58;;;;-1:-1:-1;;;6294:58:1;;19593:2:12;6294:58:1;;;19575:21:12;19632:2;19612:18;;;19605:30;19671:33;19651:18;;;19644:61;19722:18;;6294:58:1;19565:181:12;6294:58:1;6403:9;;6370:29;6388:10;6370:13;:11;:13::i;:29::-;:42;;6362:91;;;;-1:-1:-1;;;6362:91:1;;;;;;;:::i;:::-;6464:33;6474:10;6486;6464:9;:33::i;:::-;6513:37;;;6527:10;11494:51:12;;11576:2;11561:18;;11554:34;;;6513:37:1;;11467:18:12;6513:37:1;;;;;;;5560:997;;;:::o;6609:623::-;6682:19;;;;6674:59;;;;-1:-1:-1;;;6674:59:1;;14768:2:12;6674:59:1;;;14750:21:12;14807:2;14787:18;;;14780:30;14846:29;14826:18;;;14819:57;14893:18;;6674:59:1;14740:177:12;6674:59:1;6773:15;6751:18;;:37;;6743:78;;;;-1:-1:-1;;;6743:78:1;;20777:2:12;6743:78:1;;;20759:21:12;20816:2;20796:18;;;20789:30;20855;20835:18;;;20828:58;20903:18;;6743:78:1;20749:178:12;6743:78:1;6841:31;;;;:14;:31;;;;;;;;6840:32;6832:69;;;;-1:-1:-1;;;6832:69:1;;18116:2:12;6832:69:1;;;18098:21:12;18155:2;18135:18;;;18128:30;18194:26;18174:18;;;18167:54;18238:18;;6832:69:1;18088:174:12;6832:69:1;6919:16;;:41;;-1:-1:-1;;;6919:41:1;;;;;21825:25:12;;;6964:10:1;;-1:-1:-1;;;;;6919:16:1;;:24;;21798:18:12;;6919:41:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;6919:55:1;;6911:95;;;;-1:-1:-1;;;6911:95:1;;18469:2:12;6911:95:1;;;18451:21:12;18508:2;18488:18;;;18481:30;18547:29;18527:18;;;18520:57;18594:18;;6911:95:1;18441:177:12;6911:95:1;7048:9;;7024:20;7042:1;7024:13;:11;:13::i;:20::-;:33;;7016:82;;;;-1:-1:-1;;;7016:82:1;;;;;;;:::i;:::-;7109:31;;;;:14;:31;;;;;:38;;-1:-1:-1;;7109:38:1;7143:4;7109:38;;;;;;7157:24;;7167:10;;7157:9;:24::i;:::-;7197:28;;;7211:10;11494:51:12;;7223:1:1;11576:2:12;11561:18;;11554:34;7197:28:1;;11467:18:12;7197:28:1;11449:145:12;23526:396:2;23695:31;23708:4;23714:2;23718:7;23695:12;:31::i;:::-;-1:-1:-1;;;;;23740:14:2;;;:19;23736:180;;23778:56;23809:4;23815:2;23819:7;23828:5;23778:30;:56::i;:::-;23773:143;;23861:40;;-1:-1:-1;;;23861:40:2;;;;;;;;;;;23773:143;23526:396;;;;:::o;1069:418:3:-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4353:1:1;1231:7:3;:25;:54;;;-1:-1:-1;5645:7:2;5671:13;1260:7:3;:25;;1231:54;1227:101;;;1308:9;1069:418;-1:-1:-1;;1069:418:3:o;1227:101::-;1349:21;1362:7;1349:12;:21::i;:::-;1337:33;;1384:9;:16;;;1380:63;;;1423:9;1069:418;-1:-1:-1;;1069:418:3:o;1380:63::-;1459:21;1472:7;1459:12;:21::i;2139:96:1:-;1133:6:9;;-1:-1:-1;;;;;1133:6:9;39523:10:2;1273:23:9;1265:68;;;;-1:-1:-1;;;1265:68:9;;;;;;;:::i;:::-;2204:12:1::1;:24:::0;;;::::1;;;;-1:-1:-1::0;;2204:24:1;;::::1;::::0;;;::::1;::::0;;2139:96::o;1301:37::-;;;;;;;:::i;3689:392::-;3763:13;3796:17;3804:8;3796:7;:17::i;:::-;3788:77;;;;-1:-1:-1;;;3788:77:1;;19953:2:12;3788:77:1;;;19935:21:12;19992:2;19972:18;;;19965:30;20031:34;20011:18;;;20004:62;-1:-1:-1;;;20082:18:12;;;20075:45;20137:19;;3788:77:1;19925:237:12;3788:77:1;3876:28;3907:10;:8;:10::i;:::-;3876:41;;3965:1;3940:14;3934:28;:32;:140;;;;;;;;;;;;;;;;;4005:14;4021:19;:8;:17;:19::i;:::-;4042:13;3988:68;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;3927:147;3689:392;-1:-1:-1;;;3689:392:1:o;4405:211::-;1133:6:9;;-1:-1:-1;;;;;1133:6:9;39523:10:2;1273:23:9;1265:68;;;;-1:-1:-1;;;1265:68:9;;;;;;;:::i;:::-;4513:9:1::1;;4480:29;4498:10;4480:13;:11;:13::i;:29::-;:42;;4472:93;;;::::0;-1:-1:-1;;;4472:93:1;;18825:2:12;4472:93:1::1;::::0;::::1;18807:21:12::0;18864:2;18844:18;;;18837:30;18903:34;18883:18;;;18876:62;-1:-1:-1;;;18954:18:12;;;18947:36;19000:19;;4472:93:1::1;18797:228:12::0;4472:93:1::1;4576:33;4586:10;4598;4576:9;:33::i;:::-;4405:211:::0;:::o;1957:110::-;1133:6:9;;-1:-1:-1;;;;;1133:6:9;39523:10:2;1273:23:9;1265:68;;;;-1:-1:-1;;;1265:68:9;;;;;;;:::i;:::-;2029:19:1::1;:31:::0;;-1:-1:-1;;2029:31:1::1;::::0;::::1;;::::0;;;::::1;::::0;;1957:110::o;3044:120::-;1133:6:9;;-1:-1:-1;;;;;1133:6:9;39523:10:2;1273:23:9;1265:68;;;;-1:-1:-1;;;1265:68:9;;;;;;;:::i;:::-;3127:30:1;;::::1;::::0;:13:::1;::::0;:30:::1;::::0;::::1;::::0;::::1;:::i;2885:112::-:0;1133:6:9;;-1:-1:-1;;;;;1133:6:9;39523:10:2;1273:23:9;1265:68;;;;-1:-1:-1;;;1265:68:9;;;;;;;:::i;:::-;2961:18:1::1;:29:::0;2885:112::o;1579:142::-;1133:6:9;;-1:-1:-1;;;;;1133:6:9;39523:10:2;1273:23:9;1265:68;;;;-1:-1:-1;;;1265:68:9;;;;;;;:::i;:::-;1660:16:1::1;:54:::0;;-1:-1:-1;;;;;;1660:54:1::1;-1:-1:-1::0;;;;;1660:54:1;;;::::1;::::0;;;::::1;::::0;;1579:142::o;1987:240:9:-;1133:6;;-1:-1:-1;;;;;1133:6:9;39523:10:2;1273:23:9;1265:68;;;;-1:-1:-1;;;1265:68:9;;;;;;;:::i;:::-;-1:-1:-1;;;;;2075:22:9;::::1;2067:73;;;::::0;-1:-1:-1;;;2067:73:9;;15529:2:12;2067:73:9::1;::::0;::::1;15511:21:12::0;15568:2;15548:18;;;15541:30;15607:34;15587:18;;;15580:62;-1:-1:-1;;;15658:18:12;;;15651:36;15704:19;;2067:73:9::1;15501:228:12::0;2067:73:9::1;2176:6;::::0;2155:38:::1;::::0;-1:-1:-1;;;;;2155:38:9;;::::1;::::0;2176:6:::1;::::0;2155:38:::1;::::0;2176:6:::1;::::0;2155:38:::1;2203:6;:17:::0;;-1:-1:-1;;;;;;2203:17:9::1;-1:-1:-1::0;;;;;2203:17:9;;;::::1;::::0;;;::::1;::::0;;1987:240::o;2735:96:1:-;1133:6:9;;-1:-1:-1;;;;;1133:6:9;39523:10:2;1273:23:9;1265:68;;;;-1:-1:-1;;;1265:68:9;;;;;;;:::i;:::-;2803:9:1::1;:21:::0;2735:96::o;7308:754::-;7407:19;;7371:16;;7407:19;;7399:71;;;;-1:-1:-1;;;7399:71:1;;;;;;;:::i;:::-;7510:15;7488:18;;:37;;7480:79;;;;-1:-1:-1;;;7480:79:1;;15936:2:12;7480:79:1;;;15918:21:12;15975:2;15955:18;;;15948:30;16014:31;15994:18;;;15987:59;16063:18;;7480:79:1;15908:179:12;7480:79:1;7622:16;;:34;;-1:-1:-1;;;7622:34:1;;-1:-1:-1;;;;;10775:32:12;;;7622:34:1;;;10757:51:12;7570:22:1;;;;7622:16;;;:26;;10730:18:12;;7622:34:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7602:54;;7666:25;7708:12;-1:-1:-1;;;;;7694:27:1;;;;;-1:-1:-1;;;7694:27:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7694:27:1;;7666:55;;7744:6;7740:290;7760:12;7756:1;:16;7740:290;;;7809:16;;:47;;-1:-1:-1;;;7809:47:1;;-1:-1:-1;;;;;11512:32:12;;;7809:47:1;;;11494:51:12;11561:18;;;11554:34;;;7809:16:1;;;;:36;;11467:18:12;;7809:47:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7875:30;;;;:14;:30;;;;;;7792:64;;-1:-1:-1;7875:30:1;;7870:150;;7939:14;7925:8;7934:1;7925:11;;;;;;-1:-1:-1;;;7925:11:1;;;;;;;;;;;;;;:28;;;;;7870:150;;;8004:1;7990:8;7999:1;7990:11;;;;;;-1:-1:-1;;;7990:11:1;;;;;;;;;;;;;;:15;;;;;7870:150;7774:3;;;;:::i;:::-;;;;7740:290;;2672:96:10;2730:7;2756:5;2760:1;2756;:5;:::i;17693:277:2:-;17758:4;17812:7;4353:1:1;17793:26:2;;:65;;;;;17845:13;;17835:7;:23;17793:65;:151;;;;-1:-1:-1;;17895:26:2;;;;:17;:26;;;;;;-1:-1:-1;;;17895:44:2;:49;;17693:277::o;3382:96:10:-;3440:7;3466:5;3470:1;3466;:5;:::i;33423:110:2:-;33499:27;33509:2;33513:8;33499:27;;;;;;;;;;;;:9;:27::i;12515:1249::-;12582:7;12616;;4353:1:1;12662:23:2;12658:1042;;12714:13;;12707:4;:20;12703:997;;;12751:14;12768:23;;;:17;:23;;;;;;-1:-1:-1;;;12855:24:2;;12851:831;;13510:111;13517:11;13510:111;;-1:-1:-1;;;13587:6:2;13569:25;;;;:17;:25;;;;;;13510:111;;12851:831;12703:997;;13726:31;;-1:-1:-1;;;13726:31:2;;;;;;;;;;;11979:159;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12106:24:2;;;;:17;:24;;;;;;12087:44;;:18;:44::i;25948:697::-;26126:88;;-1:-1:-1;;;26126:88:2;;26106:4;;-1:-1:-1;;;;;26126:45:2;;;;;:88;;39523:10;;26193:4;;26199:7;;26208:5;;26126:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26126:88:2;;;;;;;;-1:-1:-1;;26126:88:2;;;;;;;;;;;;:::i;:::-;;;26122:517;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26404:13:2;;26400:229;;26449:40;;-1:-1:-1;;;26449:40:2;;;;;;;;;;;26400:229;26589:6;26583:13;26574:6;26570:2;26566:15;26559:38;26122:517;-1:-1:-1;;;;;;26282:64:2;-1:-1:-1;;;26282:64:2;;-1:-1:-1;26122:517:2;25948:697;;;;;;:::o;11724:164::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11834:47:2;11853:27;11872:7;11853:18;:27::i;:::-;11834:18;:47::i;3509:105:1:-;3568:13;3600:7;3593:14;;;;;:::i;271:703:11:-;327:13;544:10;540:51;;-1:-1:-1;;570:10:11;;;;;;;;;;;;-1:-1:-1;;;570:10:11;;;;;271:703::o;540:51::-;615:5;600:12;654:75;661:9;;654:75;;686:8;;;;:::i;:::-;;-1:-1:-1;708:10:11;;-1:-1:-1;716:2:11;708:10;;:::i;:::-;;;654:75;;;738:19;770:6;-1:-1:-1;;;;;760:17:11;;;;;-1:-1:-1;;;760:17:11;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;760:17:11;;738:39;;787:150;794:10;;787:150;;820:11;830:1;820:11;;:::i;:::-;;-1:-1:-1;888:10:11;896:2;888:5;:10;:::i;:::-;875:24;;:2;:24;:::i;:::-;862:39;;845:6;852;845:14;;;;;;-1:-1:-1;;;845:14:11;;;;;;;;;;;;:56;-1:-1:-1;;;;;845:56:11;;;;;;;;-1:-1:-1;915:11:11;924:2;915:11;;:::i;:::-;;;787:150;;32675:669:2;32801:19;32807:2;32811:8;32801:5;:19::i;:::-;-1:-1:-1;;;;;32859:14:2;;;:19;32855:473;;32898:11;32912:13;32959:14;;;32991:229;33021:62;33060:1;33064:2;33068:7;;;;;;33077:5;33021:30;:62::i;:::-;33016:165;;33118:40;;-1:-1:-1;;;33118:40:2;;;;;;;;;;;33016:165;33215:3;33207:5;:11;32991:229;;33300:3;33283:13;;:20;33279:34;;33305:8;;;33279:34;32855:473;;32675:669;;;:::o;13858:361::-;-1:-1:-1;;;;;;;;;;;;;13967:41:2;;;;2004:3;14052:33;;;-1:-1:-1;;;;;14018:68:2;-1:-1:-1;;;14018:68:2;-1:-1:-1;;;14115:24:2;;:29;;-1:-1:-1;;;14096:48:2;;;;2513:3;14183:28;;;;-1:-1:-1;;;14154:58:2;-1:-1:-1;13858:361:2:o;27091:2902::-;27163:20;27186:13;27213;27209:44;;27235:18;;-1:-1:-1;;;27235:18:2;;;;;;;;;;;27209:44;-1:-1:-1;;;;;27728:22:2;;;;;;:18;:22;;;;1495:2;27728:22;;;:71;;27766:32;27754:45;;27728:71;;;28035:31;;;:17;:31;;;;;-1:-1:-1;15123:15:2;;15097:24;15093:46;14703:11;14678:23;14674:41;14671:52;14661:63;;28035:170;;28264:23;;;;28035:31;;27728:22;;29016:25;27728:22;;28872:328;29520:1;29506:12;29502:20;29461:339;29560:3;29551:7;29548:16;29461:339;;29774:7;29764:8;29761:1;29734:25;29731:1;29728;29723:59;29612:1;29599:15;29461:339;;;-1:-1:-1;29831:13:2;29827:45;;29853:19;;-1:-1:-1;;;29853:19:2;;;;;;;;;;;29827:45;29887:13;:19;-1:-1:-1;4877:142:1::1;4667:358:::0;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:406:12;78:5;-1:-1:-1;;;;;104:6:12;101:30;98:2;;;134:18;;:::i;:::-;172:57;217:2;196:15;;-1:-1:-1;;192:29:12;223:4;188:40;172:57;:::i;:::-;163:66;;252:6;245:5;238:21;292:3;283:6;278:3;274:16;271:25;268:2;;;309:1;306;299:12;268:2;358:6;353:3;346:4;339:5;335:16;322:43;412:1;405:4;396:6;389:5;385:18;381:29;374:40;88:332;;;;;:::o;425:160::-;490:20;;546:13;;539:21;529:32;;519:2;;575:1;572;565:12;519:2;471:114;;;:::o;590:257::-;649:6;702:2;690:9;681:7;677:23;673:32;670:2;;;723:6;715;708:22;670:2;767:9;754:23;786:31;811:5;786:31;:::i;852:261::-;922:6;975:2;963:9;954:7;950:23;946:32;943:2;;;996:6;988;981:22;943:2;1033:9;1027:16;1052:31;1077:5;1052:31;:::i;1118:398::-;1186:6;1194;1247:2;1235:9;1226:7;1222:23;1218:32;1215:2;;;1268:6;1260;1253:22;1215:2;1312:9;1299:23;1331:31;1356:5;1331:31;:::i;:::-;1381:5;-1:-1:-1;1438:2:12;1423:18;;1410:32;1451:33;1410:32;1451:33;:::i;:::-;1503:7;1493:17;;;1205:311;;;;;:::o;1521:466::-;1598:6;1606;1614;1667:2;1655:9;1646:7;1642:23;1638:32;1635:2;;;1688:6;1680;1673:22;1635:2;1732:9;1719:23;1751:31;1776:5;1751:31;:::i;:::-;1801:5;-1:-1:-1;1858:2:12;1843:18;;1830:32;1871:33;1830:32;1871:33;:::i;:::-;1625:362;;1923:7;;-1:-1:-1;;;1977:2:12;1962:18;;;;1949:32;;1625:362::o;1992:824::-;2087:6;2095;2103;2111;2164:3;2152:9;2143:7;2139:23;2135:33;2132:2;;;2186:6;2178;2171:22;2132:2;2230:9;2217:23;2249:31;2274:5;2249:31;:::i;:::-;2299:5;-1:-1:-1;2356:2:12;2341:18;;2328:32;2369:33;2328:32;2369:33;:::i;:::-;2421:7;-1:-1:-1;2475:2:12;2460:18;;2447:32;;-1:-1:-1;2530:2:12;2515:18;;2502:32;-1:-1:-1;;;;;2546:30:12;;2543:2;;;2594:6;2586;2579:22;2543:2;2622:22;;2675:4;2667:13;;2663:27;-1:-1:-1;2653:2:12;;2709:6;2701;2694:22;2653:2;2737:73;2802:7;2797:2;2784:16;2779:2;2775;2771:11;2737:73;:::i;:::-;2727:83;;;2122:694;;;;;;;:::o;2821:325::-;2886:6;2894;2947:2;2935:9;2926:7;2922:23;2918:32;2915:2;;;2968:6;2960;2953:22;2915:2;3012:9;2999:23;3031:31;3056:5;3031:31;:::i;:::-;3081:5;-1:-1:-1;3105:35:12;3136:2;3121:18;;3105:35;:::i;:::-;3095:45;;2905:241;;;;;:::o;3151:325::-;3219:6;3227;3280:2;3268:9;3259:7;3255:23;3251:32;3248:2;;;3301:6;3293;3286:22;3248:2;3345:9;3332:23;3364:31;3389:5;3364:31;:::i;:::-;3414:5;3466:2;3451:18;;;;3438:32;;-1:-1:-1;;;3238:238:12:o;3481:393::-;3558:6;3566;3574;3627:2;3615:9;3606:7;3602:23;3598:32;3595:2;;;3648:6;3640;3633:22;3595:2;3692:9;3679:23;3711:31;3736:5;3711:31;:::i;:::-;3761:5;3813:2;3798:18;;3785:32;;-1:-1:-1;3864:2:12;3849:18;;;3836:32;;3585:289;-1:-1:-1;;;3585:289:12:o;3879:1092::-;3972:6;3980;4033:2;4021:9;4012:7;4008:23;4004:32;4001:2;;;4054:6;4046;4039:22;4001:2;4099:9;4086:23;-1:-1:-1;;;;;4124:6:12;4121:30;4118:2;;;4169:6;4161;4154:22;4118:2;4197:22;;4250:4;4242:13;;4238:27;-1:-1:-1;4228:2:12;;4284:6;4276;4269:22;4228:2;4325;4312:16;4347:4;4371:60;4387:43;4427:2;4387:43;:::i;:::-;4371:60;:::i;:::-;4453:3;4477:2;4472:3;4465:15;4505:2;4500:3;4496:12;4489:19;;4536:2;4532;4528:11;4584:7;4579:2;4573;4570:1;4566:10;4562:2;4558:19;4554:28;4551:41;4548:2;;;4610:6;4602;4595:22;4548:2;4637:6;4628:15;;4652:238;4666:2;4663:1;4660:9;4652:238;;;4737:3;4724:17;4754:31;4779:5;4754:31;:::i;:::-;4798:18;;4684:1;4677:9;;;;;4836:12;;;;4868;;4652:238;;;-1:-1:-1;4909:5:12;4946:18;;;;4933:32;;-1:-1:-1;;;;;;3991:980:12:o;4976:665::-;5062:6;5070;5123:2;5111:9;5102:7;5098:23;5094:32;5091:2;;;5144:6;5136;5129:22;5091:2;5189:9;5176:23;-1:-1:-1;;;;;5259:2:12;5251:6;5248:14;5245:2;;;5280:6;5272;5265:22;5245:2;5323:6;5312:9;5308:22;5298:32;;5368:7;5361:4;5357:2;5353:13;5349:27;5339:2;;5395:6;5387;5380:22;5339:2;5440;5427:16;5466:2;5458:6;5455:14;5452:2;;;5487:6;5479;5472:22;5452:2;5545:7;5540:2;5530:6;5527:1;5523:14;5519:2;5515:23;5511:32;5508:45;5505:2;;;5571:6;5563;5556:22;5505:2;5607;5599:11;;;;;5629:6;;-1:-1:-1;5081:560:12;;-1:-1:-1;;;;5081:560:12:o;5646:947::-;5730:6;5761:2;5804;5792:9;5783:7;5779:23;5775:32;5772:2;;;5825:6;5817;5810:22;5772:2;5870:9;5857:23;-1:-1:-1;;;;;5895:6:12;5892:30;5889:2;;;5940:6;5932;5925:22;5889:2;5968:22;;6021:4;6013:13;;6009:27;-1:-1:-1;5999:2:12;;6055:6;6047;6040:22;5999:2;6096;6083:16;6119:60;6135:43;6175:2;6135:43;:::i;6119:60::-;6201:3;6225:2;6220:3;6213:15;6253:2;6248:3;6244:12;6237:19;;6284:2;6280;6276:11;6332:7;6327:2;6321;6318:1;6314:10;6310:2;6306:19;6302:28;6299:41;6296:2;;;6358:6;6350;6343:22;6296:2;6385:6;6376:15;;6400:163;6414:2;6411:1;6408:9;6400:163;;;6471:17;;6459:30;;6432:1;6425:9;;;;;6509:12;;;;6541;;6400:163;;;-1:-1:-1;6582:5:12;5741:852;-1:-1:-1;;;;;;;5741:852:12:o;6598:190::-;6654:6;6707:2;6695:9;6686:7;6682:23;6678:32;6675:2;;;6728:6;6720;6713:22;6675:2;6756:26;6772:9;6756:26;:::i;6793:255::-;6851:6;6904:2;6892:9;6883:7;6879:23;6875:32;6872:2;;;6925:6;6917;6910:22;6872:2;6969:9;6956:23;6988:30;7012:5;6988:30;:::i;7053:259::-;7122:6;7175:2;7163:9;7154:7;7150:23;7146:32;7143:2;;;7196:6;7188;7181:22;7143:2;7233:9;7227:16;7252:30;7276:5;7252:30;:::i;7317:480::-;7386:6;7439:2;7427:9;7418:7;7414:23;7410:32;7407:2;;;7460:6;7452;7445:22;7407:2;7505:9;7492:23;-1:-1:-1;;;;;7530:6:12;7527:30;7524:2;;;7575:6;7567;7560:22;7524:2;7603:22;;7656:4;7648:13;;7644:27;-1:-1:-1;7634:2:12;;7690:6;7682;7675:22;7634:2;7718:73;7783:7;7778:2;7765:16;7760:2;7756;7752:11;7718:73;:::i;7802:190::-;7861:6;7914:2;7902:9;7893:7;7889:23;7885:32;7882:2;;;7935:6;7927;7920:22;7882:2;-1:-1:-1;7963:23:12;;7872:120;-1:-1:-1;7872:120:12:o;7997:194::-;8067:6;8120:2;8108:9;8099:7;8095:23;8091:32;8088:2;;;8141:6;8133;8126:22;8088:2;-1:-1:-1;8169:16:12;;8078:113;-1:-1:-1;8078:113:12:o;8196:258::-;8264:6;8272;8325:2;8313:9;8304:7;8300:23;8296:32;8293:2;;;8346:6;8338;8331:22;8293:2;-1:-1:-1;;8374:23:12;;;8444:2;8429:18;;;8416:32;;-1:-1:-1;8283:171:12:o;8459:257::-;8500:3;8538:5;8532:12;8565:6;8560:3;8553:19;8581:63;8637:6;8630:4;8625:3;8621:14;8614:4;8607:5;8603:16;8581:63;:::i;:::-;8698:2;8677:15;-1:-1:-1;;8673:29:12;8664:39;;;;8705:4;8660:50;;8508:208;-1:-1:-1;;8508:208:12:o;8721:349::-;8805:12;;-1:-1:-1;;;;;8801:38:12;8789:51;;8893:4;8882:16;;;8876:23;-1:-1:-1;;;;;8872:48:12;8856:14;;;8849:72;8984:4;8973:16;;;8967:23;8960:31;8953:39;8937:14;;;8930:63;9046:4;9035:16;;;9029:23;9054:8;9025:38;9009:14;;9002:62;8779:291::o;9075:1531::-;9299:3;9337:6;9331:13;9363:4;9376:51;9420:6;9415:3;9410:2;9402:6;9398:15;9376:51;:::i;:::-;9490:13;;9449:16;;;;9512:55;9490:13;9449:16;9534:15;;;9512:55;:::i;:::-;9658:13;;9589:20;;;9629:3;;9718:1;9740:18;;;;9793;;;;9820:2;;9898:4;9888:8;9884:19;9872:31;;9820:2;9961;9951:8;9948:16;9928:18;9925:40;9922:2;;;-1:-1:-1;;;9988:33:12;;10044:4;10041:1;10034:15;10074:4;9995:3;10062:17;9922:2;10105:18;10132:110;;;;10256:1;10251:330;;;;10098:483;;10132:110;-1:-1:-1;;10167:24:12;;10153:39;;10212:20;;;;-1:-1:-1;10132:110:12;;10251:330;22376:4;22395:17;;;22445:4;22429:21;;10346:3;10362:169;10376:8;10373:1;10370:15;10362:169;;;10458:14;;10443:13;;;10436:37;10501:16;;;;10393:10;;10362:169;;;10366:3;;10562:8;10555:5;10551:20;10544:27;;10098:483;-1:-1:-1;10597:3:12;;9307:1299;-1:-1:-1;;;;;;;;;;;9307:1299:12:o;10819:488::-;-1:-1:-1;;;;;11088:15:12;;;11070:34;;11140:15;;11135:2;11120:18;;11113:43;11187:2;11172:18;;11165:34;;;11235:3;11230:2;11215:18;;11208:31;;;11013:4;;11256:45;;11281:19;;11273:6;11256:45;:::i;:::-;11248:53;11022:285;-1:-1:-1;;;;;;11022:285:12:o;11878:661::-;12049:2;12101:21;;;12171:13;;12074:18;;;12193:22;;;12020:4;;12049:2;12272:15;;;;12246:2;12231:18;;;12020:4;12318:195;12332:6;12329:1;12326:13;12318:195;;;12397:13;;-1:-1:-1;;;;;12393:39:12;12381:52;;12488:15;;;;12453:12;;;;12429:1;12347:9;12318:195;;12544:727;12779:2;12831:21;;;12901:13;;12804:18;;;12923:22;;;12750:4;;12779:2;13002:15;;;;12976:2;12961:18;;;12750:4;13048:197;13062:6;13059:1;13056:13;13048:197;;;13111:52;13159:3;13150:6;13144:13;13111:52;:::i;:::-;13220:15;;;;13192:4;13183:14;;;;;13084:1;13077:9;13048:197;;13276:635;13447:2;13499:21;;;13569:13;;13472:18;;;13591:22;;;13418:4;;13447:2;13670:15;;;;13644:2;13629:18;;;13418:4;13716:169;13730:6;13727:1;13724:13;13716:169;;;13791:13;;13779:26;;13860:15;;;;13825:12;;;;13752:1;13745:9;13716:169;;14342:219;14491:2;14480:9;14473:21;14454:4;14511:44;14551:2;14540:9;14536:18;14528:6;14511:44;:::i;14922:400::-;15124:2;15106:21;;;15163:2;15143:18;;;15136:30;15202:34;15197:2;15182:18;;15175:62;-1:-1:-1;;;15268:2:12;15253:18;;15246:34;15312:3;15297:19;;15096:226::o;19030:356::-;19232:2;19214:21;;;19251:18;;;19244:30;19310:34;19305:2;19290:18;;19283:62;19377:2;19362:18;;19204:182::o;20167:403::-;20369:2;20351:21;;;20408:2;20388:18;;;20381:30;20447:34;20442:2;20427:18;;20420:62;-1:-1:-1;;;20513:2:12;20498:18;;20491:37;20560:3;20545:19;;20341:229::o;21406:268::-;21604:3;21589:19;;21617:51;21593:9;21650:6;21617:51;:::i;21861:275::-;21932:2;21926:9;21997:2;21978:13;;-1:-1:-1;;21974:27:12;21962:40;;-1:-1:-1;;;;;22017:34:12;;22053:22;;;22014:62;22011:2;;;22079:18;;:::i;:::-;22115:2;22108:22;21906:230;;-1:-1:-1;21906:230:12:o;22141:183::-;22201:4;-1:-1:-1;;;;;22226:6:12;22223:30;22220:2;;;22256:18;;:::i;:::-;-1:-1:-1;22301:1:12;22297:14;22313:4;22293:25;;22210:114::o;22461:128::-;22501:3;22532:1;22528:6;22525:1;22522:13;22519:2;;;22538:18;;:::i;:::-;-1:-1:-1;22574:9:12;;22509:80::o;22594:120::-;22634:1;22660;22650:2;;22665:18;;:::i;:::-;-1:-1:-1;22699:9:12;;22640:74::o;22719:168::-;22759:7;22825:1;22821;22817:6;22813:14;22810:1;22807:21;22802:1;22795:9;22788:17;22784:45;22781:2;;;22832:18;;:::i;:::-;-1:-1:-1;22872:9:12;;22771:116::o;22892:125::-;22932:4;22960:1;22957;22954:8;22951:2;;;22965:18;;:::i;:::-;-1:-1:-1;23002:9:12;;22941:76::o;23022:258::-;23094:1;23104:113;23118:6;23115:1;23112:13;23104:113;;;23194:11;;;23188:18;23175:11;;;23168:39;23140:2;23133:10;23104:113;;;23235:6;23232:1;23229:13;23226:2;;;-1:-1:-1;;23270:1:12;23252:16;;23245:27;23075:205::o;23285:380::-;23364:1;23360:12;;;;23407;;;23428:2;;23482:4;23474:6;23470:17;23460:27;;23428:2;23535;23527:6;23524:14;23504:18;23501:38;23498:2;;;23581:10;23576:3;23572:20;23569:1;23562:31;23616:4;23613:1;23606:15;23644:4;23641:1;23634:15;23498:2;;23340:325;;;:::o;23670:135::-;23709:3;-1:-1:-1;;23730:17:12;;23727:2;;;23750:18;;:::i;:::-;-1:-1:-1;23797:1:12;23786:13;;23717:88::o;23810:112::-;23842:1;23868;23858:2;;23873:18;;:::i;:::-;-1:-1:-1;23907:9:12;;23848:74::o;23927:127::-;23988:10;23983:3;23979:20;23976:1;23969:31;24019:4;24016:1;24009:15;24043:4;24040:1;24033:15;24059:127;24120:10;24115:3;24111:20;24108:1;24101:31;24151:4;24148:1;24141:15;24175:4;24172:1;24165:15;24191:127;24252:10;24247:3;24243:20;24240:1;24233:31;24283:4;24280:1;24273:15;24307:4;24304:1;24297:15;24323:131;-1:-1:-1;;;;;24398:31:12;;24388:42;;24378:2;;24444:1;24441;24434:12;24459:131;-1:-1:-1;;;;;;24533:32:12;;24523:43;;24513:2;;24580:1;24577;24570:12

Swarm Source

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