ETH Price: $2,637.07 (-1.16%)

Token

AstraAscendants (ASTRA)
 

Overview

Max Total Supply

6,779 ASTRA

Holders

314

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 ASTRA
0xc877b1f1140b6f1057a58efbd772fe1dccf1b3c8
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:
AstraAscendants

Compiler Version
v0.8.18+commit.87f61d96

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-11-12
*/

// File: erc721a/contracts/IERC721A.sol


// 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: erc721a/contracts/ERC721A.sol


// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;


/**
 * @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: @openzeppelin/contracts/security/ReentrancyGuard.sol


// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

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

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == _ENTERED;
    }
}

// File: @openzeppelin/contracts/utils/Context.sol


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)

pragma solidity ^0.8.0;


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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

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

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

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

// File: AstraAscendants.sol



pragma solidity ^0.8.0;



    
contract AstraAscendants is ERC721A, Ownable, ReentrancyGuard {
    bool public isMintingStart  = false;
    uint256 public pricePublic = 3000000000000000;
    string public baseURI;  
    uint256 public maxPerTransaction = 30;  
    uint256 public maxSupply = 6666;
    uint256 public mintSupply = 6666;
    mapping (address => uint256) public walletPublic;
    mapping (address => bool) public hasClaimedFreeMint;

    constructor() ERC721A("AstraAscendants", "ASTRA") {}

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

    function publicMint(uint256 qty) external payable {
        require(isMintingStart, "ASTRA isMintingStart Not live Yet !");
        require(qty <= maxPerTransaction, "ASTRA Max Per Max Per Transaction !");
        require(totalSupply() + qty <= mintSupply, "ASTRA Sold out !");

        uint256 totalCost = qty * pricePublic;

        // If user hasn't claimed their free mint and is minting only 1 NFT, set totalCost to 0
        if (!hasClaimedFreeMint[msg.sender] && qty == 1) {
            totalCost = 0;
            hasClaimedFreeMint[msg.sender] = true; 
        } 
        // If user hasn't claimed their free mint and is minting more than 1 NFT, deduct price of 1 NFT from totalCost
        else if (!hasClaimedFreeMint[msg.sender] && qty > 1) {
            totalCost -= pricePublic; 
            qty += 1; // They get one additional free NFT
            hasClaimedFreeMint[msg.sender] = true; 
        }

        require(msg.value >= totalCost, "ASTRA Insufficient Funds !");

        walletPublic[msg.sender] += qty;
        _safeMint(msg.sender, qty);
    }

    function numberMinted(address owner) public view returns (uint256) {
        return _numberMinted(owner);
    }

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

    function setPublicisMintingStart() external onlyOwner {
        isMintingStart  = !isMintingStart;
    }
    
    function setBaseURI(string memory baseURI_) external onlyOwner {
        baseURI = baseURI_;
    }

    function setPricePublic(uint256 price_) external onlyOwner {
        pricePublic = price_;
    }

    function setmaxPerTransaction(uint256 maxPerTransaction_) external onlyOwner {
        maxPerTransaction = maxPerTransaction_;
    }

    function setMintSupply(uint256 mintSupply_) external onlyOwner {
        mintSupply = mintSupply_;
    }

    function setWalletMint(address addr_) external onlyOwner {
        walletPublic[addr_] = 0;
        hasClaimedFreeMint[addr_] = false;
    }

    function withdraw() public onlyOwner {
        payable(msg.sender).transfer(payable(address(this)).balance);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","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":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"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":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasClaimedFreeMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMintingStart","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPerTransaction","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"pricePublic","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"qty","type":"uint256"}],"name":"publicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","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":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI_","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"mintSupply_","type":"uint256"}],"name":"setMintSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"price_","type":"uint256"}],"name":"setPricePublic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setPublicisMintingStart","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr_","type":"address"}],"name":"setWalletMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxPerTransaction_","type":"uint256"}],"name":"setmaxPerTransaction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"walletPublic","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526000600a60006101000a81548160ff021916908315150217905550660aa87bee538000600b55601e600d55611a0a600e55611a0a600f553480156200004857600080fd5b506040518060400160405280600f81526020017f4173747261417363656e64616e747300000000000000000000000000000000008152506040518060400160405280600581526020017f41535452410000000000000000000000000000000000000000000000000000008152508160029081620000c6919062000470565b508060039081620000d8919062000470565b50620000e96200011f60201b60201c565b600081905550505062000111620001056200012860201b60201c565b6200013060201b60201c565b600160098190555062000557565b60006001905090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200027857607f821691505b6020821081036200028e576200028d62000230565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620002f87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002b9565b620003048683620002b9565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620003516200034b62000345846200031c565b62000326565b6200031c565b9050919050565b6000819050919050565b6200036d8362000330565b620003856200037c8262000358565b848454620002c6565b825550505050565b600090565b6200039c6200038d565b620003a981848462000362565b505050565b5b81811015620003d157620003c560008262000392565b600181019050620003af565b5050565b601f8211156200042057620003ea8162000294565b620003f584620002a9565b8101602085101562000405578190505b6200041d6200041485620002a9565b830182620003ae565b50505b505050565b600082821c905092915050565b6000620004456000198460080262000425565b1980831691505092915050565b600062000460838362000432565b9150826002028217905092915050565b6200047b82620001f6565b67ffffffffffffffff81111562000497576200049662000201565b5b620004a382546200025f565b620004b0828285620003d5565b600060209050601f831160018114620004e85760008415620004d3578287015190505b620004df858262000452565b8655506200054f565b601f198416620004f88662000294565b60005b828110156200052257848901518255600182019150602085019450602081019050620004fb565b868310156200054257848901516200053e601f89168262000432565b8355505b6001600288020188555050505b505050505050565b612fda80620005676000396000f3fe6080604052600436106101f95760003560e01c806355f804b31161010d57806395d89b41116100a0578063c87b56dd1161006f578063c87b56dd146106b6578063d5abeb01146106f3578063dc33e6811461071e578063e985e9c51461075b578063f2fde38b14610798576101f9565b806395d89b411461061d578063a22cb46514610648578063ac568e8414610671578063b88d4fde1461069a576101f9565b806370a08231116100dc57806370a0823114610587578063715018a6146105c457806376cc322d146105db5780638da5cb5b146105f2576101f9565b806355f804b3146104cb5780635ff0c75b146104f45780636352211e1461051f5780636c0360eb1461055c576101f9565b806318160ddd116101905780633ccfd60b1161015f5780633ccfd60b1461040757806342842e0e1461041e578063428640d81461043a5780634530a832146104775780634b980d67146104a0576101f9565b806318160ddd1461036757806323b872dd146103925780632be905ba146103ae5780632db11544146103eb576101f9565b8063081812fc116101cc578063081812fc146102ba578063095ea7b3146102f7578063102e766d14610313578063108bfbfa1461033e576101f9565b806301ffc9a7146101fe578063045b7dca1461023b57806306f9ae431461026657806306fdde031461028f575b600080fd5b34801561020a57600080fd5b5061022560048036038101906102209190612178565b6107c1565b60405161023291906121c0565b60405180910390f35b34801561024757600080fd5b50610250610853565b60405161025d91906121f4565b60405180910390f35b34801561027257600080fd5b5061028d6004803603810190610288919061226d565b610859565b005b34801561029b57600080fd5b506102a4610901565b6040516102b1919061232a565b60405180910390f35b3480156102c657600080fd5b506102e160048036038101906102dc9190612378565b610993565b6040516102ee91906123b4565b60405180910390f35b610311600480360381019061030c91906123cf565b610a12565b005b34801561031f57600080fd5b50610328610b56565b60405161033591906121f4565b60405180910390f35b34801561034a57600080fd5b5061036560048036038101906103609190612378565b610b5c565b005b34801561037357600080fd5b5061037c610b6e565b60405161038991906121f4565b60405180910390f35b6103ac60048036038101906103a7919061240f565b610b85565b005b3480156103ba57600080fd5b506103d560048036038101906103d0919061226d565b610ea7565b6040516103e291906121f4565b60405180910390f35b61040560048036038101906104009190612378565b610ebf565b005b34801561041357600080fd5b5061041c6111fb565b005b6104386004803603810190610433919061240f565b611263565b005b34801561044657600080fd5b50610461600480360381019061045c919061226d565b611283565b60405161046e91906121c0565b60405180910390f35b34801561048357600080fd5b5061049e60048036038101906104999190612378565b6112a3565b005b3480156104ac57600080fd5b506104b56112b5565b6040516104c291906121f4565b60405180910390f35b3480156104d757600080fd5b506104f260048036038101906104ed9190612597565b6112bb565b005b34801561050057600080fd5b506105096112d6565b60405161051691906121c0565b60405180910390f35b34801561052b57600080fd5b5061054660048036038101906105419190612378565b6112e9565b60405161055391906123b4565b60405180910390f35b34801561056857600080fd5b506105716112fb565b60405161057e919061232a565b60405180910390f35b34801561059357600080fd5b506105ae60048036038101906105a9919061226d565b611389565b6040516105bb91906121f4565b60405180910390f35b3480156105d057600080fd5b506105d9611441565b005b3480156105e757600080fd5b506105f0611455565b005b3480156105fe57600080fd5b50610607611489565b60405161061491906123b4565b60405180910390f35b34801561062957600080fd5b506106326114b3565b60405161063f919061232a565b60405180910390f35b34801561065457600080fd5b5061066f600480360381019061066a919061260c565b611545565b005b34801561067d57600080fd5b5061069860048036038101906106939190612378565b611650565b005b6106b460048036038101906106af91906126ed565b611662565b005b3480156106c257600080fd5b506106dd60048036038101906106d89190612378565b6116d5565b6040516106ea919061232a565b60405180910390f35b3480156106ff57600080fd5b50610708611773565b60405161071591906121f4565b60405180910390f35b34801561072a57600080fd5b506107456004803603810190610740919061226d565b611779565b60405161075291906121f4565b60405180910390f35b34801561076757600080fd5b50610782600480360381019061077d9190612770565b61178b565b60405161078f91906121c0565b60405180910390f35b3480156107a457600080fd5b506107bf60048036038101906107ba919061226d565b61181f565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061081c57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061084c5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600f5481565b6108616118a2565b6000601060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000601160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b606060028054610910906127df565b80601f016020809104026020016040519081016040528092919081815260200182805461093c906127df565b80156109895780601f1061095e57610100808354040283529160200191610989565b820191906000526020600020905b81548152906001019060200180831161096c57829003601f168201915b5050505050905090565b600061099e82611920565b6109d4576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a1d826112e9565b90508073ffffffffffffffffffffffffffffffffffffffff16610a3e61197f565b73ffffffffffffffffffffffffffffffffffffffff1614610aa157610a6a81610a6561197f565b61178b565b610aa0576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600b5481565b610b646118a2565b80600d8190555050565b6000610b78611987565b6001546000540303905090565b6000610b9082611990565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610bf7576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610c0384611a5c565b91509150610c198187610c1461197f565b611a83565b610c6557610c2e86610c2961197f565b61178b565b610c64576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610ccb576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cd88686866001611ac7565b8015610ce357600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610db185610d8d888887611acd565b7c020000000000000000000000000000000000000000000000000000000017611af5565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610e375760006001850190506000600460008381526020019081526020016000205403610e35576000548114610e34578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610e9f8686866001611b20565b505050505050565b60106020528060005260406000206000915090505481565b600a60009054906101000a900460ff16610f0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f0590612882565b60405180910390fd5b600d54811115610f53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4a90612914565b60405180910390fd5b600f5481610f5f610b6e565b610f699190612963565b1115610faa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fa1906129e3565b60405180910390fd5b6000600b5482610fba9190612a03565b9050601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161580156110165750600182145b1561107c57600090506001601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611154565b601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161580156110d65750600182115b1561115357600b54816110e99190612a45565b90506001826110f89190612963565b91506001601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b5b80341015611197576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118e90612ac5565b60405180910390fd5b81601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546111e69190612963565b925050819055506111f73383611b26565b5050565b6112036118a2565b3373ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050158015611260573d6000803e3d6000fd5b50565b61127e83838360405180602001604052806000815250611662565b505050565b60116020528060005260406000206000915054906101000a900460ff1681565b6112ab6118a2565b80600b8190555050565b600d5481565b6112c36118a2565b80600c90816112d29190612c91565b5050565b600a60009054906101000a900460ff1681565b60006112f482611990565b9050919050565b600c8054611308906127df565b80601f0160208091040260200160405190810160405280929190818152602001828054611334906127df565b80156113815780601f1061135657610100808354040283529160200191611381565b820191906000526020600020905b81548152906001019060200180831161136457829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036113f0576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6114496118a2565b6114536000611b44565b565b61145d6118a2565b600a60009054906101000a900460ff1615600a60006101000a81548160ff021916908315150217905550565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600380546114c2906127df565b80601f01602080910402602001604051908101604052809291908181526020018280546114ee906127df565b801561153b5780601f106115105761010080835404028352916020019161153b565b820191906000526020600020905b81548152906001019060200180831161151e57829003601f168201915b5050505050905090565b806007600061155261197f565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166115ff61197f565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161164491906121c0565b60405180910390a35050565b6116586118a2565b80600f8190555050565b61166d848484610b85565b60008373ffffffffffffffffffffffffffffffffffffffff163b146116cf5761169884848484611c0a565b6116ce576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b60606116e082611920565b611716576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611720611d5a565b90506000815103611740576040518060200160405280600081525061176b565b8061174a84611dec565b60405160200161175b929190612d9f565b6040516020818303038152906040525b915050919050565b600e5481565b600061178482611e3c565b9050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6118276118a2565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188d90612e35565b60405180910390fd5b61189f81611b44565b50565b6118aa611e93565b73ffffffffffffffffffffffffffffffffffffffff166118c8611489565b73ffffffffffffffffffffffffffffffffffffffff161461191e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161191590612ea1565b60405180910390fd5b565b60008161192b611987565b1115801561193a575060005482105b8015611978575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b60006001905090565b6000808290508061199f611987565b11611a2557600054811015611a245760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603611a22575b60008103611a185760046000836001900393508381526020019081526020016000205490506119ee565b8092505050611a57565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8611ae4868684611e9b565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b611b40828260405180602001604052806000815250611ea4565b5050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611c3061197f565b8786866040518563ffffffff1660e01b8152600401611c529493929190612f16565b6020604051808303816000875af1925050508015611c8e57506040513d601f19601f82011682018060405250810190611c8b9190612f77565b60015b611d07573d8060008114611cbe576040519150601f19603f3d011682016040523d82523d6000602084013e611cc3565b606091505b506000815103611cff576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600c8054611d69906127df565b80601f0160208091040260200160405190810160405280929190818152602001828054611d95906127df565b8015611de25780601f10611db757610100808354040283529160200191611de2565b820191906000526020600020905b815481529060010190602001808311611dc557829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b600115611e2757600184039350600a81066030018453600a8104905080611e05575b50828103602084039350808452505050919050565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b600033905090565b60009392505050565b611eae8383611f41565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611f3c57600080549050600083820390505b611eee6000868380600101945086611c0a565b611f24576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110611edb578160005414611f3957600080fd5b50505b505050565b60008054905060008203611f81576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f8e6000848385611ac7565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061200583611ff66000866000611acd565b611fff856120fc565b17611af5565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146120a657808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460018101905061206b565b50600082036120e1576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060008190555050506120f76000848385611b20565b505050565b60006001821460e11b9050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61215581612120565b811461216057600080fd5b50565b6000813590506121728161214c565b92915050565b60006020828403121561218e5761218d612116565b5b600061219c84828501612163565b91505092915050565b60008115159050919050565b6121ba816121a5565b82525050565b60006020820190506121d560008301846121b1565b92915050565b6000819050919050565b6121ee816121db565b82525050565b600060208201905061220960008301846121e5565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061223a8261220f565b9050919050565b61224a8161222f565b811461225557600080fd5b50565b60008135905061226781612241565b92915050565b60006020828403121561228357612282612116565b5b600061229184828501612258565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156122d45780820151818401526020810190506122b9565b60008484015250505050565b6000601f19601f8301169050919050565b60006122fc8261229a565b61230681856122a5565b93506123168185602086016122b6565b61231f816122e0565b840191505092915050565b6000602082019050818103600083015261234481846122f1565b905092915050565b612355816121db565b811461236057600080fd5b50565b6000813590506123728161234c565b92915050565b60006020828403121561238e5761238d612116565b5b600061239c84828501612363565b91505092915050565b6123ae8161222f565b82525050565b60006020820190506123c960008301846123a5565b92915050565b600080604083850312156123e6576123e5612116565b5b60006123f485828601612258565b925050602061240585828601612363565b9150509250929050565b60008060006060848603121561242857612427612116565b5b600061243686828701612258565b935050602061244786828701612258565b925050604061245886828701612363565b9150509250925092565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124a4826122e0565b810181811067ffffffffffffffff821117156124c3576124c261246c565b5b80604052505050565b60006124d661210c565b90506124e2828261249b565b919050565b600067ffffffffffffffff8211156125025761250161246c565b5b61250b826122e0565b9050602081019050919050565b82818337600083830152505050565b600061253a612535846124e7565b6124cc565b90508281526020810184848401111561255657612555612467565b5b612561848285612518565b509392505050565b600082601f83011261257e5761257d612462565b5b813561258e848260208601612527565b91505092915050565b6000602082840312156125ad576125ac612116565b5b600082013567ffffffffffffffff8111156125cb576125ca61211b565b5b6125d784828501612569565b91505092915050565b6125e9816121a5565b81146125f457600080fd5b50565b600081359050612606816125e0565b92915050565b6000806040838503121561262357612622612116565b5b600061263185828601612258565b9250506020612642858286016125f7565b9150509250929050565b600067ffffffffffffffff8211156126675761266661246c565b5b612670826122e0565b9050602081019050919050565b600061269061268b8461264c565b6124cc565b9050828152602081018484840111156126ac576126ab612467565b5b6126b7848285612518565b509392505050565b600082601f8301126126d4576126d3612462565b5b81356126e484826020860161267d565b91505092915050565b6000806000806080858703121561270757612706612116565b5b600061271587828801612258565b945050602061272687828801612258565b935050604061273787828801612363565b925050606085013567ffffffffffffffff8111156127585761275761211b565b5b612764878288016126bf565b91505092959194509250565b6000806040838503121561278757612786612116565b5b600061279585828601612258565b92505060206127a685828601612258565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806127f757607f821691505b60208210810361280a576128096127b0565b5b50919050565b7f41535452412069734d696e74696e675374617274204e6f74206c69766520596560008201527f7420210000000000000000000000000000000000000000000000000000000000602082015250565b600061286c6023836122a5565b915061287782612810565b604082019050919050565b6000602082019050818103600083015261289b8161285f565b9050919050565b7f4153545241204d617820506572204d617820506572205472616e73616374696f60008201527f6e20210000000000000000000000000000000000000000000000000000000000602082015250565b60006128fe6023836122a5565b9150612909826128a2565b604082019050919050565b6000602082019050818103600083015261292d816128f1565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061296e826121db565b9150612979836121db565b925082820190508082111561299157612990612934565b5b92915050565b7f415354524120536f6c64206f7574202100000000000000000000000000000000600082015250565b60006129cd6010836122a5565b91506129d882612997565b602082019050919050565b600060208201905081810360008301526129fc816129c0565b9050919050565b6000612a0e826121db565b9150612a19836121db565b9250828202612a27816121db565b91508282048414831517612a3e57612a3d612934565b5b5092915050565b6000612a50826121db565b9150612a5b836121db565b9250828203905081811115612a7357612a72612934565b5b92915050565b7f415354524120496e73756666696369656e742046756e64732021000000000000600082015250565b6000612aaf601a836122a5565b9150612aba82612a79565b602082019050919050565b60006020820190508181036000830152612ade81612aa2565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302612b477fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612b0a565b612b518683612b0a565b95508019841693508086168417925050509392505050565b6000819050919050565b6000612b8e612b89612b84846121db565b612b69565b6121db565b9050919050565b6000819050919050565b612ba883612b73565b612bbc612bb482612b95565b848454612b17565b825550505050565b600090565b612bd1612bc4565b612bdc818484612b9f565b505050565b5b81811015612c0057612bf5600082612bc9565b600181019050612be2565b5050565b601f821115612c4557612c1681612ae5565b612c1f84612afa565b81016020851015612c2e578190505b612c42612c3a85612afa565b830182612be1565b50505b505050565b600082821c905092915050565b6000612c6860001984600802612c4a565b1980831691505092915050565b6000612c818383612c57565b9150826002028217905092915050565b612c9a8261229a565b67ffffffffffffffff811115612cb357612cb261246c565b5b612cbd82546127df565b612cc8828285612c04565b600060209050601f831160018114612cfb5760008415612ce9578287015190505b612cf38582612c75565b865550612d5b565b601f198416612d0986612ae5565b60005b82811015612d3157848901518255600182019150602085019450602081019050612d0c565b86831015612d4e5784890151612d4a601f891682612c57565b8355505b6001600288020188555050505b505050505050565b600081905092915050565b6000612d798261229a565b612d838185612d63565b9350612d938185602086016122b6565b80840191505092915050565b6000612dab8285612d6e565b9150612db78284612d6e565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612e1f6026836122a5565b9150612e2a82612dc3565b604082019050919050565b60006020820190508181036000830152612e4e81612e12565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612e8b6020836122a5565b9150612e9682612e55565b602082019050919050565b60006020820190508181036000830152612eba81612e7e565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000612ee882612ec1565b612ef28185612ecc565b9350612f028185602086016122b6565b612f0b816122e0565b840191505092915050565b6000608082019050612f2b60008301876123a5565b612f3860208301866123a5565b612f4560408301856121e5565b8181036060830152612f578184612edd565b905095945050505050565b600081519050612f718161214c565b92915050565b600060208284031215612f8d57612f8c612116565b5b6000612f9b84828501612f62565b9150509291505056fea26469706673582212201f9a924a22a14da7827f615306cf8c5853053aeb4353c23cb5db251b54cc9cc764736f6c63430008120033

Deployed Bytecode

0x6080604052600436106101f95760003560e01c806355f804b31161010d57806395d89b41116100a0578063c87b56dd1161006f578063c87b56dd146106b6578063d5abeb01146106f3578063dc33e6811461071e578063e985e9c51461075b578063f2fde38b14610798576101f9565b806395d89b411461061d578063a22cb46514610648578063ac568e8414610671578063b88d4fde1461069a576101f9565b806370a08231116100dc57806370a0823114610587578063715018a6146105c457806376cc322d146105db5780638da5cb5b146105f2576101f9565b806355f804b3146104cb5780635ff0c75b146104f45780636352211e1461051f5780636c0360eb1461055c576101f9565b806318160ddd116101905780633ccfd60b1161015f5780633ccfd60b1461040757806342842e0e1461041e578063428640d81461043a5780634530a832146104775780634b980d67146104a0576101f9565b806318160ddd1461036757806323b872dd146103925780632be905ba146103ae5780632db11544146103eb576101f9565b8063081812fc116101cc578063081812fc146102ba578063095ea7b3146102f7578063102e766d14610313578063108bfbfa1461033e576101f9565b806301ffc9a7146101fe578063045b7dca1461023b57806306f9ae431461026657806306fdde031461028f575b600080fd5b34801561020a57600080fd5b5061022560048036038101906102209190612178565b6107c1565b60405161023291906121c0565b60405180910390f35b34801561024757600080fd5b50610250610853565b60405161025d91906121f4565b60405180910390f35b34801561027257600080fd5b5061028d6004803603810190610288919061226d565b610859565b005b34801561029b57600080fd5b506102a4610901565b6040516102b1919061232a565b60405180910390f35b3480156102c657600080fd5b506102e160048036038101906102dc9190612378565b610993565b6040516102ee91906123b4565b60405180910390f35b610311600480360381019061030c91906123cf565b610a12565b005b34801561031f57600080fd5b50610328610b56565b60405161033591906121f4565b60405180910390f35b34801561034a57600080fd5b5061036560048036038101906103609190612378565b610b5c565b005b34801561037357600080fd5b5061037c610b6e565b60405161038991906121f4565b60405180910390f35b6103ac60048036038101906103a7919061240f565b610b85565b005b3480156103ba57600080fd5b506103d560048036038101906103d0919061226d565b610ea7565b6040516103e291906121f4565b60405180910390f35b61040560048036038101906104009190612378565b610ebf565b005b34801561041357600080fd5b5061041c6111fb565b005b6104386004803603810190610433919061240f565b611263565b005b34801561044657600080fd5b50610461600480360381019061045c919061226d565b611283565b60405161046e91906121c0565b60405180910390f35b34801561048357600080fd5b5061049e60048036038101906104999190612378565b6112a3565b005b3480156104ac57600080fd5b506104b56112b5565b6040516104c291906121f4565b60405180910390f35b3480156104d757600080fd5b506104f260048036038101906104ed9190612597565b6112bb565b005b34801561050057600080fd5b506105096112d6565b60405161051691906121c0565b60405180910390f35b34801561052b57600080fd5b5061054660048036038101906105419190612378565b6112e9565b60405161055391906123b4565b60405180910390f35b34801561056857600080fd5b506105716112fb565b60405161057e919061232a565b60405180910390f35b34801561059357600080fd5b506105ae60048036038101906105a9919061226d565b611389565b6040516105bb91906121f4565b60405180910390f35b3480156105d057600080fd5b506105d9611441565b005b3480156105e757600080fd5b506105f0611455565b005b3480156105fe57600080fd5b50610607611489565b60405161061491906123b4565b60405180910390f35b34801561062957600080fd5b506106326114b3565b60405161063f919061232a565b60405180910390f35b34801561065457600080fd5b5061066f600480360381019061066a919061260c565b611545565b005b34801561067d57600080fd5b5061069860048036038101906106939190612378565b611650565b005b6106b460048036038101906106af91906126ed565b611662565b005b3480156106c257600080fd5b506106dd60048036038101906106d89190612378565b6116d5565b6040516106ea919061232a565b60405180910390f35b3480156106ff57600080fd5b50610708611773565b60405161071591906121f4565b60405180910390f35b34801561072a57600080fd5b506107456004803603810190610740919061226d565b611779565b60405161075291906121f4565b60405180910390f35b34801561076757600080fd5b50610782600480360381019061077d9190612770565b61178b565b60405161078f91906121c0565b60405180910390f35b3480156107a457600080fd5b506107bf60048036038101906107ba919061226d565b61181f565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061081c57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061084c5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600f5481565b6108616118a2565b6000601060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000601160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b606060028054610910906127df565b80601f016020809104026020016040519081016040528092919081815260200182805461093c906127df565b80156109895780601f1061095e57610100808354040283529160200191610989565b820191906000526020600020905b81548152906001019060200180831161096c57829003601f168201915b5050505050905090565b600061099e82611920565b6109d4576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a1d826112e9565b90508073ffffffffffffffffffffffffffffffffffffffff16610a3e61197f565b73ffffffffffffffffffffffffffffffffffffffff1614610aa157610a6a81610a6561197f565b61178b565b610aa0576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600b5481565b610b646118a2565b80600d8190555050565b6000610b78611987565b6001546000540303905090565b6000610b9082611990565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610bf7576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610c0384611a5c565b91509150610c198187610c1461197f565b611a83565b610c6557610c2e86610c2961197f565b61178b565b610c64576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610ccb576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cd88686866001611ac7565b8015610ce357600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610db185610d8d888887611acd565b7c020000000000000000000000000000000000000000000000000000000017611af5565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610e375760006001850190506000600460008381526020019081526020016000205403610e35576000548114610e34578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610e9f8686866001611b20565b505050505050565b60106020528060005260406000206000915090505481565b600a60009054906101000a900460ff16610f0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f0590612882565b60405180910390fd5b600d54811115610f53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4a90612914565b60405180910390fd5b600f5481610f5f610b6e565b610f699190612963565b1115610faa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fa1906129e3565b60405180910390fd5b6000600b5482610fba9190612a03565b9050601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161580156110165750600182145b1561107c57600090506001601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611154565b601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161580156110d65750600182115b1561115357600b54816110e99190612a45565b90506001826110f89190612963565b91506001601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b5b80341015611197576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118e90612ac5565b60405180910390fd5b81601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546111e69190612963565b925050819055506111f73383611b26565b5050565b6112036118a2565b3373ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050158015611260573d6000803e3d6000fd5b50565b61127e83838360405180602001604052806000815250611662565b505050565b60116020528060005260406000206000915054906101000a900460ff1681565b6112ab6118a2565b80600b8190555050565b600d5481565b6112c36118a2565b80600c90816112d29190612c91565b5050565b600a60009054906101000a900460ff1681565b60006112f482611990565b9050919050565b600c8054611308906127df565b80601f0160208091040260200160405190810160405280929190818152602001828054611334906127df565b80156113815780601f1061135657610100808354040283529160200191611381565b820191906000526020600020905b81548152906001019060200180831161136457829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036113f0576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6114496118a2565b6114536000611b44565b565b61145d6118a2565b600a60009054906101000a900460ff1615600a60006101000a81548160ff021916908315150217905550565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600380546114c2906127df565b80601f01602080910402602001604051908101604052809291908181526020018280546114ee906127df565b801561153b5780601f106115105761010080835404028352916020019161153b565b820191906000526020600020905b81548152906001019060200180831161151e57829003601f168201915b5050505050905090565b806007600061155261197f565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166115ff61197f565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161164491906121c0565b60405180910390a35050565b6116586118a2565b80600f8190555050565b61166d848484610b85565b60008373ffffffffffffffffffffffffffffffffffffffff163b146116cf5761169884848484611c0a565b6116ce576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b60606116e082611920565b611716576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611720611d5a565b90506000815103611740576040518060200160405280600081525061176b565b8061174a84611dec565b60405160200161175b929190612d9f565b6040516020818303038152906040525b915050919050565b600e5481565b600061178482611e3c565b9050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6118276118a2565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188d90612e35565b60405180910390fd5b61189f81611b44565b50565b6118aa611e93565b73ffffffffffffffffffffffffffffffffffffffff166118c8611489565b73ffffffffffffffffffffffffffffffffffffffff161461191e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161191590612ea1565b60405180910390fd5b565b60008161192b611987565b1115801561193a575060005482105b8015611978575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b60006001905090565b6000808290508061199f611987565b11611a2557600054811015611a245760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603611a22575b60008103611a185760046000836001900393508381526020019081526020016000205490506119ee565b8092505050611a57565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8611ae4868684611e9b565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b611b40828260405180602001604052806000815250611ea4565b5050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611c3061197f565b8786866040518563ffffffff1660e01b8152600401611c529493929190612f16565b6020604051808303816000875af1925050508015611c8e57506040513d601f19601f82011682018060405250810190611c8b9190612f77565b60015b611d07573d8060008114611cbe576040519150601f19603f3d011682016040523d82523d6000602084013e611cc3565b606091505b506000815103611cff576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600c8054611d69906127df565b80601f0160208091040260200160405190810160405280929190818152602001828054611d95906127df565b8015611de25780601f10611db757610100808354040283529160200191611de2565b820191906000526020600020905b815481529060010190602001808311611dc557829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b600115611e2757600184039350600a81066030018453600a8104905080611e05575b50828103602084039350808452505050919050565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b600033905090565b60009392505050565b611eae8383611f41565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611f3c57600080549050600083820390505b611eee6000868380600101945086611c0a565b611f24576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110611edb578160005414611f3957600080fd5b50505b505050565b60008054905060008203611f81576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f8e6000848385611ac7565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061200583611ff66000866000611acd565b611fff856120fc565b17611af5565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146120a657808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460018101905061206b565b50600082036120e1576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060008190555050506120f76000848385611b20565b505050565b60006001821460e11b9050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61215581612120565b811461216057600080fd5b50565b6000813590506121728161214c565b92915050565b60006020828403121561218e5761218d612116565b5b600061219c84828501612163565b91505092915050565b60008115159050919050565b6121ba816121a5565b82525050565b60006020820190506121d560008301846121b1565b92915050565b6000819050919050565b6121ee816121db565b82525050565b600060208201905061220960008301846121e5565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061223a8261220f565b9050919050565b61224a8161222f565b811461225557600080fd5b50565b60008135905061226781612241565b92915050565b60006020828403121561228357612282612116565b5b600061229184828501612258565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156122d45780820151818401526020810190506122b9565b60008484015250505050565b6000601f19601f8301169050919050565b60006122fc8261229a565b61230681856122a5565b93506123168185602086016122b6565b61231f816122e0565b840191505092915050565b6000602082019050818103600083015261234481846122f1565b905092915050565b612355816121db565b811461236057600080fd5b50565b6000813590506123728161234c565b92915050565b60006020828403121561238e5761238d612116565b5b600061239c84828501612363565b91505092915050565b6123ae8161222f565b82525050565b60006020820190506123c960008301846123a5565b92915050565b600080604083850312156123e6576123e5612116565b5b60006123f485828601612258565b925050602061240585828601612363565b9150509250929050565b60008060006060848603121561242857612427612116565b5b600061243686828701612258565b935050602061244786828701612258565b925050604061245886828701612363565b9150509250925092565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124a4826122e0565b810181811067ffffffffffffffff821117156124c3576124c261246c565b5b80604052505050565b60006124d661210c565b90506124e2828261249b565b919050565b600067ffffffffffffffff8211156125025761250161246c565b5b61250b826122e0565b9050602081019050919050565b82818337600083830152505050565b600061253a612535846124e7565b6124cc565b90508281526020810184848401111561255657612555612467565b5b612561848285612518565b509392505050565b600082601f83011261257e5761257d612462565b5b813561258e848260208601612527565b91505092915050565b6000602082840312156125ad576125ac612116565b5b600082013567ffffffffffffffff8111156125cb576125ca61211b565b5b6125d784828501612569565b91505092915050565b6125e9816121a5565b81146125f457600080fd5b50565b600081359050612606816125e0565b92915050565b6000806040838503121561262357612622612116565b5b600061263185828601612258565b9250506020612642858286016125f7565b9150509250929050565b600067ffffffffffffffff8211156126675761266661246c565b5b612670826122e0565b9050602081019050919050565b600061269061268b8461264c565b6124cc565b9050828152602081018484840111156126ac576126ab612467565b5b6126b7848285612518565b509392505050565b600082601f8301126126d4576126d3612462565b5b81356126e484826020860161267d565b91505092915050565b6000806000806080858703121561270757612706612116565b5b600061271587828801612258565b945050602061272687828801612258565b935050604061273787828801612363565b925050606085013567ffffffffffffffff8111156127585761275761211b565b5b612764878288016126bf565b91505092959194509250565b6000806040838503121561278757612786612116565b5b600061279585828601612258565b92505060206127a685828601612258565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806127f757607f821691505b60208210810361280a576128096127b0565b5b50919050565b7f41535452412069734d696e74696e675374617274204e6f74206c69766520596560008201527f7420210000000000000000000000000000000000000000000000000000000000602082015250565b600061286c6023836122a5565b915061287782612810565b604082019050919050565b6000602082019050818103600083015261289b8161285f565b9050919050565b7f4153545241204d617820506572204d617820506572205472616e73616374696f60008201527f6e20210000000000000000000000000000000000000000000000000000000000602082015250565b60006128fe6023836122a5565b9150612909826128a2565b604082019050919050565b6000602082019050818103600083015261292d816128f1565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061296e826121db565b9150612979836121db565b925082820190508082111561299157612990612934565b5b92915050565b7f415354524120536f6c64206f7574202100000000000000000000000000000000600082015250565b60006129cd6010836122a5565b91506129d882612997565b602082019050919050565b600060208201905081810360008301526129fc816129c0565b9050919050565b6000612a0e826121db565b9150612a19836121db565b9250828202612a27816121db565b91508282048414831517612a3e57612a3d612934565b5b5092915050565b6000612a50826121db565b9150612a5b836121db565b9250828203905081811115612a7357612a72612934565b5b92915050565b7f415354524120496e73756666696369656e742046756e64732021000000000000600082015250565b6000612aaf601a836122a5565b9150612aba82612a79565b602082019050919050565b60006020820190508181036000830152612ade81612aa2565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302612b477fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612b0a565b612b518683612b0a565b95508019841693508086168417925050509392505050565b6000819050919050565b6000612b8e612b89612b84846121db565b612b69565b6121db565b9050919050565b6000819050919050565b612ba883612b73565b612bbc612bb482612b95565b848454612b17565b825550505050565b600090565b612bd1612bc4565b612bdc818484612b9f565b505050565b5b81811015612c0057612bf5600082612bc9565b600181019050612be2565b5050565b601f821115612c4557612c1681612ae5565b612c1f84612afa565b81016020851015612c2e578190505b612c42612c3a85612afa565b830182612be1565b50505b505050565b600082821c905092915050565b6000612c6860001984600802612c4a565b1980831691505092915050565b6000612c818383612c57565b9150826002028217905092915050565b612c9a8261229a565b67ffffffffffffffff811115612cb357612cb261246c565b5b612cbd82546127df565b612cc8828285612c04565b600060209050601f831160018114612cfb5760008415612ce9578287015190505b612cf38582612c75565b865550612d5b565b601f198416612d0986612ae5565b60005b82811015612d3157848901518255600182019150602085019450602081019050612d0c565b86831015612d4e5784890151612d4a601f891682612c57565b8355505b6001600288020188555050505b505050505050565b600081905092915050565b6000612d798261229a565b612d838185612d63565b9350612d938185602086016122b6565b80840191505092915050565b6000612dab8285612d6e565b9150612db78284612d6e565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612e1f6026836122a5565b9150612e2a82612dc3565b604082019050919050565b60006020820190508181036000830152612e4e81612e12565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612e8b6020836122a5565b9150612e9682612e55565b602082019050919050565b60006020820190508181036000830152612eba81612e7e565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000612ee882612ec1565b612ef28185612ecc565b9350612f028185602086016122b6565b612f0b816122e0565b840191505092915050565b6000608082019050612f2b60008301876123a5565b612f3860208301866123a5565b612f4560408301856121e5565b8181036060830152612f578184612edd565b905095945050505050565b600081519050612f718161214c565b92915050565b600060208284031215612f8d57612f8c612116565b5b6000612f9b84828501612f62565b9150509291505056fea26469706673582212201f9a924a22a14da7827f615306cf8c5853053aeb4353c23cb5db251b54cc9cc764736f6c63430008120033

Deployed Bytecode Sourcemap

58334:2794:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18404:639;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58611:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60858:143;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;19306:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25797:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25230:408;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58445:45;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60602:134;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;15057:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;29436:2825;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58650:48;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58934:1091;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;61009:116;;;;;;;;;;;;;:::i;:::-;;32357:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58705:51;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60496:98;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58527:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60388:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58403:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;20699:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58497:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;16241:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57444:103;;;;;;;;;;;;;:::i;:::-;;60270:106;;;;;;;;;;;;;:::i;:::-;;56803:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;19482:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26355:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60744:106;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;33148:407;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;19692:318;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58573:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60033:113;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26746:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57702:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;18404:639;18489:4;18828:10;18813:25;;:11;:25;;;;:102;;;;18905:10;18890:25;;:11;:25;;;;18813:102;:179;;;;18982:10;18967:25;;:11;:25;;;;18813:179;18793:199;;18404:639;;;:::o;58611:32::-;;;;:::o;60858:143::-;56689:13;:11;:13::i;:::-;60948:1:::1;60926:12;:19;60939:5;60926:19;;;;;;;;;;;;;;;:23;;;;60988:5;60960:18;:25;60979:5;60960:25;;;;;;;;;;;;;;;;:33;;;;;;;;;;;;;;;;;;60858:143:::0;:::o;19306:100::-;19360:13;19393:5;19386:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19306:100;:::o;25797:218::-;25873:7;25898:16;25906:7;25898;:16::i;:::-;25893:64;;25923:34;;;;;;;;;;;;;;25893:64;25977:15;:24;25993:7;25977:24;;;;;;;;;;;:30;;;;;;;;;;;;25970:37;;25797:218;;;:::o;25230:408::-;25319:13;25335:16;25343:7;25335;:16::i;:::-;25319:32;;25391:5;25368:28;;:19;:17;:19::i;:::-;:28;;;25364:175;;25416:44;25433:5;25440:19;:17;:19::i;:::-;25416:16;:44::i;:::-;25411:128;;25488:35;;;;;;;;;;;;;;25411:128;25364:175;25584:2;25551:15;:24;25567:7;25551:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;25622:7;25618:2;25602:28;;25611:5;25602:28;;;;;;;;;;;;25308:330;25230:408;;:::o;58445:45::-;;;;:::o;60602:134::-;56689:13;:11;:13::i;:::-;60710:18:::1;60690:17;:38;;;;60602:134:::0;:::o;15057:323::-;15118:7;15346:15;:13;:15::i;:::-;15331:12;;15315:13;;:28;:46;15308:53;;15057:323;:::o;29436:2825::-;29578:27;29608;29627:7;29608:18;:27::i;:::-;29578:57;;29693:4;29652:45;;29668:19;29652:45;;;29648:86;;29706:28;;;;;;;;;;;;;;29648:86;29748:27;29777:23;29804:35;29831:7;29804:26;:35::i;:::-;29747:92;;;;29939:68;29964:15;29981:4;29987:19;:17;:19::i;:::-;29939:24;:68::i;:::-;29934:180;;30027:43;30044:4;30050:19;:17;:19::i;:::-;30027:16;:43::i;:::-;30022:92;;30079:35;;;;;;;;;;;;;;30022:92;29934:180;30145:1;30131:16;;:2;:16;;;30127:52;;30156:23;;;;;;;;;;;;;;30127:52;30192:43;30214:4;30220:2;30224:7;30233:1;30192:21;:43::i;:::-;30328:15;30325:160;;;30468:1;30447:19;30440:30;30325:160;30865:18;:24;30884:4;30865:24;;;;;;;;;;;;;;;;30863:26;;;;;;;;;;;;30934:18;:22;30953:2;30934:22;;;;;;;;;;;;;;;;30932:24;;;;;;;;;;;31256:146;31293:2;31342:45;31357:4;31363:2;31367:19;31342:14;:45::i;:::-;11456:8;31314:73;31256:18;:146::i;:::-;31227:17;:26;31245:7;31227:26;;;;;;;;;;;:175;;;;31573:1;11456:8;31522:19;:47;:52;31518:627;;31595:19;31627:1;31617:7;:11;31595:33;;31784:1;31750:17;:30;31768:11;31750:30;;;;;;;;;;;;:35;31746:384;;31888:13;;31873:11;:28;31869:242;;32068:19;32035:17;:30;32053:11;32035:30;;;;;;;;;;;:52;;;;31869:242;31746:384;31576:569;31518:627;32192:7;32188:2;32173:27;;32182:4;32173:27;;;;;;;;;;;;32211:42;32232:4;32238:2;32242:7;32251:1;32211:20;:42::i;:::-;29567:2694;;;29436:2825;;;:::o;58650:48::-;;;;;;;;;;;;;;;;;:::o;58934:1091::-;59003:14;;;;;;;;;;;58995:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;59083:17;;59076:3;:24;;59068:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;59182:10;;59175:3;59159:13;:11;:13::i;:::-;:19;;;;:::i;:::-;:33;;59151:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;59226:17;59252:11;;59246:3;:17;;;;:::i;:::-;59226:37;;59378:18;:30;59397:10;59378:30;;;;;;;;;;;;;;;;;;;;;;;;;59377:31;:43;;;;;59419:1;59412:3;:8;59377:43;59373:490;;;59449:1;59437:13;;59498:4;59465:18;:30;59484:10;59465:30;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;59373:490;;;59656:18;:30;59675:10;59656:30;;;;;;;;;;;;;;;;;;;;;;;;;59655:31;:42;;;;;59696:1;59690:3;:7;59655:42;59651:212;;;59727:11;;59714:24;;;;;:::i;:::-;;;59761:1;59754:8;;;;;:::i;:::-;;;59846:4;59813:18;:30;59832:10;59813:30;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;59651:212;59373:490;59896:9;59883;:22;;59875:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;59977:3;59949:12;:24;59962:10;59949:24;;;;;;;;;;;;;;;;:31;;;;;;;:::i;:::-;;;;;;;;59991:26;60001:10;60013:3;59991:9;:26::i;:::-;58984:1041;58934:1091;:::o;61009:116::-;56689:13;:11;:13::i;:::-;61065:10:::1;61057:28;;:60;61102:4;61086:30;;;61057:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;61009:116::o:0;32357:193::-;32503:39;32520:4;32526:2;32530:7;32503:39;;;;;;;;;;;;:16;:39::i;:::-;32357:193;;;:::o;58705:51::-;;;;;;;;;;;;;;;;;;;;;;:::o;60496:98::-;56689:13;:11;:13::i;:::-;60580:6:::1;60566:11;:20;;;;60496:98:::0;:::o;58527:37::-;;;;:::o;60388:100::-;56689:13;:11;:13::i;:::-;60472:8:::1;60462:7;:18;;;;;;:::i;:::-;;60388:100:::0;:::o;58403:35::-;;;;;;;;;;;;;:::o;20699:152::-;20771:7;20814:27;20833:7;20814:18;:27::i;:::-;20791:52;;20699:152;;;:::o;58497:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;16241:233::-;16313:7;16354:1;16337:19;;:5;:19;;;16333:60;;16365:28;;;;;;;;;;;;;;16333:60;10400:13;16411:18;:25;16430:5;16411:25;;;;;;;;;;;;;;;;:55;16404:62;;16241:233;;;:::o;57444:103::-;56689:13;:11;:13::i;:::-;57509:30:::1;57536:1;57509:18;:30::i;:::-;57444:103::o:0;60270:106::-;56689:13;:11;:13::i;:::-;60354:14:::1;;;;;;;;;;;60353:15;60335:14;;:33;;;;;;;;;;;;;;;;;;60270:106::o:0;56803:87::-;56849:7;56876:6;;;;;;;;;;;56869:13;;56803:87;:::o;19482:104::-;19538:13;19571:7;19564:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19482:104;:::o;26355:234::-;26502:8;26450:18;:39;26469:19;:17;:19::i;:::-;26450:39;;;;;;;;;;;;;;;:49;26490:8;26450:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;26562:8;26526:55;;26541:19;:17;:19::i;:::-;26526:55;;;26572:8;26526:55;;;;;;:::i;:::-;;;;;;;;26355:234;;:::o;60744:106::-;56689:13;:11;:13::i;:::-;60831:11:::1;60818:10;:24;;;;60744:106:::0;:::o;33148:407::-;33323:31;33336:4;33342:2;33346:7;33323:12;:31::i;:::-;33387:1;33369:2;:14;;;:19;33365:183;;33408:56;33439:4;33445:2;33449:7;33458:5;33408:30;:56::i;:::-;33403:145;;33492:40;;;;;;;;;;;;;;33403:145;33365:183;33148:407;;;;:::o;19692:318::-;19765:13;19796:16;19804:7;19796;:16::i;:::-;19791:59;;19821:29;;;;;;;;;;;;;;19791:59;19863:21;19887:10;:8;:10::i;:::-;19863:34;;19940:1;19921:7;19915:21;:26;:87;;;;;;;;;;;;;;;;;19968:7;19977:18;19987:7;19977:9;:18::i;:::-;19951:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19915:87;19908:94;;;19692:318;;;:::o;58573:31::-;;;;:::o;60033:113::-;60091:7;60118:20;60132:5;60118:13;:20::i;:::-;60111:27;;60033:113;;;:::o;26746:164::-;26843:4;26867:18;:25;26886:5;26867:25;;;;;;;;;;;;;;;:35;26893:8;26867:35;;;;;;;;;;;;;;;;;;;;;;;;;26860:42;;26746:164;;;;:::o;57702:201::-;56689:13;:11;:13::i;:::-;57811:1:::1;57791:22;;:8;:22;;::::0;57783:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;57867:28;57886:8;57867:18;:28::i;:::-;57702:201:::0;:::o;56968:132::-;57043:12;:10;:12::i;:::-;57032:23;;:7;:5;:7::i;:::-;:23;;;57024:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;56968:132::o;27168:282::-;27233:4;27289:7;27270:15;:13;:15::i;:::-;:26;;:66;;;;;27323:13;;27313:7;:23;27270:66;:153;;;;;27422:1;11176:8;27374:17;:26;27392:7;27374:26;;;;;;;;;;;;:44;:49;27270:153;27250:173;;27168:282;;;:::o;49476:105::-;49536:7;49563:10;49556:17;;49476:105;:::o;58825:101::-;58890:7;58917:1;58910:8;;58825:101;:::o;21854:1275::-;21921:7;21941:12;21956:7;21941:22;;22024:4;22005:15;:13;:15::i;:::-;:23;22001:1061;;22058:13;;22051:4;:20;22047:1015;;;22096:14;22113:17;:23;22131:4;22113:23;;;;;;;;;;;;22096:40;;22230:1;11176:8;22202:6;:24;:29;22198:845;;22867:113;22884:1;22874:6;:11;22867:113;;22927:17;:25;22945:6;;;;;;;22927:25;;;;;;;;;;;;22918:34;;22867:113;;;23013:6;23006:13;;;;;;22198:845;22073:989;22047:1015;22001:1061;23090:31;;;;;;;;;;;;;;21854:1275;;;;:::o;28331:485::-;28433:27;28462:23;28503:38;28544:15;:24;28560:7;28544:24;;;;;;;;;;;28503:65;;28721:18;28698:41;;28778:19;28772:26;28753:45;;28683:126;28331:485;;;:::o;27559:659::-;27708:11;27873:16;27866:5;27862:28;27853:37;;28033:16;28022:9;28018:32;28005:45;;28183:15;28172:9;28169:30;28161:5;28150:9;28147:20;28144:56;28134:66;;27559:659;;;;;:::o;34217:159::-;;;;;:::o;48785:311::-;48920:7;48940:16;11580:3;48966:19;:41;;48940:68;;11580:3;49034:31;49045:4;49051:2;49055:9;49034:10;:31::i;:::-;49026:40;;:62;;49019:69;;;48785:311;;;;;:::o;23677:450::-;23757:14;23925:16;23918:5;23914:28;23905:37;;24102:5;24088:11;24063:23;24059:41;24056:52;24049:5;24046:63;24036:73;;23677:450;;;;:::o;35041:158::-;;;;;:::o;43308:112::-;43385:27;43395:2;43399:8;43385:27;;;;;;;;;;;;:9;:27::i;:::-;43308:112;;:::o;58063:191::-;58137:16;58156:6;;;;;;;;;;;58137:25;;58182:8;58173:6;;:17;;;;;;;;;;;;;;;;;;58237:8;58206:40;;58227:8;58206:40;;;;;;;;;;;;58126:128;58063:191;:::o;35639:716::-;35802:4;35848:2;35823:45;;;35869:19;:17;:19::i;:::-;35890:4;35896:7;35905:5;35823:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;35819:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36123:1;36106:6;:13;:18;36102:235;;36152:40;;;;;;;;;;;;;;36102:235;36295:6;36289:13;36280:6;36276:2;36272:15;36265:38;35819:529;35992:54;;;35982:64;;;:6;:64;;;;35975:71;;;35639:716;;;;;;:::o;60154:108::-;60214:13;60247:7;60240:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60154:108;:::o;49683:1745::-;49748:17;50182:4;50175;50169:11;50165:22;50274:1;50268:4;50261:15;50349:4;50346:1;50342:12;50335:19;;50431:1;50426:3;50419:14;50535:3;50774:5;50756:428;50782:1;50756:428;;;50822:1;50817:3;50813:11;50806:18;;50993:2;50987:4;50983:13;50979:2;50975:22;50970:3;50962:36;51087:2;51081:4;51077:13;51069:21;;51154:4;50756:428;51144:25;50756:428;50760:21;51223:3;51218;51214:13;51338:4;51333:3;51329:14;51322:21;;51403:6;51398:3;51391:19;49787:1634;;;49683:1745;;;:::o;16556:178::-;16617:7;10400:13;10538:2;16645:18;:25;16664:5;16645:25;;;;;;;;;;;;;;;;:50;;16644:82;16637:89;;16556:178;;;:::o;55354:98::-;55407:7;55434:10;55427:17;;55354:98;:::o;48486:147::-;48623:6;48486:147;;;;;:::o;42535:689::-;42666:19;42672:2;42676:8;42666:5;:19::i;:::-;42745:1;42727:2;:14;;;:19;42723:483;;42767:11;42781:13;;42767:27;;42813:13;42835:8;42829:3;:14;42813:30;;42862:233;42893:62;42932:1;42936:2;42940:7;;;;;;42949:5;42893:30;:62::i;:::-;42888:167;;42991:40;;;;;;;;;;;;;;42888:167;43090:3;43082:5;:11;42862:233;;43177:3;43160:13;;:20;43156:34;;43182:8;;;43156:34;42748:458;;42723:483;42535:689;;;:::o;36817:2966::-;36890:20;36913:13;;36890:36;;36953:1;36941:8;:13;36937:44;;36963:18;;;;;;;;;;;;;;36937:44;36994:61;37024:1;37028:2;37032:12;37046:8;36994:21;:61::i;:::-;37538:1;10538:2;37508:1;:26;;37507:32;37495:8;:45;37469:18;:22;37488:2;37469:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;37817:139;37854:2;37908:33;37931:1;37935:2;37939:1;37908:14;:33::i;:::-;37875:30;37896:8;37875:20;:30::i;:::-;:66;37817:18;:139::i;:::-;37783:17;:31;37801:12;37783:31;;;;;;;;;;;:173;;;;37973:16;38004:11;38033:8;38018:12;:23;38004:37;;38554:16;38550:2;38546:25;38534:37;;38926:12;38886:8;38845:1;38783:25;38724:1;38663;38636:335;39297:1;39283:12;39279:20;39237:346;39338:3;39329:7;39326:16;39237:346;;39556:7;39546:8;39543:1;39516:25;39513:1;39510;39505:59;39391:1;39382:7;39378:15;39367:26;;39237:346;;;39241:77;39628:1;39616:8;:13;39612:45;;39638:19;;;;;;;;;;;;;;39612:45;39690:3;39674:13;:19;;;;37243:2462;;39715:60;39744:1;39748:2;39752:12;39766:8;39715:20;:60::i;:::-;36879:2904;36817:2966;;:::o;24229:324::-;24299:14;24532:1;24522:8;24519:15;24493:24;24489:46;24479:56;;24229:324;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:77::-;1555:7;1584:5;1573:16;;1518:77;;;:::o;1601:118::-;1688:24;1706:5;1688:24;:::i;:::-;1683:3;1676:37;1601:118;;:::o;1725:222::-;1818:4;1856:2;1845:9;1841:18;1833:26;;1869:71;1937:1;1926:9;1922:17;1913:6;1869:71;:::i;:::-;1725:222;;;;:::o;1953:126::-;1990:7;2030:42;2023:5;2019:54;2008:65;;1953:126;;;:::o;2085:96::-;2122:7;2151:24;2169:5;2151:24;:::i;:::-;2140:35;;2085:96;;;:::o;2187:122::-;2260:24;2278:5;2260:24;:::i;:::-;2253:5;2250:35;2240:63;;2299:1;2296;2289:12;2240:63;2187:122;:::o;2315:139::-;2361:5;2399:6;2386:20;2377:29;;2415:33;2442:5;2415:33;:::i;:::-;2315:139;;;;:::o;2460:329::-;2519:6;2568:2;2556:9;2547:7;2543:23;2539:32;2536:119;;;2574:79;;:::i;:::-;2536:119;2694:1;2719:53;2764:7;2755:6;2744:9;2740:22;2719:53;:::i;:::-;2709:63;;2665:117;2460:329;;;;:::o;2795:99::-;2847:6;2881:5;2875:12;2865:22;;2795:99;;;:::o;2900:169::-;2984:11;3018:6;3013:3;3006:19;3058:4;3053:3;3049:14;3034:29;;2900:169;;;;:::o;3075:246::-;3156:1;3166:113;3180:6;3177:1;3174:13;3166:113;;;3265:1;3260:3;3256:11;3250:18;3246:1;3241:3;3237:11;3230:39;3202:2;3199:1;3195:10;3190:15;;3166:113;;;3313:1;3304:6;3299:3;3295:16;3288:27;3137:184;3075:246;;;:::o;3327:102::-;3368:6;3419:2;3415:7;3410:2;3403:5;3399:14;3395:28;3385:38;;3327:102;;;:::o;3435:377::-;3523:3;3551:39;3584:5;3551:39;:::i;:::-;3606:71;3670:6;3665:3;3606:71;:::i;:::-;3599:78;;3686:65;3744:6;3739:3;3732:4;3725:5;3721:16;3686:65;:::i;:::-;3776:29;3798:6;3776:29;:::i;:::-;3771:3;3767:39;3760:46;;3527:285;3435:377;;;;:::o;3818:313::-;3931:4;3969:2;3958:9;3954:18;3946:26;;4018:9;4012:4;4008:20;4004:1;3993:9;3989:17;3982:47;4046:78;4119:4;4110:6;4046:78;:::i;:::-;4038:86;;3818:313;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:329::-;4469:6;4518:2;4506:9;4497:7;4493:23;4489:32;4486:119;;;4524:79;;:::i;:::-;4486:119;4644:1;4669:53;4714:7;4705:6;4694:9;4690:22;4669:53;:::i;:::-;4659:63;;4615:117;4410:329;;;;:::o;4745:118::-;4832:24;4850:5;4832:24;:::i;:::-;4827:3;4820:37;4745:118;;:::o;4869:222::-;4962:4;5000:2;4989:9;4985:18;4977:26;;5013:71;5081:1;5070:9;5066:17;5057:6;5013:71;:::i;:::-;4869:222;;;;:::o;5097:474::-;5165:6;5173;5222:2;5210:9;5201:7;5197:23;5193:32;5190:119;;;5228:79;;:::i;:::-;5190:119;5348:1;5373:53;5418:7;5409:6;5398:9;5394:22;5373:53;:::i;:::-;5363:63;;5319:117;5475:2;5501:53;5546:7;5537:6;5526:9;5522:22;5501:53;:::i;:::-;5491:63;;5446:118;5097:474;;;;;:::o;5577:619::-;5654:6;5662;5670;5719:2;5707:9;5698:7;5694:23;5690:32;5687:119;;;5725:79;;:::i;:::-;5687:119;5845:1;5870:53;5915:7;5906:6;5895:9;5891:22;5870:53;:::i;:::-;5860:63;;5816:117;5972:2;5998:53;6043:7;6034:6;6023:9;6019:22;5998:53;:::i;:::-;5988:63;;5943:118;6100:2;6126:53;6171:7;6162:6;6151:9;6147:22;6126:53;:::i;:::-;6116:63;;6071:118;5577:619;;;;;:::o;6202:117::-;6311:1;6308;6301:12;6325:117;6434:1;6431;6424:12;6448:180;6496:77;6493:1;6486:88;6593:4;6590:1;6583:15;6617:4;6614:1;6607:15;6634:281;6717:27;6739:4;6717:27;:::i;:::-;6709:6;6705:40;6847:6;6835:10;6832:22;6811:18;6799:10;6796:34;6793:62;6790:88;;;6858:18;;:::i;:::-;6790:88;6898:10;6894:2;6887:22;6677:238;6634:281;;:::o;6921:129::-;6955:6;6982:20;;:::i;:::-;6972:30;;7011:33;7039:4;7031:6;7011:33;:::i;:::-;6921:129;;;:::o;7056:308::-;7118:4;7208:18;7200:6;7197:30;7194:56;;;7230:18;;:::i;:::-;7194:56;7268:29;7290:6;7268:29;:::i;:::-;7260:37;;7352:4;7346;7342:15;7334:23;;7056:308;;;:::o;7370:146::-;7467:6;7462:3;7457;7444:30;7508:1;7499:6;7494:3;7490:16;7483:27;7370:146;;;:::o;7522:425::-;7600:5;7625:66;7641:49;7683:6;7641:49;:::i;:::-;7625:66;:::i;:::-;7616:75;;7714:6;7707:5;7700:21;7752:4;7745:5;7741:16;7790:3;7781:6;7776:3;7772:16;7769:25;7766:112;;;7797:79;;:::i;:::-;7766:112;7887:54;7934:6;7929:3;7924;7887:54;:::i;:::-;7606:341;7522:425;;;;;:::o;7967:340::-;8023:5;8072:3;8065:4;8057:6;8053:17;8049:27;8039:122;;8080:79;;:::i;:::-;8039:122;8197:6;8184:20;8222:79;8297:3;8289:6;8282:4;8274:6;8270:17;8222:79;:::i;:::-;8213:88;;8029:278;7967:340;;;;:::o;8313:509::-;8382:6;8431:2;8419:9;8410:7;8406:23;8402:32;8399:119;;;8437:79;;:::i;:::-;8399:119;8585:1;8574:9;8570:17;8557:31;8615:18;8607:6;8604:30;8601:117;;;8637:79;;:::i;:::-;8601:117;8742:63;8797:7;8788:6;8777:9;8773:22;8742:63;:::i;:::-;8732:73;;8528:287;8313:509;;;;:::o;8828:116::-;8898:21;8913:5;8898:21;:::i;:::-;8891:5;8888:32;8878:60;;8934:1;8931;8924:12;8878:60;8828:116;:::o;8950:133::-;8993:5;9031:6;9018:20;9009:29;;9047:30;9071:5;9047:30;:::i;:::-;8950:133;;;;:::o;9089:468::-;9154:6;9162;9211:2;9199:9;9190:7;9186:23;9182:32;9179:119;;;9217:79;;:::i;:::-;9179:119;9337:1;9362:53;9407:7;9398:6;9387:9;9383:22;9362:53;:::i;:::-;9352:63;;9308:117;9464:2;9490:50;9532:7;9523:6;9512:9;9508:22;9490:50;:::i;:::-;9480:60;;9435:115;9089:468;;;;;:::o;9563:307::-;9624:4;9714:18;9706:6;9703:30;9700:56;;;9736:18;;:::i;:::-;9700:56;9774:29;9796:6;9774:29;:::i;:::-;9766:37;;9858:4;9852;9848:15;9840:23;;9563:307;;;:::o;9876:423::-;9953:5;9978:65;9994:48;10035:6;9994:48;:::i;:::-;9978:65;:::i;:::-;9969:74;;10066:6;10059:5;10052:21;10104:4;10097:5;10093:16;10142:3;10133:6;10128:3;10124:16;10121:25;10118:112;;;10149:79;;:::i;:::-;10118:112;10239:54;10286:6;10281:3;10276;10239:54;:::i;:::-;9959:340;9876:423;;;;;:::o;10318:338::-;10373:5;10422:3;10415:4;10407:6;10403:17;10399:27;10389:122;;10430:79;;:::i;:::-;10389:122;10547:6;10534:20;10572:78;10646:3;10638:6;10631:4;10623:6;10619:17;10572:78;:::i;:::-;10563:87;;10379:277;10318:338;;;;:::o;10662:943::-;10757:6;10765;10773;10781;10830:3;10818:9;10809:7;10805:23;10801:33;10798:120;;;10837:79;;:::i;:::-;10798:120;10957:1;10982:53;11027:7;11018:6;11007:9;11003:22;10982:53;:::i;:::-;10972:63;;10928:117;11084:2;11110:53;11155:7;11146:6;11135:9;11131:22;11110:53;:::i;:::-;11100:63;;11055:118;11212:2;11238:53;11283:7;11274:6;11263:9;11259:22;11238:53;:::i;:::-;11228:63;;11183:118;11368:2;11357:9;11353:18;11340:32;11399:18;11391:6;11388:30;11385:117;;;11421:79;;:::i;:::-;11385:117;11526:62;11580:7;11571:6;11560:9;11556:22;11526:62;:::i;:::-;11516:72;;11311:287;10662:943;;;;;;;:::o;11611:474::-;11679:6;11687;11736:2;11724:9;11715:7;11711:23;11707:32;11704:119;;;11742:79;;:::i;:::-;11704:119;11862:1;11887:53;11932:7;11923:6;11912:9;11908:22;11887:53;:::i;:::-;11877:63;;11833:117;11989:2;12015:53;12060:7;12051:6;12040:9;12036:22;12015:53;:::i;:::-;12005:63;;11960:118;11611:474;;;;;:::o;12091:180::-;12139:77;12136:1;12129:88;12236:4;12233:1;12226:15;12260:4;12257:1;12250:15;12277:320;12321:6;12358:1;12352:4;12348:12;12338:22;;12405:1;12399:4;12395:12;12426:18;12416:81;;12482:4;12474:6;12470:17;12460:27;;12416:81;12544:2;12536:6;12533:14;12513:18;12510:38;12507:84;;12563:18;;:::i;:::-;12507:84;12328:269;12277:320;;;:::o;12603:222::-;12743:34;12739:1;12731:6;12727:14;12720:58;12812:5;12807:2;12799:6;12795:15;12788:30;12603:222;:::o;12831:366::-;12973:3;12994:67;13058:2;13053:3;12994:67;:::i;:::-;12987:74;;13070:93;13159:3;13070:93;:::i;:::-;13188:2;13183:3;13179:12;13172:19;;12831:366;;;:::o;13203:419::-;13369:4;13407:2;13396:9;13392:18;13384:26;;13456:9;13450:4;13446:20;13442:1;13431:9;13427:17;13420:47;13484:131;13610:4;13484:131;:::i;:::-;13476:139;;13203:419;;;:::o;13628:222::-;13768:34;13764:1;13756:6;13752:14;13745:58;13837:5;13832:2;13824:6;13820:15;13813:30;13628:222;:::o;13856:366::-;13998:3;14019:67;14083:2;14078:3;14019:67;:::i;:::-;14012:74;;14095:93;14184:3;14095:93;:::i;:::-;14213:2;14208:3;14204:12;14197:19;;13856:366;;;:::o;14228:419::-;14394:4;14432:2;14421:9;14417:18;14409:26;;14481:9;14475:4;14471:20;14467:1;14456:9;14452:17;14445:47;14509:131;14635:4;14509:131;:::i;:::-;14501:139;;14228:419;;;:::o;14653:180::-;14701:77;14698:1;14691:88;14798:4;14795:1;14788:15;14822:4;14819:1;14812:15;14839:191;14879:3;14898:20;14916:1;14898:20;:::i;:::-;14893:25;;14932:20;14950:1;14932:20;:::i;:::-;14927:25;;14975:1;14972;14968:9;14961:16;;14996:3;14993:1;14990:10;14987:36;;;15003:18;;:::i;:::-;14987:36;14839:191;;;;:::o;15036:166::-;15176:18;15172:1;15164:6;15160:14;15153:42;15036:166;:::o;15208:366::-;15350:3;15371:67;15435:2;15430:3;15371:67;:::i;:::-;15364:74;;15447:93;15536:3;15447:93;:::i;:::-;15565:2;15560:3;15556:12;15549:19;;15208:366;;;:::o;15580:419::-;15746:4;15784:2;15773:9;15769:18;15761:26;;15833:9;15827:4;15823:20;15819:1;15808:9;15804:17;15797:47;15861:131;15987:4;15861:131;:::i;:::-;15853:139;;15580:419;;;:::o;16005:410::-;16045:7;16068:20;16086:1;16068:20;:::i;:::-;16063:25;;16102:20;16120:1;16102:20;:::i;:::-;16097:25;;16157:1;16154;16150:9;16179:30;16197:11;16179:30;:::i;:::-;16168:41;;16358:1;16349:7;16345:15;16342:1;16339:22;16319:1;16312:9;16292:83;16269:139;;16388:18;;:::i;:::-;16269:139;16053:362;16005:410;;;;:::o;16421:194::-;16461:4;16481:20;16499:1;16481:20;:::i;:::-;16476:25;;16515:20;16533:1;16515:20;:::i;:::-;16510:25;;16559:1;16556;16552:9;16544:17;;16583:1;16577:4;16574:11;16571:37;;;16588:18;;:::i;:::-;16571:37;16421:194;;;;:::o;16621:176::-;16761:28;16757:1;16749:6;16745:14;16738:52;16621:176;:::o;16803:366::-;16945:3;16966:67;17030:2;17025:3;16966:67;:::i;:::-;16959:74;;17042:93;17131:3;17042:93;:::i;:::-;17160:2;17155:3;17151:12;17144:19;;16803:366;;;:::o;17175:419::-;17341:4;17379:2;17368:9;17364:18;17356:26;;17428:9;17422:4;17418:20;17414:1;17403:9;17399:17;17392:47;17456:131;17582:4;17456:131;:::i;:::-;17448:139;;17175:419;;;:::o;17600:141::-;17649:4;17672:3;17664:11;;17695:3;17692:1;17685:14;17729:4;17726:1;17716:18;17708:26;;17600:141;;;:::o;17747:93::-;17784:6;17831:2;17826;17819:5;17815:14;17811:23;17801:33;;17747:93;;;:::o;17846:107::-;17890:8;17940:5;17934:4;17930:16;17909:37;;17846:107;;;;:::o;17959:393::-;18028:6;18078:1;18066:10;18062:18;18101:97;18131:66;18120:9;18101:97;:::i;:::-;18219:39;18249:8;18238:9;18219:39;:::i;:::-;18207:51;;18291:4;18287:9;18280:5;18276:21;18267:30;;18340:4;18330:8;18326:19;18319:5;18316:30;18306:40;;18035:317;;17959:393;;;;;:::o;18358:60::-;18386:3;18407:5;18400:12;;18358:60;;;:::o;18424:142::-;18474:9;18507:53;18525:34;18534:24;18552:5;18534:24;:::i;:::-;18525:34;:::i;:::-;18507:53;:::i;:::-;18494:66;;18424:142;;;:::o;18572:75::-;18615:3;18636:5;18629:12;;18572:75;;;:::o;18653:269::-;18763:39;18794:7;18763:39;:::i;:::-;18824:91;18873:41;18897:16;18873:41;:::i;:::-;18865:6;18858:4;18852:11;18824:91;:::i;:::-;18818:4;18811:105;18729:193;18653:269;;;:::o;18928:73::-;18973:3;18928:73;:::o;19007:189::-;19084:32;;:::i;:::-;19125:65;19183:6;19175;19169:4;19125:65;:::i;:::-;19060:136;19007:189;;:::o;19202:186::-;19262:120;19279:3;19272:5;19269:14;19262:120;;;19333:39;19370:1;19363:5;19333:39;:::i;:::-;19306:1;19299:5;19295:13;19286:22;;19262:120;;;19202:186;;:::o;19394:543::-;19495:2;19490:3;19487:11;19484:446;;;19529:38;19561:5;19529:38;:::i;:::-;19613:29;19631:10;19613:29;:::i;:::-;19603:8;19599:44;19796:2;19784:10;19781:18;19778:49;;;19817:8;19802:23;;19778:49;19840:80;19896:22;19914:3;19896:22;:::i;:::-;19886:8;19882:37;19869:11;19840:80;:::i;:::-;19499:431;;19484:446;19394:543;;;:::o;19943:117::-;19997:8;20047:5;20041:4;20037:16;20016:37;;19943:117;;;;:::o;20066:169::-;20110:6;20143:51;20191:1;20187:6;20179:5;20176:1;20172:13;20143:51;:::i;:::-;20139:56;20224:4;20218;20214:15;20204:25;;20117:118;20066:169;;;;:::o;20240:295::-;20316:4;20462:29;20487:3;20481:4;20462:29;:::i;:::-;20454:37;;20524:3;20521:1;20517:11;20511:4;20508:21;20500:29;;20240:295;;;;:::o;20540:1395::-;20657:37;20690:3;20657:37;:::i;:::-;20759:18;20751:6;20748:30;20745:56;;;20781:18;;:::i;:::-;20745:56;20825:38;20857:4;20851:11;20825:38;:::i;:::-;20910:67;20970:6;20962;20956:4;20910:67;:::i;:::-;21004:1;21028:4;21015:17;;21060:2;21052:6;21049:14;21077:1;21072:618;;;;21734:1;21751:6;21748:77;;;21800:9;21795:3;21791:19;21785:26;21776:35;;21748:77;21851:67;21911:6;21904:5;21851:67;:::i;:::-;21845:4;21838:81;21707:222;21042:887;;21072:618;21124:4;21120:9;21112:6;21108:22;21158:37;21190:4;21158:37;:::i;:::-;21217:1;21231:208;21245:7;21242:1;21239:14;21231:208;;;21324:9;21319:3;21315:19;21309:26;21301:6;21294:42;21375:1;21367:6;21363:14;21353:24;;21422:2;21411:9;21407:18;21394:31;;21268:4;21265:1;21261:12;21256:17;;21231:208;;;21467:6;21458:7;21455:19;21452:179;;;21525:9;21520:3;21516:19;21510:26;21568:48;21610:4;21602:6;21598:17;21587:9;21568:48;:::i;:::-;21560:6;21553:64;21475:156;21452:179;21677:1;21673;21665:6;21661:14;21657:22;21651:4;21644:36;21079:611;;;21042:887;;20632:1303;;;20540:1395;;:::o;21941:148::-;22043:11;22080:3;22065:18;;21941:148;;;;:::o;22095:390::-;22201:3;22229:39;22262:5;22229:39;:::i;:::-;22284:89;22366:6;22361:3;22284:89;:::i;:::-;22277:96;;22382:65;22440:6;22435:3;22428:4;22421:5;22417:16;22382:65;:::i;:::-;22472:6;22467:3;22463:16;22456:23;;22205:280;22095:390;;;;:::o;22491:435::-;22671:3;22693:95;22784:3;22775:6;22693:95;:::i;:::-;22686:102;;22805:95;22896:3;22887:6;22805:95;:::i;:::-;22798:102;;22917:3;22910:10;;22491:435;;;;;:::o;22932:225::-;23072:34;23068:1;23060:6;23056:14;23049:58;23141:8;23136:2;23128:6;23124:15;23117:33;22932:225;:::o;23163:366::-;23305:3;23326:67;23390:2;23385:3;23326:67;:::i;:::-;23319:74;;23402:93;23491:3;23402:93;:::i;:::-;23520:2;23515:3;23511:12;23504:19;;23163:366;;;:::o;23535:419::-;23701:4;23739:2;23728:9;23724:18;23716:26;;23788:9;23782:4;23778:20;23774:1;23763:9;23759:17;23752:47;23816:131;23942:4;23816:131;:::i;:::-;23808:139;;23535:419;;;:::o;23960:182::-;24100:34;24096:1;24088:6;24084:14;24077:58;23960:182;:::o;24148:366::-;24290:3;24311:67;24375:2;24370:3;24311:67;:::i;:::-;24304:74;;24387:93;24476:3;24387:93;:::i;:::-;24505:2;24500:3;24496:12;24489:19;;24148:366;;;:::o;24520:419::-;24686:4;24724:2;24713:9;24709:18;24701:26;;24773:9;24767:4;24763:20;24759:1;24748:9;24744:17;24737:47;24801:131;24927:4;24801:131;:::i;:::-;24793:139;;24520:419;;;:::o;24945:98::-;24996:6;25030:5;25024:12;25014:22;;24945:98;;;:::o;25049:168::-;25132:11;25166:6;25161:3;25154:19;25206:4;25201:3;25197:14;25182:29;;25049:168;;;;:::o;25223:373::-;25309:3;25337:38;25369:5;25337:38;:::i;:::-;25391:70;25454:6;25449:3;25391:70;:::i;:::-;25384:77;;25470:65;25528:6;25523:3;25516:4;25509:5;25505:16;25470:65;:::i;:::-;25560:29;25582:6;25560:29;:::i;:::-;25555:3;25551:39;25544:46;;25313:283;25223:373;;;;:::o;25602:640::-;25797:4;25835:3;25824:9;25820:19;25812:27;;25849:71;25917:1;25906:9;25902:17;25893:6;25849:71;:::i;:::-;25930:72;25998:2;25987:9;25983:18;25974:6;25930:72;:::i;:::-;26012;26080:2;26069:9;26065:18;26056:6;26012:72;:::i;:::-;26131:9;26125:4;26121:20;26116:2;26105:9;26101:18;26094:48;26159:76;26230:4;26221:6;26159:76;:::i;:::-;26151:84;;25602:640;;;;;;;:::o;26248:141::-;26304:5;26335:6;26329:13;26320:22;;26351:32;26377:5;26351:32;:::i;:::-;26248:141;;;;:::o;26395:349::-;26464:6;26513:2;26501:9;26492:7;26488:23;26484:32;26481:119;;;26519:79;;:::i;:::-;26481:119;26639:1;26664:63;26719:7;26710:6;26699:9;26695:22;26664:63;:::i;:::-;26654:73;;26610:127;26395:349;;;;:::o

Swarm Source

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