ETH Price: $3,138.24 (-5.33%)
 

Overview

Max Total Supply

608 SC

Holders

110

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
gethype.eth
Balance
1 SC
0x6984abf56f07a9b77f9c86505662df02abd18ca9
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:
ShamiCrystals

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 400 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-04-03
*/

// 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/security/Pausable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        _requireNotPaused();
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        _requirePaused();
        _;
    }

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

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        require(!paused(), "Pausable: paused");
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        require(paused(), "Pausable: not paused");
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

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


// OpenZeppelin Contracts (last updated v4.7.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 anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

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

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

// File: 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: erc721a/contracts/extensions/IERC721AQueryable.sol


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

pragma solidity ^0.8.4;


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

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

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

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

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

// File: erc721a/contracts/extensions/ERC721AQueryable.sol


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

pragma solidity ^0.8.4;



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

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

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

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

// File: @openzeppelin/contracts/utils/structs/EnumerableSet.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 *
 * [WARNING]
 * ====
 * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
 * unusable.
 * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
 * array of EnumerableSet.
 * ====
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

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

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

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

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

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

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

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

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

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

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

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

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

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

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

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

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

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

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

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

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

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

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

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

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

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

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

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

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

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

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

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

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }
}

// File: contracts/IOperatorFilterRegistry.sol


pragma solidity ^0.8.13;


interface IOperatorFilterRegistry {
    function isOperatorAllowed(address registrant, address operator) external returns (bool);
    function register(address registrant) external;
    function registerAndSubscribe(address registrant, address subscription) external;
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;
    function updateOperator(address registrant, address operator, bool filtered) external;
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;
    function subscribe(address registrant, address registrantToSubscribe) external;
    function unsubscribe(address registrant, bool copyExistingEntries) external;
    function subscriptionOf(address addr) external returns (address registrant);
    function subscribers(address registrant) external returns (address[] memory);
    function subscriberAt(address registrant, uint256 index) external returns (address);
    function copyEntriesOf(address registrant, address registrantToCopy) external;
    function isOperatorFiltered(address registrant, address operator) external returns (bool);
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);
    function filteredOperators(address addr) external returns (address[] memory);
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);
    function isRegistered(address addr) external returns (bool);
    function codeHashOf(address addr) external returns (bytes32);
}
// File: contracts/OperatorFilterer.sol


pragma solidity ^0.8.13;


abstract contract OperatorFilterer {
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry constant operatorFilterRegistry =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

    constructor(address subscriptionOrRegistrantToCopy, bool subscribe) {
        // If an inheriting token contract is deployed to a network without the registry deployed, the modifier
        // will not revert, but the contract will need to be registered with the registry once it is deployed in
        // order for the modifier to filter addresses.
        if (address(operatorFilterRegistry).code.length > 0) {
            if (subscribe) {
                operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
            } else {
                if (subscriptionOrRegistrantToCopy != address(0)) {
                    operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
                } else {
                    operatorFilterRegistry.register(address(this));
                }
            }
        }
    }

    modifier onlyAllowedOperator(address from) virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(operatorFilterRegistry).code.length > 0) {
            // Allow spending tokens from addresses with balance
            // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
            // from an EOA.
            if (from == msg.sender) {
                _;
                return;
            }
            if (
                !(
                    operatorFilterRegistry.isOperatorAllowed(address(this), msg.sender)
                        && operatorFilterRegistry.isOperatorAllowed(address(this), from)
                )
            ) {
                revert OperatorNotAllowed(msg.sender);
            }
        }
        _;
    }
}
// File: contracts/DefaultOperatorFilterer.sol


pragma solidity ^0.8.13;


contract DefaultOperatorFilterer is OperatorFilterer {
    address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

    constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {}
}
// File: contracts/shami.sol


pragma solidity ^0.8.13;





contract ShamiCrystals is ERC721AQueryable, DefaultOperatorFilterer, Ownable, Pausable {
    
    uint256 public MAX_MINTS = 5000;
    uint256 public MAX_SUPPLY = 5000;
    uint256 public price = 0.018 ether;
    
    string public baseURI;

    // Dev info          
    address public dev = 0x1234cdF2D2dC0F3337DBF5128F934f1Ae9286E4c;
    uint256 public devCut = 10;//%

    uint256 public mintCounter = 0;
    uint256 public airDropCounter = 0;

    constructor() ERC721A("Shami Crystals", "SC") {}

    function mint(uint256 quantity) external payable whenNotPaused {
        require(quantity + _numberMinted(msg.sender) <= MAX_MINTS, "mint: Exceeded the limit per wallet");
        require(totalSupply() + quantity <= MAX_SUPPLY, "mint: Not enough tokens left");
        require(msg.value >= (price * quantity), "mint: Not enough ether sent");

        mintCounter += quantity;
        _safeMint(msg.sender, quantity);
    }

    function airDrop(address[] calldata addrs, uint256 quantity) external onlyOwner {
        uint256 len = addrs.length;
        require(totalSupply() + (quantity * len) <= MAX_SUPPLY, "airDrop: Not enough tokens to airdrop");
        airDropCounter += quantity * len;
        for (uint256 i = 0; i < len; i++) {
            _safeMint(addrs[i], quantity);
        }
    }

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

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

    function transferFrom(address from, address to, uint256 tokenId)
        public
        payable
        override(ERC721A, IERC721A)
        onlyAllowedOperator(from)
    {
        super.transferFrom(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId)
        public
        payable
        override(ERC721A, IERC721A)
        onlyAllowedOperator(from)
    {
        super.safeTransferFrom(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data)
        public
        payable
        override(ERC721A, IERC721A)
        onlyAllowedOperator(from)
    {
        super.safeTransferFrom(from, to, tokenId, data);
    }

    function setPrice(uint256 _price) external onlyOwner {
        price = _price;
    }

    function setMaxMint(uint256 _max) external onlyOwner {
        MAX_MINTS = _max;
    }

    function toggleAllMintPause() public onlyOwner {
        paused() ? _unpause() : _pause();
    }

    function setBaseURI(string memory _uri) external onlyOwner {
        baseURI = _uri;
    }

    function updateMaxSupply(uint256 _max) external onlyOwner {
        MAX_SUPPLY = _max;
    }

    function updateDevWallet(address _dev) external {
        require(msg.sender == dev, "updateDevWallet: Sender is not dev");
        dev = _dev;
    }

    function withdraw() external onlyOwner {
        require(address(this).balance > 0, "withdraw: contract balance must be greater than 0"); 
        uint256 balance = address(this).balance;
        uint256 ownerBal = ((balance * (100 - devCut)) / 100);
        uint256 devBal = ((balance * (devCut)) / 100);
        payable(msg.sender).transfer(ownerBal);
        payable(dev).transfer(devBal);
    }

}

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":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"MAX_MINTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"addrs","type":"address[]"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"airDrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"airDropCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dev","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"devCut","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"explicitOwnershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"explicitOwnershipsOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"_uri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_max","type":"uint256"}],"name":"setMaxMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setPrice","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":[],"name":"toggleAllMintPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_dev","type":"address"}],"name":"updateDevWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_max","type":"uint256"}],"name":"updateMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526113886009819055600a908155663ff2e795f50000600b55600d80546001600160a01b031916731234cdf2d2dc0f3337dbf5128f934f1ae9286e4c179055600e556000600f8190556010553480156200005c57600080fd5b50733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600e81526020016d5368616d69204372797374616c7360901b81525060405180604001604052806002815260200161534360f01b8152508160029080519060200190620000ce929190620002a4565b508051620000e4906003906020840190620002a4565b50600160005550506daaeb6d7670e522a718067333cd4e3b15620002315780156200017f57604051633e9f1edf60e11b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b600060405180830381600087803b1580156200016057600080fd5b505af115801562000175573d6000803e3d6000fd5b5050505062000231565b6001600160a01b03821615620001d05760405163a0af290360e01b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e9063a0af29039060440162000145565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b1580156200021757600080fd5b505af11580156200022c573d6000803e3d6000fd5b505050505b506200023f90503362000252565b6008805460ff60a01b1916905562000386565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b828054620002b2906200034a565b90600052602060002090601f016020900481019282620002d6576000855562000321565b82601f10620002f157805160ff191683800117855562000321565b8280016001018555821562000321579182015b828111156200032157825182559160200191906001019062000304565b506200032f92915062000333565b5090565b5b808211156200032f576000815560010162000334565b600181811c908216806200035f57607f821691505b6020821081036200038057634e487b7160e01b600052602260045260246000fd5b50919050565b61277c80620003966000396000f3fe6080604052600436106102305760003560e01c8063715018a61161012e578063a0712d68116100ab578063cce132d11161006f578063cce132d114610627578063e985e9c51461063d578063f103b43314610686578063f2fde38b146106a6578063fd1fc4a0146106c657600080fd5b8063a0712d6814610594578063a22cb465146105a7578063b88d4fde146105c7578063c23dc68f146105da578063c87b56dd1461060757600080fd5b806391cca3db116100f257806391cca3db1461051357806395d89b411461053357806399a2557a146105485780639c28683714610568578063a035b1fe1461057e57600080fd5b8063715018a61461047d57806373be8f92146104925780638462151c146104a85780638da5cb5b146104d557806391b7f5ed146104f357600080fd5b80633ccfd60b116101bc5780635bbb2177116101805780635bbb2177146103dc5780635c975abb146104095780636352211e146104285780636c0360eb1461044857806370a082311461045d57600080fd5b80633ccfd60b1461035e57806342842e0e1461037357806346aa52ce14610386578063547520fe1461039c57806355f804b3146103bc57600080fd5b806318160ddd1161020357806318160ddd146102d95780631816467f1461030057806323b872dd14610320578063274a32d31461033357806332cb6b0c1461034857600080fd5b806301ffc9a71461023557806306fdde031461026a578063081812fc1461028c578063095ea7b3146102c4575b600080fd5b34801561024157600080fd5b506102556102503660046120a4565b6106e6565b60405190151581526020015b60405180910390f35b34801561027657600080fd5b5061027f610738565b6040516102619190612119565b34801561029857600080fd5b506102ac6102a736600461212c565b6107ca565b6040516001600160a01b039091168152602001610261565b6102d76102d2366004612161565b61080e565b005b3480156102e557600080fd5b5060015460005403600019015b604051908152602001610261565b34801561030c57600080fd5b506102d761031b36600461218b565b6108ae565b6102d761032e3660046121a6565b61093a565b34801561033f57600080fd5b506102d7610a9a565b34801561035457600080fd5b506102f2600a5481565b34801561036a57600080fd5b506102d7610ac5565b6102d76103813660046121a6565b610bf5565b34801561039257600080fd5b506102f2600f5481565b3480156103a857600080fd5b506102d76103b736600461212c565b610d4a565b3480156103c857600080fd5b506102d76103d736600461226e565b610d57565b3480156103e857600080fd5b506103fc6103f7366004612303565b610d76565b6040516102619190612345565b34801561041557600080fd5b50600854600160a01b900460ff16610255565b34801561043457600080fd5b506102ac61044336600461212c565b610e42565b34801561045457600080fd5b5061027f610e4d565b34801561046957600080fd5b506102f261047836600461218b565b610edb565b34801561048957600080fd5b506102d7610f2a565b34801561049e57600080fd5b506102f260105481565b3480156104b457600080fd5b506104c86104c336600461218b565b610f3c565b60405161026191906123c2565b3480156104e157600080fd5b506008546001600160a01b03166102ac565b3480156104ff57600080fd5b506102d761050e36600461212c565b611045565b34801561051f57600080fd5b50600d546102ac906001600160a01b031681565b34801561053f57600080fd5b5061027f611052565b34801561055457600080fd5b506104c86105633660046123fa565b611061565b34801561057457600080fd5b506102f2600e5481565b34801561058a57600080fd5b506102f2600b5481565b6102d76105a236600461212c565b6111e9565b3480156105b357600080fd5b506102d76105c236600461243b565b611360565b6102d76105d5366004612472565b6113cc565b3480156105e657600080fd5b506105fa6105f536600461212c565b61152f565b60405161026191906124ee565b34801561061357600080fd5b5061027f61062236600461212c565b6115b7565b34801561063357600080fd5b506102f260095481565b34801561064957600080fd5b50610255610658366004612533565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b34801561069257600080fd5b506102d76106a136600461212c565b61163a565b3480156106b257600080fd5b506102d76106c136600461218b565b611647565b3480156106d257600080fd5b506102d76106e1366004612566565b6116bd565b60006301ffc9a760e01b6001600160e01b03198316148061071757506380ac58cd60e01b6001600160e01b03198316145b806107325750635b5e139f60e01b6001600160e01b03198316145b92915050565b606060028054610747906125b2565b80601f0160208091040260200160405190810160405280929190818152602001828054610773906125b2565b80156107c05780601f10610795576101008083540402835291602001916107c0565b820191906000526020600020905b8154815290600101906020018083116107a357829003601f168201915b5050505050905090565b60006107d5826117b3565b6107f2576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b600061081982610e42565b9050336001600160a01b03821614610852576108358133610658565b610852576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600d546001600160a01b031633146109185760405162461bcd60e51b815260206004820152602260248201527f75706461746544657657616c6c65743a2053656e646572206973206e6f74206460448201526132bb60f11b60648201526084015b60405180910390fd5b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b826daaeb6d7670e522a718067333cd4e3b15610a8957336001600160a01b038216036109705761096b8484846117e8565b610a94565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c6171134906044016020604051808303816000875af11580156109c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e591906125ec565b8015610a6a5750604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c6171134906044016020604051808303816000875af1158015610a46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6a91906125ec565b610a8957604051633b79c77360e21b815233600482015260240161090f565b610a948484846117e8565b50505050565b610aa2611980565b600854600160a01b900460ff16610abd57610abb6119da565b565b610abb611a3a565b610acd611980565b60004711610b435760405162461bcd60e51b815260206004820152603160248201527f77697468647261773a20636f6e74726163742062616c616e6365206d7573742060448201527f62652067726561746572207468616e2030000000000000000000000000000000606482015260840161090f565b600e544790600090606490610b58908261261f565b610b629084612636565b610b6c9190612655565b905060006064600e5484610b809190612636565b610b8a9190612655565b604051909150339083156108fc029084906000818181858888f19350505050158015610bba573d6000803e3d6000fd5b50600d546040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015610a94573d6000803e3d6000fd5b826daaeb6d7670e522a718067333cd4e3b15610d3f57336001600160a01b03821603610c265761096b848484611a76565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c6171134906044016020604051808303816000875af1158015610c77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9b91906125ec565b8015610d205750604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c6171134906044016020604051808303816000875af1158015610cfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2091906125ec565b610d3f57604051633b79c77360e21b815233600482015260240161090f565b610a94848484611a76565b610d52611980565b600955565b610d5f611980565b8051610d7290600c906020840190611ff5565b5050565b60608160008167ffffffffffffffff811115610d9457610d946121e2565b604051908082528060200260200182016040528015610de657816020015b604080516080810182526000808252602080830182905292820181905260608201528252600019909201910181610db25790505b50905060005b828114610e3957610e14868683818110610e0857610e08612677565b9050602002013561152f565b828281518110610e2657610e26612677565b6020908102919091010152600101610dec565b50949350505050565b600061073282611a96565b600c8054610e5a906125b2565b80601f0160208091040260200160405190810160405280929190818152602001828054610e86906125b2565b8015610ed35780601f10610ea857610100808354040283529160200191610ed3565b820191906000526020600020905b815481529060010190602001808311610eb657829003601f168201915b505050505081565b60006001600160a01b038216610f04576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b031660009081526005602052604090205467ffffffffffffffff1690565b610f32611980565b610abb6000611b05565b60606000806000610f4c85610edb565b905060008167ffffffffffffffff811115610f6957610f696121e2565b604051908082528060200260200182016040528015610f92578160200160208202803683370190505b509050610fbf60408051608081018252600080825260208201819052918101829052606081019190915290565b60015b83861461103957610fd281611b57565b915081604001516110315781516001600160a01b031615610ff257815194505b876001600160a01b0316856001600160a01b031603611031578083878060010198508151811061102457611024612677565b6020026020010181815250505b600101610fc2565b50909695505050505050565b61104d611980565b600b55565b606060038054610747906125b2565b606081831061108357604051631960ccad60e11b815260040160405180910390fd5b60008061108f60005490565b9050600185101561109f57600194505b808411156110ab578093505b60006110b687610edb565b9050848610156110d557858503818110156110cf578091505b506110d9565b5060005b60008167ffffffffffffffff8111156110f4576110f46121e2565b60405190808252806020026020018201604052801561111d578160200160208202803683370190505b509050816000036111335793506111e292505050565b600061113e8861152f565b90506000816040015161114f575080515b885b8881141580156111615750848714155b156111d65761116f81611b57565b925082604001516111ce5782516001600160a01b03161561118f57825191505b8a6001600160a01b0316826001600160a01b0316036111ce57808488806001019950815181106111c1576111c1612677565b6020026020010181815250505b600101611151565b50505092835250909150505b9392505050565b6111f1611bd6565b60095433600090815260056020526040908190205461121b911c67ffffffffffffffff168361268d565b11156112755760405162461bcd60e51b815260206004820152602360248201527f6d696e743a20457863656564656420746865206c696d6974207065722077616c6044820152621b195d60ea1b606482015260840161090f565b600a546001546000548391900360001901611290919061268d565b11156112de5760405162461bcd60e51b815260206004820152601c60248201527f6d696e743a204e6f7420656e6f75676820746f6b656e73206c65667400000000604482015260640161090f565b80600b546112ec9190612636565b34101561133b5760405162461bcd60e51b815260206004820152601b60248201527f6d696e743a204e6f7420656e6f7567682065746865722073656e740000000000604482015260640161090f565b80600f600082825461134d919061268d565b9091555061135d90503382611c23565b50565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b836daaeb6d7670e522a718067333cd4e3b1561151c57336001600160a01b03821603611403576113fe85858585611c3d565b611528565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c6171134906044016020604051808303816000875af1158015611454573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147891906125ec565b80156114fd5750604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c6171134906044016020604051808303816000875af11580156114d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114fd91906125ec565b61151c57604051633b79c77360e21b815233600482015260240161090f565b61152885858585611c3d565b5050505050565b604080516080810182526000808252602082018190529181018290526060810191909152604080516080810182526000808252602082018190529181018290526060810191909152600183108061158857506000548310155b156115935792915050565b61159c83611b57565b90508060400151156115ae5792915050565b6111e283611c81565b60606115c2826117b3565b6115df57604051630a14c4b560e41b815260040160405180910390fd5b60006115e9611cf9565b9050805160000361160957604051806020016040528060008152506111e2565b8061161384611d08565b6040516020016116249291906126a5565b6040516020818303038152906040529392505050565b611642611980565b600a55565b61164f611980565b6001600160a01b0381166116b45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161090f565b61135d81611b05565b6116c5611980565b600a5482906116d48284612636565b60015460005403600019016116e9919061268d565b11156117455760405162461bcd60e51b815260206004820152602560248201527f61697244726f703a204e6f7420656e6f75676820746f6b656e7320746f20616960448201526407264726f760dc1b606482015260840161090f565b61174f8183612636565b60106000828254611760919061268d565b90915550600090505b81811015611528576117a185858381811061178657611786612677565b905060200201602081019061179b919061218b565b84611c23565b806117ab816126d4565b915050611769565b6000816001111580156117c7575060005482105b8015610732575050600090815260046020526040902054600160e01b161590565b60006117f382611a96565b9050836001600160a01b0316816001600160a01b0316146118265760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417611873576118568633610658565b61187357604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b03851661189a57604051633a954ecd60e21b815260040160405180910390fd5b80156118a557600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260046020526040812091909155600160e11b84169003611937576001840160008181526004602052604081205490036119355760005481146119355760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b6008546001600160a01b03163314610abb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090f565b6119e2611bd6565b6008805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611a1d3390565b6040516001600160a01b03909116815260200160405180910390a1565b611a42611d4c565b6008805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33611a1d565b611a91838383604051806020016040528060008152506113cc565b505050565b60008180600111611aec57600054811015611aec5760008181526004602052604081205490600160e01b82169003611aea575b806000036111e2575060001901600081815260046020526040902054611ac9565b505b604051636f96cda160e11b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60408051608081018252600080825260208201819052918101829052606081019190915260008281526004602052604090205461073290604080516080810182526001600160a01b038316815260a083901c67ffffffffffffffff166020820152600160e01b831615159181019190915260e89190911c606082015290565b600854600160a01b900460ff1615610abb5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161090f565b610d72828260405180602001604052806000815250611da5565b611c4884848461093a565b6001600160a01b0383163b15610a9457611c6484848484611e0b565b610a94576040516368d2bf6b60e11b815260040160405180910390fd5b604080516080810182526000808252602082018190529181018290526060810191909152610732611cb183611a96565b604080516080810182526001600160a01b038316815260a083901c67ffffffffffffffff166020820152600160e01b831615159181019190915260e89190911c606082015290565b6060600c8054610747906125b2565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a900480611d225750819003601f19909101908152919050565b600854600160a01b900460ff16610abb5760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161090f565b611daf8383611ef7565b6001600160a01b0383163b15611a91576000548281035b611dd96000868380600101945086611e0b565b611df6576040516368d2bf6b60e11b815260040160405180910390fd5b818110611dc657816000541461152857600080fd5b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290611e409033908990889088906004016126ed565b6020604051808303816000875af1925050508015611e7b575060408051601f3d908101601f19168201909252611e7891810190612729565b60015b611ed9573d808015611ea9576040519150601f19603f3d011682016040523d82523d6000602084013e611eae565b606091505b508051600003611ed1576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b6000805490829003611f1c5760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b03831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b818114611fcb57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101611f93565b5081600003611fec57604051622e076360e81b815260040160405180910390fd5b60005550505050565b828054612001906125b2565b90600052602060002090601f0160209004810192826120235760008555612069565b82601f1061203c57805160ff1916838001178555612069565b82800160010185558215612069579182015b8281111561206957825182559160200191906001019061204e565b50612075929150612079565b5090565b5b80821115612075576000815560010161207a565b6001600160e01b03198116811461135d57600080fd5b6000602082840312156120b657600080fd5b81356111e28161208e565b60005b838110156120dc5781810151838201526020016120c4565b83811115610a945750506000910152565b600081518084526121058160208601602086016120c1565b601f01601f19169290920160200192915050565b6020815260006111e260208301846120ed565b60006020828403121561213e57600080fd5b5035919050565b80356001600160a01b038116811461215c57600080fd5b919050565b6000806040838503121561217457600080fd5b61217d83612145565b946020939093013593505050565b60006020828403121561219d57600080fd5b6111e282612145565b6000806000606084860312156121bb57600080fd5b6121c484612145565b92506121d260208501612145565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115612213576122136121e2565b604051601f8501601f19908116603f0116810190828211818310171561223b5761223b6121e2565b8160405280935085815286868601111561225457600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561228057600080fd5b813567ffffffffffffffff81111561229757600080fd5b8201601f810184136122a857600080fd5b611eef848235602084016121f8565b60008083601f8401126122c957600080fd5b50813567ffffffffffffffff8111156122e157600080fd5b6020830191508360208260051b85010111156122fc57600080fd5b9250929050565b6000806020838503121561231657600080fd5b823567ffffffffffffffff81111561232d57600080fd5b612339858286016122b7565b90969095509350505050565b6020808252825182820181905260009190848201906040850190845b81811015611039576123af8385516001600160a01b03815116825267ffffffffffffffff602082015116602083015260408101511515604083015262ffffff60608201511660608301525050565b9284019260809290920191600101612361565b6020808252825182820181905260009190848201906040850190845b81811015611039578351835292840192918401916001016123de565b60008060006060848603121561240f57600080fd5b61241884612145565b95602085013595506040909401359392505050565b801515811461135d57600080fd5b6000806040838503121561244e57600080fd5b61245783612145565b915060208301356124678161242d565b809150509250929050565b6000806000806080858703121561248857600080fd5b61249185612145565b935061249f60208601612145565b925060408501359150606085013567ffffffffffffffff8111156124c257600080fd5b8501601f810187136124d357600080fd5b6124e2878235602084016121f8565b91505092959194509250565b81516001600160a01b0316815260208083015167ffffffffffffffff169082015260408083015115159082015260608083015162ffffff169082015260808101610732565b6000806040838503121561254657600080fd5b61254f83612145565b915061255d60208401612145565b90509250929050565b60008060006040848603121561257b57600080fd5b833567ffffffffffffffff81111561259257600080fd5b61259e868287016122b7565b909790965060209590950135949350505050565b600181811c908216806125c657607f821691505b6020821081036125e657634e487b7160e01b600052602260045260246000fd5b50919050565b6000602082840312156125fe57600080fd5b81516111e28161242d565b634e487b7160e01b600052601160045260246000fd5b60008282101561263157612631612609565b500390565b600081600019048311821515161561265057612650612609565b500290565b60008261267257634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b600082198211156126a0576126a0612609565b500190565b600083516126b78184602088016120c1565b8351908301906126cb8183602088016120c1565b01949350505050565b6000600182016126e6576126e6612609565b5060010190565b60006001600160a01b0380871683528086166020840152508360408301526080606083015261271f60808301846120ed565b9695505050505050565b60006020828403121561273b57600080fd5b81516111e28161208e56fea2646970667358221220bed620996bd1aad4b311bfe810756c39062cdfca764a6ed30d98ba8dade0714564736f6c634300080d0033

Deployed Bytecode

0x6080604052600436106102305760003560e01c8063715018a61161012e578063a0712d68116100ab578063cce132d11161006f578063cce132d114610627578063e985e9c51461063d578063f103b43314610686578063f2fde38b146106a6578063fd1fc4a0146106c657600080fd5b8063a0712d6814610594578063a22cb465146105a7578063b88d4fde146105c7578063c23dc68f146105da578063c87b56dd1461060757600080fd5b806391cca3db116100f257806391cca3db1461051357806395d89b411461053357806399a2557a146105485780639c28683714610568578063a035b1fe1461057e57600080fd5b8063715018a61461047d57806373be8f92146104925780638462151c146104a85780638da5cb5b146104d557806391b7f5ed146104f357600080fd5b80633ccfd60b116101bc5780635bbb2177116101805780635bbb2177146103dc5780635c975abb146104095780636352211e146104285780636c0360eb1461044857806370a082311461045d57600080fd5b80633ccfd60b1461035e57806342842e0e1461037357806346aa52ce14610386578063547520fe1461039c57806355f804b3146103bc57600080fd5b806318160ddd1161020357806318160ddd146102d95780631816467f1461030057806323b872dd14610320578063274a32d31461033357806332cb6b0c1461034857600080fd5b806301ffc9a71461023557806306fdde031461026a578063081812fc1461028c578063095ea7b3146102c4575b600080fd5b34801561024157600080fd5b506102556102503660046120a4565b6106e6565b60405190151581526020015b60405180910390f35b34801561027657600080fd5b5061027f610738565b6040516102619190612119565b34801561029857600080fd5b506102ac6102a736600461212c565b6107ca565b6040516001600160a01b039091168152602001610261565b6102d76102d2366004612161565b61080e565b005b3480156102e557600080fd5b5060015460005403600019015b604051908152602001610261565b34801561030c57600080fd5b506102d761031b36600461218b565b6108ae565b6102d761032e3660046121a6565b61093a565b34801561033f57600080fd5b506102d7610a9a565b34801561035457600080fd5b506102f2600a5481565b34801561036a57600080fd5b506102d7610ac5565b6102d76103813660046121a6565b610bf5565b34801561039257600080fd5b506102f2600f5481565b3480156103a857600080fd5b506102d76103b736600461212c565b610d4a565b3480156103c857600080fd5b506102d76103d736600461226e565b610d57565b3480156103e857600080fd5b506103fc6103f7366004612303565b610d76565b6040516102619190612345565b34801561041557600080fd5b50600854600160a01b900460ff16610255565b34801561043457600080fd5b506102ac61044336600461212c565b610e42565b34801561045457600080fd5b5061027f610e4d565b34801561046957600080fd5b506102f261047836600461218b565b610edb565b34801561048957600080fd5b506102d7610f2a565b34801561049e57600080fd5b506102f260105481565b3480156104b457600080fd5b506104c86104c336600461218b565b610f3c565b60405161026191906123c2565b3480156104e157600080fd5b506008546001600160a01b03166102ac565b3480156104ff57600080fd5b506102d761050e36600461212c565b611045565b34801561051f57600080fd5b50600d546102ac906001600160a01b031681565b34801561053f57600080fd5b5061027f611052565b34801561055457600080fd5b506104c86105633660046123fa565b611061565b34801561057457600080fd5b506102f2600e5481565b34801561058a57600080fd5b506102f2600b5481565b6102d76105a236600461212c565b6111e9565b3480156105b357600080fd5b506102d76105c236600461243b565b611360565b6102d76105d5366004612472565b6113cc565b3480156105e657600080fd5b506105fa6105f536600461212c565b61152f565b60405161026191906124ee565b34801561061357600080fd5b5061027f61062236600461212c565b6115b7565b34801561063357600080fd5b506102f260095481565b34801561064957600080fd5b50610255610658366004612533565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b34801561069257600080fd5b506102d76106a136600461212c565b61163a565b3480156106b257600080fd5b506102d76106c136600461218b565b611647565b3480156106d257600080fd5b506102d76106e1366004612566565b6116bd565b60006301ffc9a760e01b6001600160e01b03198316148061071757506380ac58cd60e01b6001600160e01b03198316145b806107325750635b5e139f60e01b6001600160e01b03198316145b92915050565b606060028054610747906125b2565b80601f0160208091040260200160405190810160405280929190818152602001828054610773906125b2565b80156107c05780601f10610795576101008083540402835291602001916107c0565b820191906000526020600020905b8154815290600101906020018083116107a357829003601f168201915b5050505050905090565b60006107d5826117b3565b6107f2576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b600061081982610e42565b9050336001600160a01b03821614610852576108358133610658565b610852576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600d546001600160a01b031633146109185760405162461bcd60e51b815260206004820152602260248201527f75706461746544657657616c6c65743a2053656e646572206973206e6f74206460448201526132bb60f11b60648201526084015b60405180910390fd5b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b826daaeb6d7670e522a718067333cd4e3b15610a8957336001600160a01b038216036109705761096b8484846117e8565b610a94565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c6171134906044016020604051808303816000875af11580156109c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e591906125ec565b8015610a6a5750604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c6171134906044016020604051808303816000875af1158015610a46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6a91906125ec565b610a8957604051633b79c77360e21b815233600482015260240161090f565b610a948484846117e8565b50505050565b610aa2611980565b600854600160a01b900460ff16610abd57610abb6119da565b565b610abb611a3a565b610acd611980565b60004711610b435760405162461bcd60e51b815260206004820152603160248201527f77697468647261773a20636f6e74726163742062616c616e6365206d7573742060448201527f62652067726561746572207468616e2030000000000000000000000000000000606482015260840161090f565b600e544790600090606490610b58908261261f565b610b629084612636565b610b6c9190612655565b905060006064600e5484610b809190612636565b610b8a9190612655565b604051909150339083156108fc029084906000818181858888f19350505050158015610bba573d6000803e3d6000fd5b50600d546040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015610a94573d6000803e3d6000fd5b826daaeb6d7670e522a718067333cd4e3b15610d3f57336001600160a01b03821603610c265761096b848484611a76565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c6171134906044016020604051808303816000875af1158015610c77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9b91906125ec565b8015610d205750604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c6171134906044016020604051808303816000875af1158015610cfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2091906125ec565b610d3f57604051633b79c77360e21b815233600482015260240161090f565b610a94848484611a76565b610d52611980565b600955565b610d5f611980565b8051610d7290600c906020840190611ff5565b5050565b60608160008167ffffffffffffffff811115610d9457610d946121e2565b604051908082528060200260200182016040528015610de657816020015b604080516080810182526000808252602080830182905292820181905260608201528252600019909201910181610db25790505b50905060005b828114610e3957610e14868683818110610e0857610e08612677565b9050602002013561152f565b828281518110610e2657610e26612677565b6020908102919091010152600101610dec565b50949350505050565b600061073282611a96565b600c8054610e5a906125b2565b80601f0160208091040260200160405190810160405280929190818152602001828054610e86906125b2565b8015610ed35780601f10610ea857610100808354040283529160200191610ed3565b820191906000526020600020905b815481529060010190602001808311610eb657829003601f168201915b505050505081565b60006001600160a01b038216610f04576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b031660009081526005602052604090205467ffffffffffffffff1690565b610f32611980565b610abb6000611b05565b60606000806000610f4c85610edb565b905060008167ffffffffffffffff811115610f6957610f696121e2565b604051908082528060200260200182016040528015610f92578160200160208202803683370190505b509050610fbf60408051608081018252600080825260208201819052918101829052606081019190915290565b60015b83861461103957610fd281611b57565b915081604001516110315781516001600160a01b031615610ff257815194505b876001600160a01b0316856001600160a01b031603611031578083878060010198508151811061102457611024612677565b6020026020010181815250505b600101610fc2565b50909695505050505050565b61104d611980565b600b55565b606060038054610747906125b2565b606081831061108357604051631960ccad60e11b815260040160405180910390fd5b60008061108f60005490565b9050600185101561109f57600194505b808411156110ab578093505b60006110b687610edb565b9050848610156110d557858503818110156110cf578091505b506110d9565b5060005b60008167ffffffffffffffff8111156110f4576110f46121e2565b60405190808252806020026020018201604052801561111d578160200160208202803683370190505b509050816000036111335793506111e292505050565b600061113e8861152f565b90506000816040015161114f575080515b885b8881141580156111615750848714155b156111d65761116f81611b57565b925082604001516111ce5782516001600160a01b03161561118f57825191505b8a6001600160a01b0316826001600160a01b0316036111ce57808488806001019950815181106111c1576111c1612677565b6020026020010181815250505b600101611151565b50505092835250909150505b9392505050565b6111f1611bd6565b60095433600090815260056020526040908190205461121b911c67ffffffffffffffff168361268d565b11156112755760405162461bcd60e51b815260206004820152602360248201527f6d696e743a20457863656564656420746865206c696d6974207065722077616c6044820152621b195d60ea1b606482015260840161090f565b600a546001546000548391900360001901611290919061268d565b11156112de5760405162461bcd60e51b815260206004820152601c60248201527f6d696e743a204e6f7420656e6f75676820746f6b656e73206c65667400000000604482015260640161090f565b80600b546112ec9190612636565b34101561133b5760405162461bcd60e51b815260206004820152601b60248201527f6d696e743a204e6f7420656e6f7567682065746865722073656e740000000000604482015260640161090f565b80600f600082825461134d919061268d565b9091555061135d90503382611c23565b50565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b836daaeb6d7670e522a718067333cd4e3b1561151c57336001600160a01b03821603611403576113fe85858585611c3d565b611528565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c6171134906044016020604051808303816000875af1158015611454573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147891906125ec565b80156114fd5750604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c6171134906044016020604051808303816000875af11580156114d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114fd91906125ec565b61151c57604051633b79c77360e21b815233600482015260240161090f565b61152885858585611c3d565b5050505050565b604080516080810182526000808252602082018190529181018290526060810191909152604080516080810182526000808252602082018190529181018290526060810191909152600183108061158857506000548310155b156115935792915050565b61159c83611b57565b90508060400151156115ae5792915050565b6111e283611c81565b60606115c2826117b3565b6115df57604051630a14c4b560e41b815260040160405180910390fd5b60006115e9611cf9565b9050805160000361160957604051806020016040528060008152506111e2565b8061161384611d08565b6040516020016116249291906126a5565b6040516020818303038152906040529392505050565b611642611980565b600a55565b61164f611980565b6001600160a01b0381166116b45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161090f565b61135d81611b05565b6116c5611980565b600a5482906116d48284612636565b60015460005403600019016116e9919061268d565b11156117455760405162461bcd60e51b815260206004820152602560248201527f61697244726f703a204e6f7420656e6f75676820746f6b656e7320746f20616960448201526407264726f760dc1b606482015260840161090f565b61174f8183612636565b60106000828254611760919061268d565b90915550600090505b81811015611528576117a185858381811061178657611786612677565b905060200201602081019061179b919061218b565b84611c23565b806117ab816126d4565b915050611769565b6000816001111580156117c7575060005482105b8015610732575050600090815260046020526040902054600160e01b161590565b60006117f382611a96565b9050836001600160a01b0316816001600160a01b0316146118265760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417611873576118568633610658565b61187357604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b03851661189a57604051633a954ecd60e21b815260040160405180910390fd5b80156118a557600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260046020526040812091909155600160e11b84169003611937576001840160008181526004602052604081205490036119355760005481146119355760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b6008546001600160a01b03163314610abb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090f565b6119e2611bd6565b6008805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611a1d3390565b6040516001600160a01b03909116815260200160405180910390a1565b611a42611d4c565b6008805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33611a1d565b611a91838383604051806020016040528060008152506113cc565b505050565b60008180600111611aec57600054811015611aec5760008181526004602052604081205490600160e01b82169003611aea575b806000036111e2575060001901600081815260046020526040902054611ac9565b505b604051636f96cda160e11b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60408051608081018252600080825260208201819052918101829052606081019190915260008281526004602052604090205461073290604080516080810182526001600160a01b038316815260a083901c67ffffffffffffffff166020820152600160e01b831615159181019190915260e89190911c606082015290565b600854600160a01b900460ff1615610abb5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161090f565b610d72828260405180602001604052806000815250611da5565b611c4884848461093a565b6001600160a01b0383163b15610a9457611c6484848484611e0b565b610a94576040516368d2bf6b60e11b815260040160405180910390fd5b604080516080810182526000808252602082018190529181018290526060810191909152610732611cb183611a96565b604080516080810182526001600160a01b038316815260a083901c67ffffffffffffffff166020820152600160e01b831615159181019190915260e89190911c606082015290565b6060600c8054610747906125b2565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a900480611d225750819003601f19909101908152919050565b600854600160a01b900460ff16610abb5760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161090f565b611daf8383611ef7565b6001600160a01b0383163b15611a91576000548281035b611dd96000868380600101945086611e0b565b611df6576040516368d2bf6b60e11b815260040160405180910390fd5b818110611dc657816000541461152857600080fd5b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290611e409033908990889088906004016126ed565b6020604051808303816000875af1925050508015611e7b575060408051601f3d908101601f19168201909252611e7891810190612729565b60015b611ed9573d808015611ea9576040519150601f19603f3d011682016040523d82523d6000602084013e611eae565b606091505b508051600003611ed1576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b6000805490829003611f1c5760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b03831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b818114611fcb57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101611f93565b5081600003611fec57604051622e076360e81b815260040160405180910390fd5b60005550505050565b828054612001906125b2565b90600052602060002090601f0160209004810192826120235760008555612069565b82601f1061203c57805160ff1916838001178555612069565b82800160010185558215612069579182015b8281111561206957825182559160200191906001019061204e565b50612075929150612079565b5090565b5b80821115612075576000815560010161207a565b6001600160e01b03198116811461135d57600080fd5b6000602082840312156120b657600080fd5b81356111e28161208e565b60005b838110156120dc5781810151838201526020016120c4565b83811115610a945750506000910152565b600081518084526121058160208601602086016120c1565b601f01601f19169290920160200192915050565b6020815260006111e260208301846120ed565b60006020828403121561213e57600080fd5b5035919050565b80356001600160a01b038116811461215c57600080fd5b919050565b6000806040838503121561217457600080fd5b61217d83612145565b946020939093013593505050565b60006020828403121561219d57600080fd5b6111e282612145565b6000806000606084860312156121bb57600080fd5b6121c484612145565b92506121d260208501612145565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115612213576122136121e2565b604051601f8501601f19908116603f0116810190828211818310171561223b5761223b6121e2565b8160405280935085815286868601111561225457600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561228057600080fd5b813567ffffffffffffffff81111561229757600080fd5b8201601f810184136122a857600080fd5b611eef848235602084016121f8565b60008083601f8401126122c957600080fd5b50813567ffffffffffffffff8111156122e157600080fd5b6020830191508360208260051b85010111156122fc57600080fd5b9250929050565b6000806020838503121561231657600080fd5b823567ffffffffffffffff81111561232d57600080fd5b612339858286016122b7565b90969095509350505050565b6020808252825182820181905260009190848201906040850190845b81811015611039576123af8385516001600160a01b03815116825267ffffffffffffffff602082015116602083015260408101511515604083015262ffffff60608201511660608301525050565b9284019260809290920191600101612361565b6020808252825182820181905260009190848201906040850190845b81811015611039578351835292840192918401916001016123de565b60008060006060848603121561240f57600080fd5b61241884612145565b95602085013595506040909401359392505050565b801515811461135d57600080fd5b6000806040838503121561244e57600080fd5b61245783612145565b915060208301356124678161242d565b809150509250929050565b6000806000806080858703121561248857600080fd5b61249185612145565b935061249f60208601612145565b925060408501359150606085013567ffffffffffffffff8111156124c257600080fd5b8501601f810187136124d357600080fd5b6124e2878235602084016121f8565b91505092959194509250565b81516001600160a01b0316815260208083015167ffffffffffffffff169082015260408083015115159082015260608083015162ffffff169082015260808101610732565b6000806040838503121561254657600080fd5b61254f83612145565b915061255d60208401612145565b90509250929050565b60008060006040848603121561257b57600080fd5b833567ffffffffffffffff81111561259257600080fd5b61259e868287016122b7565b909790965060209590950135949350505050565b600181811c908216806125c657607f821691505b6020821081036125e657634e487b7160e01b600052602260045260246000fd5b50919050565b6000602082840312156125fe57600080fd5b81516111e28161242d565b634e487b7160e01b600052601160045260246000fd5b60008282101561263157612631612609565b500390565b600081600019048311821515161561265057612650612609565b500290565b60008261267257634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b600082198211156126a0576126a0612609565b500190565b600083516126b78184602088016120c1565b8351908301906126cb8183602088016120c1565b01949350505050565b6000600182016126e6576126e6612609565b5060010190565b60006001600160a01b0380871683528086166020840152508360408301526080606083015261271f60808301846120ed565b9695505050505050565b60006020828403121561273b57600080fd5b81516111e28161208e56fea2646970667358221220bed620996bd1aad4b311bfe810756c39062cdfca764a6ed30d98ba8dade0714564736f6c634300080d0033

Deployed Bytecode Sourcemap

84665:3379:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24652:639;;;;;;;;;;-1:-1:-1;24652:639:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;24652:639:0;;;;;;;;25554:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;32045:218::-;;;;;;;;;;-1:-1:-1;32045:218:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1692:55:1;;;1674:74;;1662:2;1647:18;32045:218:0;1528:226:1;31478:408:0;;;;;;:::i;:::-;;:::i;:::-;;21305:323;;;;;;;;;;-1:-1:-1;86201:1:0;21579:12;21366:7;21563:13;:28;-1:-1:-1;;21563:46:0;21305:323;;;2365:25:1;;;2353:2;2338:18;21305:323:0;2219:177:1;87474:152:0;;;;;;;;;;-1:-1:-1;87474:152:0;;;;;:::i;:::-;;:::i;86218:231::-;;;;;;:::i;:::-;;:::i;87166:98::-;;;;;;;;;;;;;:::i;84803:32::-;;;;;;;;;;;;;;;;87634:405;;;;;;;;;;;;;:::i;86457:239::-;;;;;;:::i;:::-;;:::i;85054:30::-;;;;;;;;;;;;;;;;87070:88;;;;;;;;;;-1:-1:-1;87070:88:0;;;;;:::i;:::-;;:::i;87272:92::-;;;;;;;;;;-1:-1:-1;87272:92:0;;;;;:::i;:::-;;:::i;61875:528::-;;;;;;;;;;-1:-1:-1;61875:528:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;2566:86::-;;;;;;;;;;-1:-1:-1;2637:7:0;;-1:-1:-1;;;2637:7:0;;;;2566:86;;26947:152;;;;;;;;;;-1:-1:-1;26947:152:0;;;;;:::i;:::-;;:::i;84889:21::-;;;;;;;;;;;;;:::i;22489:233::-;;;;;;;;;;-1:-1:-1;22489:233:0;;;;;:::i;:::-;;:::i;5431:103::-;;;;;;;;;;;;;:::i;85091:33::-;;;;;;;;;;;;;;;;65751:900;;;;;;;;;;-1:-1:-1;65751:900:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;4783:87::-;;;;;;;;;;-1:-1:-1;4856:6:0;;-1:-1:-1;;;;;4856:6:0;4783:87;;86976:86;;;;;;;;;;-1:-1:-1;86976:86:0;;;;;:::i;:::-;;:::i;84946:63::-;;;;;;;;;;-1:-1:-1;84946:63:0;;;;-1:-1:-1;;;;;84946:63:0;;;25730:104;;;;;;;;;;;;;:::i;62791:2513::-;;;;;;;;;;-1:-1:-1;62791:2513:0;;;;;:::i;:::-;;:::i;85016:26::-;;;;;;;;;;;;;;;;84842:34;;;;;;;;;;;;;;;;85189:429;;;;;;:::i;:::-;;:::i;32603:234::-;;;;;;;;;;-1:-1:-1;32603:234:0;;;;;:::i;:::-;;:::i;86704:264::-;;;;;;:::i;:::-;;:::i;61288:428::-;;;;;;;;;;-1:-1:-1;61288:428:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;25940:318::-;;;;;;;;;;-1:-1:-1;25940:318:0;;;;;:::i;:::-;;:::i;84765:31::-;;;;;;;;;;;;;;;;32994:164;;;;;;;;;;-1:-1:-1;32994:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;33115:25:0;;;33091:4;33115:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;32994:164;87372:94;;;;;;;;;;-1:-1:-1;87372:94:0;;;;;:::i;:::-;;:::i;5689:201::-;;;;;;;;;;-1:-1:-1;5689:201:0;;;;;:::i;:::-;;:::i;85626:375::-;;;;;;;;;;-1:-1:-1;85626:375:0;;;;;:::i;:::-;;:::i;24652:639::-;24737:4;-1:-1:-1;;;;;;;;;25061:25:0;;;;:102;;-1:-1:-1;;;;;;;;;;25138:25:0;;;25061:102;:179;;;-1:-1:-1;;;;;;;;;;25215:25:0;;;25061:179;25041:199;24652:639;-1:-1:-1;;24652:639:0:o;25554:100::-;25608:13;25641:5;25634:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25554:100;:::o;32045:218::-;32121:7;32146:16;32154:7;32146;:16::i;:::-;32141:64;;32171:34;;-1:-1:-1;;;32171:34:0;;;;;;;;;;;32141:64;-1:-1:-1;32225:24:0;;;;:15;:24;;;;;:30;-1:-1:-1;;;;;32225:30:0;;32045:218::o;31478:408::-;31567:13;31583:16;31591:7;31583;:16::i;:::-;31567:32;-1:-1:-1;55811:10:0;-1:-1:-1;;;;;31616:28:0;;;31612:175;;31664:44;31681:5;55811:10;32994:164;:::i;31664:44::-;31659:128;;31736:35;;-1:-1:-1;;;31736:35:0;;;;;;;;;;;31659:128;31799:24;;;;:15;:24;;;;;;:35;;-1:-1:-1;;;;;;31799:35:0;-1:-1:-1;;;;;31799:35:0;;;;;;;;;31850:28;;31799:24;;31850:28;;;;;;;31556:330;31478:408;;:::o;87474:152::-;87555:3;;-1:-1:-1;;;;;87555:3:0;87541:10;:17;87533:64;;;;-1:-1:-1;;;87533:64:0;;9780:2:1;87533:64:0;;;9762:21:1;9819:2;9799:18;;;9792:30;9858:34;9838:18;;;9831:62;-1:-1:-1;;;9909:18:1;;;9902:32;9951:19;;87533:64:0;;;;;;;;;87608:3;:10;;-1:-1:-1;;;;;;87608:10:0;-1:-1:-1;;;;;87608:10:0;;;;;;;;;;87474:152::o;86218:231::-;86382:4;82428:42;83568:43;:47;83564:699;;83855:10;-1:-1:-1;;;;;83847:18:0;;;83843:85;;86404:37:::1;86423:4;86429:2;86433:7;86404:18;:37::i;:::-;83906:7:::0;;83843:85;83988:67;;-1:-1:-1;;;83988:67:0;;84037:4;83988:67;;;10216:34:1;84044:10:0;10266:18:1;;;10259:43;82428:42:0;;83988:40;;10128:18:1;;83988:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:157;;;;-1:-1:-1;84084:61:0;;-1:-1:-1;;;84084:61:0;;84133:4;84084:61;;;10216:34:1;-1:-1:-1;;;;;10286:15:1;;10266:18;;;10259:43;82428:42:0;;84084:40;;10128:18:1;;84084:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;83942:310;;84206:30;;-1:-1:-1;;;84206:30:0;;84225:10;84206:30;;;1674:74:1;1647:18;;84206:30:0;1528:226:1;83942:310:0;86404:37:::1;86423:4;86429:2;86433:7;86404:18;:37::i;:::-;86218:231:::0;;;;:::o;87166:98::-;4669:13;:11;:13::i;:::-;2637:7;;-1:-1:-1;;;2637:7:0;;;;87224:32:::1;;87248:8;:6;:8::i;:::-;87166:98::o:0;87224:32::-:1;87235:10;:8;:10::i;87634:405::-:0;4669:13;:11;:13::i;:::-;87716:1:::1;87692:21;:25;87684:87;;;::::0;-1:-1:-1;;;87684:87:0;;10765:2:1;87684:87:0::1;::::0;::::1;10747:21:1::0;10804:2;10784:18;;;10777:30;10843:34;10823:18;;;10816:62;10914:19;10894:18;;;10887:47;10951:19;;87684:87:0::1;10563:413:1::0;87684:87:0::1;87871:6;::::0;87801:21:::1;::::0;87783:15:::1;::::0;87882:3:::1;::::0;87865:12:::1;::::0;87882:3;87865:12:::1;:::i;:::-;87854:24;::::0;:7;:24:::1;:::i;:::-;87853:32;;;;:::i;:::-;87833:53;;87897:14;87938:3;87927:6;;87916:7;:18;;;;:::i;:::-;87915:26;;;;:::i;:::-;87953:38;::::0;87897:45;;-1:-1:-1;87961:10:0::1;::::0;87953:38;::::1;;;::::0;87982:8;;87953:38:::1;::::0;;;87982:8;87961:10;87953:38;::::1;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;88010:3:0::1;::::0;88002:29:::1;::::0;-1:-1:-1;;;;;88010:3:0;;::::1;::::0;88002:29;::::1;;;::::0;88024:6;;88010:3:::1;88002:29:::0;88010:3;88002:29;88024:6;88010:3;88002:29;::::1;;;;;;;;;;;;;::::0;::::1;;;;86457:239:::0;86625:4;82428:42;83568:43;:47;83564:699;;83855:10;-1:-1:-1;;;;;83847:18:0;;;83843:85;;86647:41:::1;86670:4;86676:2;86680:7;86647:22;:41::i;83843:85::-:0;83988:67;;-1:-1:-1;;;83988:67:0;;84037:4;83988:67;;;10216:34:1;84044:10:0;10266:18:1;;;10259:43;82428:42:0;;83988:40;;10128:18:1;;83988:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:157;;;;-1:-1:-1;84084:61:0;;-1:-1:-1;;;84084:61:0;;84133:4;84084:61;;;10216:34:1;-1:-1:-1;;;;;10286:15:1;;10266:18;;;10259:43;82428:42:0;;84084:40;;10128:18:1;;84084:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;83942:310;;84206:30;;-1:-1:-1;;;84206:30:0;;84225:10;84206:30;;;1674:74:1;1647:18;;84206:30:0;1528:226:1;83942:310:0;86647:41:::1;86670:4;86676:2;86680:7;86647:22;:41::i;87070:88::-:0;4669:13;:11;:13::i;:::-;87134:9:::1;:16:::0;87070:88::o;87272:92::-;4669:13;:11;:13::i;:::-;87342:14;;::::1;::::0;:7:::1;::::0;:14:::1;::::0;::::1;::::0;::::1;:::i;:::-;;87272:92:::0;:::o;61875:528::-;62019:23;62110:8;62085:22;62110:8;62177:36;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62177:36:0;;-1:-1:-1;;62177:36:0;;;;;;;;;;;;62140:73;;62233:9;62228:125;62249:14;62244:1;:19;62228:125;;62305:32;62325:8;;62334:1;62325:11;;;;;;;:::i;:::-;;;;;;;62305:19;:32::i;:::-;62289:10;62300:1;62289:13;;;;;;;;:::i;:::-;;;;;;;;;;:48;62265:3;;62228:125;;;-1:-1:-1;62374:10:0;61875:528;-1:-1:-1;;;;61875:528:0:o;26947:152::-;27019:7;27062:27;27081:7;27062:18;:27::i;84889:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;22489:233::-;22561:7;-1:-1:-1;;;;;22585:19:0;;22581:60;;22613:28;;-1:-1:-1;;;22613:28:0;;;;;;;;;;;22581:60;-1:-1:-1;;;;;;22659:25:0;;;;;:18;:25;;;;;;16648:13;22659:55;;22489:233::o;5431:103::-;4669:13;:11;:13::i;:::-;5496:30:::1;5523:1;5496:18;:30::i;65751:900::-:0;65829:16;65883:19;65917:25;65957:22;65982:16;65992:5;65982:9;:16::i;:::-;65957:41;;66013:25;66055:14;66041:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66041:29:0;;66013:57;;66085:31;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66085:31:0;86201:1;66131:472;66180:14;66165:11;:29;66131:472;;66232:15;66245:1;66232:12;:15::i;:::-;66220:27;;66270:9;:16;;;66311:8;66266:73;66361:14;;-1:-1:-1;;;;;66361:28:0;;66357:111;;66434:14;;;-1:-1:-1;66357:111:0;66511:5;-1:-1:-1;;;;;66490:26:0;:17;-1:-1:-1;;;;;66490:26:0;;66486:102;;66567:1;66541:8;66550:13;;;;;;66541:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;66486:102;66196:3;;66131:472;;;-1:-1:-1;66624:8:0;;65751:900;-1:-1:-1;;;;;;65751:900:0:o;86976:86::-;4669:13;:11;:13::i;:::-;87040:5:::1;:14:::0;86976:86::o;25730:104::-;25786:13;25819:7;25812:14;;;;;:::i;62791:2513::-;62934:16;63001:4;62992:5;:13;62988:45;;63014:19;;-1:-1:-1;;;63014:19:0;;;;;;;;;;;62988:45;63048:19;63082:17;63102:14;21047:7;21074:13;;20992:103;63102:14;63082:34;-1:-1:-1;86201:1:0;63194:5;:23;63190:87;;;86201:1;63238:23;;63190:87;63353:9;63346:4;:16;63342:73;;;63390:9;63383:16;;63342:73;63429:25;63457:16;63467:5;63457:9;:16::i;:::-;63429:44;;63651:4;63643:5;:12;63639:278;;;63698:12;;;63733:31;;;63729:111;;;63809:11;63789:31;;63729:111;63657:198;63639:278;;;-1:-1:-1;63900:1:0;63639:278;63931:25;63973:17;63959:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63959:32:0;;63931:60;;64010:17;64031:1;64010:22;64006:78;;64060:8;-1:-1:-1;64053:15:0;;-1:-1:-1;;;64053:15:0;64006:78;64228:31;64262:26;64282:5;64262:19;:26::i;:::-;64228:60;;64303:25;64548:9;:16;;;64543:92;;-1:-1:-1;64605:14:0;;64543:92;64666:5;64649:478;64678:4;64673:1;:9;;:45;;;;;64701:17;64686:11;:32;;64673:45;64649:478;;;64756:15;64769:1;64756:12;:15::i;:::-;64744:27;;64794:9;:16;;;64835:8;64790:73;64885:14;;-1:-1:-1;;;;;64885:28:0;;64881:111;;64958:14;;;-1:-1:-1;64881:111:0;65035:5;-1:-1:-1;;;;;65014:26:0;:17;-1:-1:-1;;;;;65014:26:0;;65010:102;;65091:1;65065:8;65074:13;;;;;;65065:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;65010:102;64720:3;;64649:478;;;-1:-1:-1;;;65212:29:0;;;-1:-1:-1;65219:8:0;;-1:-1:-1;;62791:2513:0;;;;;;:::o;85189:429::-;2171:19;:17;:19::i;:::-;85311:9:::1;::::0;85296:10:::1;22865:7:::0;22893:25;;;:18;:25;;16786:2;22893:25;;;;;85271:36:::1;::::0;22893:50;16648:13;22892:82;85271:8;:36:::1;:::i;:::-;:49;;85263:97;;;::::0;-1:-1:-1;;;85263:97:0;;12105:2:1;85263:97:0::1;::::0;::::1;12087:21:1::0;12144:2;12124:18;;;12117:30;12183:34;12163:18;;;12156:62;-1:-1:-1;;;12234:18:1;;;12227:33;12277:19;;85263:97:0::1;11903:399:1::0;85263:97:0::1;85407:10;::::0;86201:1;21579:12;21366:7;21563:13;85395:8;;21563:28;;-1:-1:-1;;21563:46:0;85379:24:::1;;;;:::i;:::-;:38;;85371:79;;;::::0;-1:-1:-1;;;85371:79:0;;12509:2:1;85371:79:0::1;::::0;::::1;12491:21:1::0;12548:2;12528:18;;;12521:30;12587;12567:18;;;12560:58;12635:18;;85371:79:0::1;12307:352:1::0;85371:79:0::1;85491:8;85483:5;;:16;;;;:::i;:::-;85469:9;:31;;85461:71;;;::::0;-1:-1:-1;;;85461:71:0;;12866:2:1;85461:71:0::1;::::0;::::1;12848:21:1::0;12905:2;12885:18;;;12878:30;12944:29;12924:18;;;12917:57;12991:18;;85461:71:0::1;12664:351:1::0;85461:71:0::1;85560:8;85545:11;;:23;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;85579:31:0::1;::::0;-1:-1:-1;85589:10:0::1;85601:8:::0;85579:9:::1;:31::i;:::-;85189:429:::0;:::o;32603:234::-;55811:10;32698:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;32698:49:0;;;;;;;;;;;;:60;;-1:-1:-1;;32698:60:0;;;;;;;;;;32774:55;;540:41:1;;;32698:49:0;;55811:10;32774:55;;513:18:1;32774:55:0;;;;;;;32603:234;;:::o;86704:264::-;86891:4;82428:42;83568:43;:47;83564:699;;83855:10;-1:-1:-1;;;;;83847:18:0;;;83843:85;;86913:47:::1;86936:4;86942:2;86946:7;86955:4;86913:22;:47::i;:::-;83906:7:::0;;83843:85;83988:67;;-1:-1:-1;;;83988:67:0;;84037:4;83988:67;;;10216:34:1;84044:10:0;10266:18:1;;;10259:43;82428:42:0;;83988:40;;10128:18:1;;83988:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:157;;;;-1:-1:-1;84084:61:0;;-1:-1:-1;;;84084:61:0;;84133:4;84084:61;;;10216:34:1;-1:-1:-1;;;;;10286:15:1;;10266:18;;;10259:43;82428:42:0;;84084:40;;10128:18:1;;84084:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;83942:310;;84206:30;;-1:-1:-1;;;84206:30:0;;84225:10;84206:30;;;1674:74:1;1647:18;;84206:30:0;1528:226:1;83942:310:0;86913:47:::1;86936:4;86942:2;86946:7;86955:4;86913:22;:47::i;:::-;86704:264:::0;;;;;:::o;61288:428::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86201:1:0;61452:7;:25;:54;;;-1:-1:-1;21047:7:0;21074:13;61481:7;:25;;61452:54;61448:103;;;61530:9;61288:428;-1:-1:-1;;61288:428:0:o;61448:103::-;61573:21;61586:7;61573:12;:21::i;:::-;61561:33;;61609:9;:16;;;61605:65;;;61649:9;61288:428;-1:-1:-1;;61288:428:0:o;61605:65::-;61687:21;61700:7;61687:12;:21::i;25940:318::-;26013:13;26044:16;26052:7;26044;:16::i;:::-;26039:59;;26069:29;;-1:-1:-1;;;26069:29:0;;;;;;;;;;;26039:59;26111:21;26135:10;:8;:10::i;:::-;26111:34;;26169:7;26163:21;26188:1;26163:26;:87;;;;;;;;;;;;;;;;;26216:7;26225:18;26235:7;26225:9;:18::i;:::-;26199:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;26156:94;25940:318;-1:-1:-1;;;25940:318:0:o;87372:94::-;4669:13;:11;:13::i;:::-;87441:10:::1;:17:::0;87372:94::o;5689:201::-;4669:13;:11;:13::i;:::-;-1:-1:-1;;;;;5778:22:0;::::1;5770:73;;;::::0;-1:-1:-1;;;5770:73:0;;13697:2:1;5770:73:0::1;::::0;::::1;13679:21:1::0;13736:2;13716:18;;;13709:30;13775:34;13755:18;;;13748:62;-1:-1:-1;;;13826:18:1;;;13819:36;13872:19;;5770:73:0::1;13495:402:1::0;5770:73:0::1;5854:28;5873:8;5854:18;:28::i;85626:375::-:0;4669:13;:11;:13::i;:::-;85798:10:::1;::::0;85731:5;;85779:14:::1;85731:5:::0;85779:8;:14:::1;:::i;:::-;86201:1:::0;21579:12;21366:7;21563:13;:28;-1:-1:-1;;21563:46:0;85762:32:::1;;;;:::i;:::-;:46;;85754:96;;;::::0;-1:-1:-1;;;85754:96:0;;14104:2:1;85754:96:0::1;::::0;::::1;14086:21:1::0;14143:2;14123:18;;;14116:30;14182:34;14162:18;;;14155:62;-1:-1:-1;;;14233:18:1;;;14226:35;14278:19;;85754:96:0::1;13902:401:1::0;85754:96:0::1;85879:14;85890:3:::0;85879:8;:14:::1;:::i;:::-;85861;;:32;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;85909:9:0::1;::::0;-1:-1:-1;85904:90:0::1;85928:3;85924:1;:7;85904:90;;;85953:29;85963:5;;85969:1;85963:8;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;85973;85953:9;:29::i;:::-;85933:3:::0;::::1;::::0;::::1;:::i;:::-;;;;85904:90;;33416:282:::0;33481:4;33537:7;86201:1;33518:26;;:66;;;;;33571:13;;33561:7;:23;33518:66;:153;;;;-1:-1:-1;;33622:26:0;;;;:17;:26;;;;;;-1:-1:-1;;;33622:44:0;:49;;33416:282::o;35684:2825::-;35826:27;35856;35875:7;35856:18;:27::i;:::-;35826:57;;35941:4;-1:-1:-1;;;;;35900:45:0;35916:19;-1:-1:-1;;;;;35900:45:0;;35896:86;;35954:28;;-1:-1:-1;;;35954:28:0;;;;;;;;;;;35896:86;35996:27;34792:24;;;:15;:24;;;;;35020:26;;55811:10;34417:30;;;-1:-1:-1;;;;;34110:28:0;;34395:20;;;34392:56;36182:180;;36275:43;36292:4;55811:10;32994:164;:::i;36275:43::-;36270:92;;36327:35;;-1:-1:-1;;;36327:35:0;;;;;;;;;;;36270:92;-1:-1:-1;;;;;36379:16:0;;36375:52;;36404:23;;-1:-1:-1;;;36404:23:0;;;;;;;;;;;36375:52;36576:15;36573:160;;;36716:1;36695:19;36688:30;36573:160;-1:-1:-1;;;;;37113:24:0;;;;;;;:18;:24;;;;;;37111:26;;-1:-1:-1;;37111:26:0;;;37182:22;;;;;;;;;37180:24;;-1:-1:-1;37180:24:0;;;30336:11;30311:23;30307:41;30294:63;-1:-1:-1;;;30294:63:0;37475:26;;;;:17;:26;;;;;:175;;;;-1:-1:-1;;;37770:47:0;;:52;;37766:627;;37875:1;37865:11;;37843:19;37998:30;;;:17;:30;;;;;;:35;;37994:384;;38136:13;;38121:11;:28;38117:242;;38283:30;;;;:17;:30;;;;;:52;;;38117:242;37824:569;37766:627;38440:7;38436:2;-1:-1:-1;;;;;38421:27:0;38430:4;-1:-1:-1;;;;;38421:27:0;;;;;;;;;;;35815:2694;;;35684:2825;;;:::o;4948:132::-;4856:6;;-1:-1:-1;;;;;4856:6:0;55811:10;5012:23;5004:68;;;;-1:-1:-1;;;5004:68:0;;14650:2:1;5004:68:0;;;14632:21:1;;;14669:18;;;14662:30;14728:34;14708:18;;;14701:62;14780:18;;5004:68:0;14448:356:1;3162:118:0;2171:19;:17;:19::i;:::-;3222:7:::1;:14:::0;;-1:-1:-1;;;;3222:14:0::1;-1:-1:-1::0;;;3222:14:0::1;::::0;;3252:20:::1;3259:12;55811:10:::0;;55724:105;3259:12:::1;3252:20;::::0;-1:-1:-1;;;;;1692:55:1;;;1674:74;;1662:2;1647:18;3252:20:0::1;;;;;;;3162:118::o:0;3421:120::-;2430:16;:14;:16::i;:::-;3480:7:::1;:15:::0;;-1:-1:-1;;;;3480:15:0::1;::::0;;3511:22:::1;55811:10:::0;3520:12:::1;55724:105:::0;38605:193;38751:39;38768:4;38774:2;38778:7;38751:39;;;;;;;;;;;;:16;:39::i;:::-;38605:193;;;:::o;28102:1275::-;28169:7;28204;;86201:1;28253:23;28249:1061;;28306:13;;28299:4;:20;28295:1015;;;28344:14;28361:23;;;:17;:23;;;;;;;-1:-1:-1;;;28450:24:0;;:29;;28446:845;;29115:113;29122:6;29132:1;29122:11;29115:113;;-1:-1:-1;;;29193:6:0;29175:25;;;;:17;:25;;;;;;29115:113;;28446:845;28321:989;28295:1015;29338:31;;-1:-1:-1;;;29338:31:0;;;;;;;;;;;6050:191;6143:6;;;-1:-1:-1;;;;;6160:17:0;;;-1:-1:-1;;;;;;6160:17:0;;;;;;;6193:40;;6143:6;;;6160:17;6143:6;;6193:40;;6124:16;;6193:40;6113:128;6050:191;:::o;27550:161::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27678:24:0;;;;:17;:24;;;;;;27659:44;;-1:-1:-1;;;;;;;;;;;;;29586:41:0;;;;17307:3;29672:33;;;29638:68;;-1:-1:-1;;;29638:68:0;-1:-1:-1;;;29736:24:0;;:29;;-1:-1:-1;;;29717:48:0;;;;17828:3;29805:28;;;;-1:-1:-1;;;29776:58:0;-1:-1:-1;29476:366:0;2725:108;2637:7;;-1:-1:-1;;;2637:7:0;;;;2795:9;2787:38;;;;-1:-1:-1;;;2787:38:0;;15011:2:1;2787:38:0;;;14993:21:1;15050:2;15030:18;;;15023:30;-1:-1:-1;;;15069:18:1;;;15062:46;15125:18;;2787:38:0;14809:340:1;49556:112:0;49633:27;49643:2;49647:8;49633:27;;;;;;;;;;;;:9;:27::i;39396:407::-;39571:31;39584:4;39590:2;39594:7;39571:12;:31::i;:::-;-1:-1:-1;;;;;39617:14:0;;;:19;39613:183;;39656:56;39687:4;39693:2;39697:7;39706:5;39656:30;:56::i;:::-;39651:145;;39740:40;;-1:-1:-1;;;39740:40:0;;;;;;;;;;;27288:166;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27399:47:0;27418:27;27437:7;27418:18;:27::i;:::-;-1:-1:-1;;;;;;;;;;;;;29586:41:0;;;;17307:3;29672:33;;;29638:68;;-1:-1:-1;;;29638:68:0;-1:-1:-1;;;29736:24:0;;:29;;-1:-1:-1;;;29717:48:0;;;;17828:3;29805:28;;;;-1:-1:-1;;;29776:58:0;-1:-1:-1;29476:366:0;86009:100;86061:13;86094:7;86087:14;;;;;:::i;55931:1745::-;55996:17;56430:4;56423;56417:11;56413:22;56522:1;56516:4;56509:15;56597:4;56594:1;56590:12;56583:19;;;56679:1;56674:3;56667:14;56783:3;57022:5;57004:428;57070:1;57065:3;57061:11;57054:18;;57241:2;57235:4;57231:13;57227:2;57223:22;57218:3;57210:36;57335:2;57325:13;;57392:25;57004:428;57392:25;-1:-1:-1;57462:13:0;;;-1:-1:-1;;57577:14:0;;;57639:19;;;57577:14;55931:1745;-1:-1:-1;55931:1745:0:o;2910:108::-;2637:7;;-1:-1:-1;;;2637:7:0;;;;2969:41;;;;-1:-1:-1;;;2969:41:0;;15356:2:1;2969:41:0;;;15338:21:1;15395:2;15375:18;;;15368:30;15434:22;15414:18;;;15407:50;15474:18;;2969:41:0;15154:344:1;48783:689:0;48914:19;48920:2;48924:8;48914:5;:19::i;:::-;-1:-1:-1;;;;;48975:14:0;;;:19;48971:483;;49015:11;49029:13;49077:14;;;49110:233;49141:62;49180:1;49184:2;49188:7;;;;;;49197:5;49141:30;:62::i;:::-;49136:167;;49239:40;;-1:-1:-1;;;49239:40:0;;;;;;;;;;;49136:167;49338:3;49330:5;:11;49110:233;;49425:3;49408:13;;:20;49404:34;;49430:8;;;41887:716;42071:88;;-1:-1:-1;;;42071:88:0;;42050:4;;-1:-1:-1;;;;;42071:45:0;;;;;:88;;55811:10;;42138:4;;42144:7;;42153:5;;42071:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42071:88:0;;;;;;;;-1:-1:-1;;42071:88:0;;;;;;;;;;;;:::i;:::-;;;42067:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42354:6;:13;42371:1;42354:18;42350:235;;42400:40;;-1:-1:-1;;;42400:40:0;;;;;;;;;;;42350:235;42543:6;42537:13;42528:6;42524:2;42520:15;42513:38;42067:529;-1:-1:-1;;;;;;42230:64:0;-1:-1:-1;;;42230:64:0;;-1:-1:-1;42067:529:0;41887:716;;;;;;:::o;43065:2966::-;43138:20;43161:13;;;43189;;;43185:44;;43211:18;;-1:-1:-1;;;43211:18:0;;;;;;;;;;;43185:44;-1:-1:-1;;;;;43717:22:0;;;;;;:18;:22;;;;16786:2;43717:22;;;:71;;43755:32;43743:45;;43717:71;;;44031:31;;;:17;:31;;;;;-1:-1:-1;30767:15:0;;30741:24;30737:46;30336:11;30311:23;30307:41;30304:52;30294:63;;44031:173;;44266:23;;;;44031:31;;43717:22;;45031:25;43717:22;;44884:335;45545:1;45531:12;45527:20;45485:346;45586:3;45577:7;45574:16;45485:346;;45804:7;45794:8;45791:1;45764:25;45761:1;45758;45753:59;45639:1;45626:15;45485:346;;;45489:77;45864:8;45876:1;45864:13;45860:45;;45886:19;;-1:-1:-1;;;45886:19:0;;;;;;;;;;;45860:45;45922:13;:19;-1:-1:-1;38605:193:0;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;-1:-1:-1;;840:1:1;822:16;;815:27;592:258::o;855:::-;897:3;935:5;929:12;962:6;957:3;950:19;978:63;1034:6;1027:4;1022:3;1018:14;1011:4;1004:5;1000:16;978:63;:::i;:::-;1095:2;1074:15;-1:-1:-1;;1070:29:1;1061:39;;;;1102:4;1057:50;;855:258;-1:-1:-1;;855:258:1:o;1118:220::-;1267:2;1256:9;1249:21;1230:4;1287:45;1328:2;1317:9;1313:18;1305:6;1287:45;:::i;1343:180::-;1402:6;1455:2;1443:9;1434:7;1430:23;1426:32;1423:52;;;1471:1;1468;1461:12;1423:52;-1:-1:-1;1494:23:1;;1343:180;-1:-1:-1;1343:180:1:o;1759:196::-;1827:20;;-1:-1:-1;;;;;1876:54:1;;1866:65;;1856:93;;1945:1;1942;1935:12;1856:93;1759:196;;;:::o;1960:254::-;2028:6;2036;2089:2;2077:9;2068:7;2064:23;2060:32;2057:52;;;2105:1;2102;2095:12;2057:52;2128:29;2147:9;2128:29;:::i;:::-;2118:39;2204:2;2189:18;;;;2176:32;;-1:-1:-1;;;1960:254:1:o;2401:186::-;2460:6;2513:2;2501:9;2492:7;2488:23;2484:32;2481:52;;;2529:1;2526;2519:12;2481:52;2552:29;2571:9;2552:29;:::i;2592:328::-;2669:6;2677;2685;2738:2;2726:9;2717:7;2713:23;2709:32;2706:52;;;2754:1;2751;2744:12;2706:52;2777:29;2796:9;2777:29;:::i;:::-;2767:39;;2825:38;2859:2;2848:9;2844:18;2825:38;:::i;:::-;2815:48;;2910:2;2899:9;2895:18;2882:32;2872:42;;2592:328;;;;;:::o;2925:127::-;2986:10;2981:3;2977:20;2974:1;2967:31;3017:4;3014:1;3007:15;3041:4;3038:1;3031:15;3057:632;3122:5;3152:18;3193:2;3185:6;3182:14;3179:40;;;3199:18;;:::i;:::-;3274:2;3268:9;3242:2;3328:15;;-1:-1:-1;;3324:24:1;;;3350:2;3320:33;3316:42;3304:55;;;3374:18;;;3394:22;;;3371:46;3368:72;;;3420:18;;:::i;:::-;3460:10;3456:2;3449:22;3489:6;3480:15;;3519:6;3511;3504:22;3559:3;3550:6;3545:3;3541:16;3538:25;3535:45;;;3576:1;3573;3566:12;3535:45;3626:6;3621:3;3614:4;3606:6;3602:17;3589:44;3681:1;3674:4;3665:6;3657;3653:19;3649:30;3642:41;;;;3057:632;;;;;:::o;3694:451::-;3763:6;3816:2;3804:9;3795:7;3791:23;3787:32;3784:52;;;3832:1;3829;3822:12;3784:52;3872:9;3859:23;3905:18;3897:6;3894:30;3891:50;;;3937:1;3934;3927:12;3891:50;3960:22;;4013:4;4005:13;;4001:27;-1:-1:-1;3991:55:1;;4042:1;4039;4032:12;3991:55;4065:74;4131:7;4126:2;4113:16;4108:2;4104;4100:11;4065:74;:::i;4150:367::-;4213:8;4223:6;4277:3;4270:4;4262:6;4258:17;4254:27;4244:55;;4295:1;4292;4285:12;4244:55;-1:-1:-1;4318:20:1;;4361:18;4350:30;;4347:50;;;4393:1;4390;4383:12;4347:50;4430:4;4422:6;4418:17;4406:29;;4490:3;4483:4;4473:6;4470:1;4466:14;4458:6;4454:27;4450:38;4447:47;4444:67;;;4507:1;4504;4497:12;4444:67;4150:367;;;;;:::o;4522:437::-;4608:6;4616;4669:2;4657:9;4648:7;4644:23;4640:32;4637:52;;;4685:1;4682;4675:12;4637:52;4725:9;4712:23;4758:18;4750:6;4747:30;4744:50;;;4790:1;4787;4780:12;4744:50;4829:70;4891:7;4882:6;4871:9;4867:22;4829:70;:::i;:::-;4918:8;;4803:96;;-1:-1:-1;4522:437:1;-1:-1:-1;;;;4522:437:1:o;5341:722::-;5574:2;5626:21;;;5696:13;;5599:18;;;5718:22;;;5545:4;;5574:2;5797:15;;;;5771:2;5756:18;;;5545:4;5840:197;5854:6;5851:1;5848:13;5840:197;;;5903:52;5951:3;5942:6;5936:13;-1:-1:-1;;;;;5054:5:1;5048:12;5044:61;5039:3;5032:74;5167:18;5159:4;5152:5;5148:16;5142:23;5138:48;5131:4;5126:3;5122:14;5115:72;5250:4;5243:5;5239:16;5233:23;5226:31;5219:39;5212:4;5207:3;5203:14;5196:63;5320:8;5312:4;5305:5;5301:16;5295:23;5291:38;5284:4;5279:3;5275:14;5268:62;;;4964:372;5903:52;6012:15;;;;5984:4;5975:14;;;;;5876:1;5869:9;5840:197;;6068:632;6239:2;6291:21;;;6361:13;;6264:18;;;6383:22;;;6210:4;;6239:2;6462:15;;;;6436:2;6421:18;;;6210:4;6505:169;6519:6;6516:1;6513:13;6505:169;;;6580:13;;6568:26;;6649:15;;;;6614:12;;;;6541:1;6534:9;6505:169;;6705:322;6782:6;6790;6798;6851:2;6839:9;6830:7;6826:23;6822:32;6819:52;;;6867:1;6864;6857:12;6819:52;6890:29;6909:9;6890:29;:::i;:::-;6880:39;6966:2;6951:18;;6938:32;;-1:-1:-1;7017:2:1;7002:18;;;6989:32;;6705:322;-1:-1:-1;;;6705:322:1:o;7032:118::-;7118:5;7111:13;7104:21;7097:5;7094:32;7084:60;;7140:1;7137;7130:12;7155:315;7220:6;7228;7281:2;7269:9;7260:7;7256:23;7252:32;7249:52;;;7297:1;7294;7287:12;7249:52;7320:29;7339:9;7320:29;:::i;:::-;7310:39;;7399:2;7388:9;7384:18;7371:32;7412:28;7434:5;7412:28;:::i;:::-;7459:5;7449:15;;;7155:315;;;;;:::o;7475:667::-;7570:6;7578;7586;7594;7647:3;7635:9;7626:7;7622:23;7618:33;7615:53;;;7664:1;7661;7654:12;7615:53;7687:29;7706:9;7687:29;:::i;:::-;7677:39;;7735:38;7769:2;7758:9;7754:18;7735:38;:::i;:::-;7725:48;;7820:2;7809:9;7805:18;7792:32;7782:42;;7875:2;7864:9;7860:18;7847:32;7902:18;7894:6;7891:30;7888:50;;;7934:1;7931;7924:12;7888:50;7957:22;;8010:4;8002:13;;7998:27;-1:-1:-1;7988:55:1;;8039:1;8036;8029:12;7988:55;8062:74;8128:7;8123:2;8110:16;8105:2;8101;8097:11;8062:74;:::i;:::-;8052:84;;;7475:667;;;;;;;:::o;8147:266::-;5048:12;;-1:-1:-1;;;;;5044:61:1;5032:74;;5159:4;5148:16;;;5142:23;5167:18;5138:48;5122:14;;;5115:72;5250:4;5239:16;;;5233:23;5226:31;5219:39;5203:14;;;5196:63;5312:4;5301:16;;;5295:23;5320:8;5291:38;5275:14;;;5268:62;8343:3;8328:19;;8356:51;4964:372;8418:260;8486:6;8494;8547:2;8535:9;8526:7;8522:23;8518:32;8515:52;;;8563:1;8560;8553:12;8515:52;8586:29;8605:9;8586:29;:::i;:::-;8576:39;;8634:38;8668:2;8657:9;8653:18;8634:38;:::i;:::-;8624:48;;8418:260;;;;;:::o;8683:505::-;8778:6;8786;8794;8847:2;8835:9;8826:7;8822:23;8818:32;8815:52;;;8863:1;8860;8853:12;8815:52;8903:9;8890:23;8936:18;8928:6;8925:30;8922:50;;;8968:1;8965;8958:12;8922:50;9007:70;9069:7;9060:6;9049:9;9045:22;9007:70;:::i;:::-;9096:8;;8981:96;;-1:-1:-1;9178:2:1;9163:18;;;;9150:32;;8683:505;-1:-1:-1;;;;8683:505:1:o;9193:380::-;9272:1;9268:12;;;;9315;;;9336:61;;9390:4;9382:6;9378:17;9368:27;;9336:61;9443:2;9435:6;9432:14;9412:18;9409:38;9406:161;;9489:10;9484:3;9480:20;9477:1;9470:31;9524:4;9521:1;9514:15;9552:4;9549:1;9542:15;9406:161;;9193:380;;;:::o;10313:245::-;10380:6;10433:2;10421:9;10412:7;10408:23;10404:32;10401:52;;;10449:1;10446;10439:12;10401:52;10481:9;10475:16;10500:28;10522:5;10500:28;:::i;10981:127::-;11042:10;11037:3;11033:20;11030:1;11023:31;11073:4;11070:1;11063:15;11097:4;11094:1;11087:15;11113:125;11153:4;11181:1;11178;11175:8;11172:34;;;11186:18;;:::i;:::-;-1:-1:-1;11223:9:1;;11113:125::o;11243:168::-;11283:7;11349:1;11345;11341:6;11337:14;11334:1;11331:21;11326:1;11319:9;11312:17;11308:45;11305:71;;;11356:18;;:::i;:::-;-1:-1:-1;11396:9:1;;11243:168::o;11416:217::-;11456:1;11482;11472:132;;11526:10;11521:3;11517:20;11514:1;11507:31;11561:4;11558:1;11551:15;11589:4;11586:1;11579:15;11472:132;-1:-1:-1;11618:9:1;;11416:217::o;11638:127::-;11699:10;11694:3;11690:20;11687:1;11680:31;11730:4;11727:1;11720:15;11754:4;11751:1;11744:15;11770:128;11810:3;11841:1;11837:6;11834:1;11831:13;11828:39;;;11847:18;;:::i;:::-;-1:-1:-1;11883:9:1;;11770:128::o;13020:470::-;13199:3;13237:6;13231:13;13253:53;13299:6;13294:3;13287:4;13279:6;13275:17;13253:53;:::i;:::-;13369:13;;13328:16;;;;13391:57;13369:13;13328:16;13425:4;13413:17;;13391:57;:::i;:::-;13464:20;;13020:470;-1:-1:-1;;;;13020:470:1:o;14308:135::-;14347:3;14368:17;;;14365:43;;14388:18;;:::i;:::-;-1:-1:-1;14435:1:1;14424:13;;14308:135::o;15503:512::-;15697:4;-1:-1:-1;;;;;15807:2:1;15799:6;15795:15;15784:9;15777:34;15859:2;15851:6;15847:15;15842:2;15831:9;15827:18;15820:43;;15899:6;15894:2;15883:9;15879:18;15872:34;15942:3;15937:2;15926:9;15922:18;15915:31;15963:46;16004:3;15993:9;15989:19;15981:6;15963:46;:::i;:::-;15955:54;15503:512;-1:-1:-1;;;;;;15503:512:1:o;16020:249::-;16089:6;16142:2;16130:9;16121:7;16117:23;16113:32;16110:52;;;16158:1;16155;16148:12;16110:52;16190:9;16184:16;16209:30;16233:5;16209:30;:::i

Swarm Source

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