ETH Price: $2,543.61 (+4.36%)

Token

Wrapped Optix (WOPTIX)
 

Overview

Max Total Supply

16 WOPTIX

Holders

14

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 WOPTIX
0x63Fca178f455bb421615C7CeB5D1B452FCFf16c8
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:
Woptix

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
No with 200 runs

Other Settings:
constantinople EvmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-10-06
*/

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

// File: 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: contracts/IERC721ABurnable.sol


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

pragma solidity ^0.8.4;


/**
 * @dev Interface of ERC721ABurnable.
 */
interface IERC721ABurnable is IERC721A {
    /**
     * @dev Burns `tokenId`. See {ERC721A-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) external;
}
// File: contracts/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: 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: contracts/ERC721ABurnable.sol


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

pragma solidity ^0.8.4;



/**
 * @title ERC721ABurnable.
 *
 * @dev ERC721A token that can be irreversibly burned (destroyed).
 */
abstract contract ERC721ABurnable is ERC721A, IERC721ABurnable {
    /**
     * @dev Burns `tokenId`. See {ERC721A-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) public virtual override {
        _burn(tokenId, true);
    }
}
// File: contracts/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/Strings.sol


// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

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


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

pragma solidity ^0.8.0;

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

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

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


// OpenZeppelin Contracts (last updated v4.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: contracts/Woptix.sol


pragma solidity ^0.8.4;







contract Woptix is ERC721A, ERC721AQueryable, ERC721ABurnable, Ownable {

    string metadataPath = "https://universe.theblinkless.com/woptixjson/";
    address public payoutWallet = 0xeD2faa60373eC70E57B39152aeE5Ce4ed7C333c7; //wallet for payouts
    address public optixContract = 0xa93fce39D926527Af68B8520FB55e2f74D9201b5; // optix contract address
    mapping(uint256 => uint256) public tokenList; //token_id => amount wrapped in wei
    mapping(uint256 => uint256) public validWrappers; // wei => ether / list of valid wrappers
    uint256 public wrappingFee = 0.002 ether;
    uint256 public canWrap = 1; // turn on/off wrapping

    constructor() ERC721A("Wrapped Optix", "WOPTIX") {
        validWrappers[1000000000000000000000] = 1000;
        validWrappers[10000000000000000000000] = 10000;
        validWrappers[100000000000000000000000] = 100000;
        validWrappers[250000000000000000000000] = 250000;
        validWrappers[500000000000000000000000] = 500000;
        validWrappers[1000000000000000000000000] = 1000000;
    }


    function isValidWrapper(uint256 _amount) public view returns(bool isIndeed) {
        return validWrappers[_amount] != 0;
    }

    function wrapOptix(uint256 _amount) public payable{
        //ensure mint is active
        require(canWrap == 1, "Wrapping currently disabled.");
        
        //ensure payment is valid
        require(msg.value >= wrappingFee);

        //ensure only allowed wrappers are minted
        require(isValidWrapper(_amount), "Not a valid wrapper");

        //transfer payment
        (bool success, ) = payable(payoutWallet).call{value: address(this).balance}("");
        require(success, "Transfer failed.");

        //transfer optix for mint (must have approval already!)
        IERC20(optixContract).transferFrom(msg.sender,address(this),_amount );

        //add to tokenList
        tokenList[_nextTokenId()] = _amount;

        // mint the tokens
        _mint(msg.sender, 1);

        
    }


    function unwrapOptix(uint256 _tokenId) public payable{
        //make sure they own the nft
        require(ownerOf(_tokenId) == msg.sender, "Must own the NFT to unwrap!");

         //ensure payment is valid
        require(msg.value >= wrappingFee);

        //transfer payment
        (bool success, ) = payable(payoutWallet).call{value: address(this).balance}("");
        require(success, "Transfer failed.");

        //burn the nft
        burn(_tokenId);

        //transfer optix for mint (must have approval already!)
        IERC20(optixContract).transfer(msg.sender, tokenList[_tokenId] );      
          
    }

    /**
    * Return metadata path
    */
    function tokenURI(uint tokenId) override(ERC721A,IERC721A) public view returns(string memory _uri){
    
        return string.concat(metadataPath,Strings.toString(tokenList[tokenId]),".json");
    } 

    /**
    * Update the wrapping fee
    */
    function updateWrappingFee(uint256 _fee) public onlyOwner{
        wrappingFee = _fee;
    }

    /**
    * Update mint status
    */
    function updateCanWrap(uint256 _canWrap) public onlyOwner{
        canWrap = _canWrap;
    }

    /**
    * Add to valid wrappers
    */
    function addToValidWrappers(uint256 _wei, uint256 _ether) public onlyOwner{
        validWrappers[_wei] = _ether;
    }



    /**
    * Update the metadata path
    */
    function updateMetadataPath(string memory _path) public onlyOwner{
        metadataPath = _path;
    }

    /**
    * Update the optix address
    */
     function updateOptixContract(address _contract) public onlyOwner{
        optixContract = _contract;
    }

    /**
    * Update the payout wallet address
    */
    function updatePayoutWallet(address _payoutWallet) public onlyOwner{
        payoutWallet = _payoutWallet;
    }

     /*
    * Withdraw by owner
    */
    function withdraw() external onlyOwner {
        (bool success, ) = payable(payoutWallet).call{value: address(this).balance}("");
        require(success, "Transfer failed.");
    }



    /*
    * These are here to receive ETH sent to the contract address
    */
    receive() external payable {}

    fallback() external payable {}
}

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":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"uint256","name":"_wei","type":"uint256"},{"internalType":"uint256","name":"_ether","type":"uint256"}],"name":"addToValidWrappers","outputs":[],"stateMutability":"nonpayable","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":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"canWrap","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":"_amount","type":"uint256"}],"name":"isValidWrapper","outputs":[{"internalType":"bool","name":"isIndeed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"optixContract","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"payoutWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenList","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"_uri","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":"uint256","name":"_tokenId","type":"uint256"}],"name":"unwrapOptix","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_canWrap","type":"uint256"}],"name":"updateCanWrap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_path","type":"string"}],"name":"updateMetadataPath","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"}],"name":"updateOptixContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_payoutWallet","type":"address"}],"name":"updatePayoutWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"updateWrappingFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"validWrappers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"wrapOptix","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"wrappingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040526040518060600160405280602d815260200162004698602d9139600990816200002e9190620005ed565b5073ed2faa60373ec70e57b39152aee5ce4ed7c333c7600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555073a93fce39d926527af68b8520fb55e2f74d9201b5600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555066071afd498d0000600e556001600f55348015620000f657600080fd5b506040518060400160405280600d81526020017f57726170706564204f70746978000000000000000000000000000000000000008152506040518060400160405280600681526020017f574f5054495800000000000000000000000000000000000000000000000000008152508160029081620001749190620005ed565b508060039081620001869190620005ed565b5062000197620002a060201b60201c565b6000819055505050620001bf620001b3620002a560201b60201c565b620002ad60201b60201c565b6103e8600d6000683635c9adc5dea00000815260200190815260200160002081905550612710600d600069021e19e0c9bab2400000815260200190815260200160002081905550620186a0600d600069152d02c7e14af68000008152602001908152602001600020819055506203d090600d60006934f086f3b33b684000008152602001908152602001600020819055506207a120600d60006969e10de76676d0800000815260200190815260200160002081905550620f4240600d600069d3c21bcecceda1000000815260200190815260200160002081905550620006d4565b600090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620003f557607f821691505b6020821081036200040b576200040a620003ad565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620004757fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000436565b62000481868362000436565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620004ce620004c8620004c28462000499565b620004a3565b62000499565b9050919050565b6000819050919050565b620004ea83620004ad565b62000502620004f982620004d5565b84845462000443565b825550505050565b600090565b620005196200050a565b62000526818484620004df565b505050565b5b818110156200054e57620005426000826200050f565b6001810190506200052c565b5050565b601f8211156200059d57620005678162000411565b620005728462000426565b8101602085101562000582578190505b6200059a620005918562000426565b8301826200052b565b50505b505050565b600082821c905092915050565b6000620005c260001984600802620005a2565b1980831691505092915050565b6000620005dd8383620005af565b9150826002028217905092915050565b620005f88262000373565b67ffffffffffffffff8111156200061457620006136200037e565b5b620006208254620003dc565b6200062d82828562000552565b600060209050601f83116001811462000665576000841562000650578287015190505b6200065c8582620005cf565b865550620006cc565b601f198416620006758662000411565b60005b828110156200069f5784890151825560018201915060208501945060208101905062000678565b86831015620006bf5784890151620006bb601f891682620005af565b8355505b6001600288020188555050505b505050505050565b613fb480620006e46000396000f3fe6080604052600436106102295760003560e01c80636004ebfd116101235780639ead7222116100ab578063c87b56dd1161006f578063c87b56dd146107e1578063ca3f3e161461081e578063e485018e14610847578063e985e9c514610884578063f2fde38b146108c157610230565b80639ead7222146106f7578063a22cb46514610734578063b88d4fde1461075d578063c23dc68f14610779578063c733bb20146107b657610230565b80638462151c116100f25780638462151c146105fc5780638488bb4e146106395780638da5cb5b1461066457806395d89b411461068f57806399a2557a146106ba57610230565b80636004ebfd1461052e5780636352211e1461056b57806370a08231146105a8578063715018a6146105e557610230565b806323b872dd116101b157806342966c681161017557806342966c681461045a57806355d5204c1461048357806356cd40f8146104ac5780635bbb2177146104c85780635c3d25ca1461050557610230565b806323b872dd146103b757806338911230146103d35780633ccfd60b146103fc5780633db3f4df1461041357806342842e0e1461043e57610230565b806311b7cdf3116101f857806311b7cdf3146102f357806311c544f61461031c578063144b4c451461034557806315e519a01461037057806318160ddd1461038c57610230565b806301ffc9a71461023257806306fdde031461026f578063081812fc1461029a578063095ea7b3146102d757610230565b3661023057005b005b34801561023e57600080fd5b5061025960048036038101906102549190612b23565b6108ea565b6040516102669190612b6b565b60405180910390f35b34801561027b57600080fd5b5061028461097c565b6040516102919190612c16565b60405180910390f35b3480156102a657600080fd5b506102c160048036038101906102bc9190612c6e565b610a0e565b6040516102ce9190612cdc565b60405180910390f35b6102f160048036038101906102ec9190612d23565b610a8d565b005b3480156102ff57600080fd5b5061031a60048036038101906103159190612c6e565b610bd1565b005b34801561032857600080fd5b50610343600480360381019061033e9190612d63565b610be3565b005b34801561035157600080fd5b5061035a610c07565b6040516103679190612db2565b60405180910390f35b61038a60048036038101906103859190612c6e565b610c0d565b005b34801561039857600080fd5b506103a1610e38565b6040516103ae9190612db2565b60405180910390f35b6103d160048036038101906103cc9190612dcd565b610e4f565b005b3480156103df57600080fd5b506103fa60048036038101906103f59190612c6e565b611171565b005b34801561040857600080fd5b50610411611183565b005b34801561041f57600080fd5b50610428611273565b6040516104359190612db2565b60405180910390f35b61045860048036038101906104539190612dcd565b611279565b005b34801561046657600080fd5b50610481600480360381019061047c9190612c6e565b611299565b005b34801561048f57600080fd5b506104aa60048036038101906104a59190612f55565b6112a7565b005b6104c660048036038101906104c19190612c6e565b6112c2565b005b3480156104d457600080fd5b506104ef60048036038101906104ea9190612ffe565b611514565b6040516104fc91906131ae565b60405180910390f35b34801561051157600080fd5b5061052c600480360381019061052791906131d0565b6115d7565b005b34801561053a57600080fd5b5061055560048036038101906105509190612c6e565b611623565b6040516105629190612db2565b60405180910390f35b34801561057757600080fd5b50610592600480360381019061058d9190612c6e565b61163b565b60405161059f9190612cdc565b60405180910390f35b3480156105b457600080fd5b506105cf60048036038101906105ca91906131d0565b61164d565b6040516105dc9190612db2565b60405180910390f35b3480156105f157600080fd5b506105fa611705565b005b34801561060857600080fd5b50610623600480360381019061061e91906131d0565b611719565b60405161063091906132bb565b60405180910390f35b34801561064557600080fd5b5061064e61185c565b60405161065b9190612cdc565b60405180910390f35b34801561067057600080fd5b50610679611882565b6040516106869190612cdc565b60405180910390f35b34801561069b57600080fd5b506106a46118ac565b6040516106b19190612c16565b60405180910390f35b3480156106c657600080fd5b506106e160048036038101906106dc91906132dd565b61193e565b6040516106ee91906132bb565b60405180910390f35b34801561070357600080fd5b5061071e60048036038101906107199190612c6e565b611b4a565b60405161072b9190612db2565b60405180910390f35b34801561074057600080fd5b5061075b6004803603810190610756919061335c565b611b62565b005b6107776004803603810190610772919061343d565b611c6d565b005b34801561078557600080fd5b506107a0600480360381019061079b9190612c6e565b611ce0565b6040516107ad9190613515565b60405180910390f35b3480156107c257600080fd5b506107cb611d4a565b6040516107d89190612cdc565b60405180910390f35b3480156107ed57600080fd5b5061080860048036038101906108039190612c6e565b611d70565b6040516108159190612c16565b60405180910390f35b34801561082a57600080fd5b50610845600480360381019061084091906131d0565b611db7565b005b34801561085357600080fd5b5061086e60048036038101906108699190612c6e565b611e03565b60405161087b9190612b6b565b60405180910390f35b34801561089057600080fd5b506108ab60048036038101906108a69190613530565b611e23565b6040516108b89190612b6b565b60405180910390f35b3480156108cd57600080fd5b506108e860048036038101906108e391906131d0565b611eb7565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061094557506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806109755750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461098b9061359f565b80601f01602080910402602001604051908101604052809291908181526020018280546109b79061359f565b8015610a045780601f106109d957610100808354040283529160200191610a04565b820191906000526020600020905b8154815290600101906020018083116109e757829003601f168201915b5050505050905090565b6000610a1982611f3a565b610a4f576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a988261163b565b90508073ffffffffffffffffffffffffffffffffffffffff16610ab9611f99565b73ffffffffffffffffffffffffffffffffffffffff1614610b1c57610ae581610ae0611f99565b611e23565b610b1b576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b610bd9611fa1565b80600f8190555050565b610beb611fa1565b80600d6000848152602001908152602001600020819055505050565b600e5481565b3373ffffffffffffffffffffffffffffffffffffffff16610c2d8261163b565b73ffffffffffffffffffffffffffffffffffffffff1614610c83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c7a9061361c565b60405180910390fd5b600e54341015610c9257600080fd5b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1631604051610cf19061366d565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b5050905080610d77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6e906136ce565b60405180910390fd5b610d8082611299565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33600c6000868152602001908152602001600020546040518363ffffffff1660e01b8152600401610df09291906136ee565b6020604051808303816000875af1158015610e0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e33919061372c565b505050565b6000610e4261201f565b6001546000540303905090565b6000610e5a82612024565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610ec1576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610ecd846120f0565b91509150610ee38187610ede611f99565b612117565b610f2f57610ef886610ef3611f99565b611e23565b610f2e576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610f95576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610fa2868686600161215b565b8015610fad57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001019190508190555061107b85611057888887612161565b7c020000000000000000000000000000000000000000000000000000000017612189565b600460008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084160361110157600060018501905060006004600083815260200190815260200160002054036110ff5760005481146110fe578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461116986868660016121b4565b505050505050565b611179611fa1565b80600e8190555050565b61118b611fa1565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16316040516111ea9061366d565b60006040518083038185875af1925050503d8060008114611227576040519150601f19603f3d011682016040523d82523d6000602084013e61122c565b606091505b5050905080611270576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611267906136ce565b60405180910390fd5b50565b600f5481565b61129483838360405180602001604052806000815250611c6d565b505050565b6112a48160016121ba565b50565b6112af611fa1565b80600990816112be9190613905565b5050565b6001600f5414611307576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112fe90613a23565b60405180910390fd5b600e5434101561131657600080fd5b61131f81611e03565b61135e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135590613a8f565b60405180910390fd5b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16316040516113bd9061366d565b60006040518083038185875af1925050503d80600081146113fa576040519150601f19603f3d011682016040523d82523d6000602084013e6113ff565b606091505b5050905080611443576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161143a906136ce565b60405180910390fd5b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b81526004016114a293929190613aaf565b6020604051808303816000875af11580156114c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e5919061372c565b5081600c60006114f361240c565b815260200190815260200160002081905550611510336001612415565b5050565b6060600083839050905060008167ffffffffffffffff81111561153a57611539612e2a565b5b60405190808252806020026020018201604052801561157357816020015b611560612a68565b8152602001906001900390816115585790505b50905060005b8281146115cb576115a286868381811061159657611595613ae6565b5b90506020020135611ce0565b8282815181106115b5576115b4613ae6565b5b6020026020010181905250806001019050611579565b50809250505092915050565b6115df611fa1565b80600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600d6020528060005260406000206000915090505481565b600061164682612024565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036116b4576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b61170d611fa1565b61171760006125d0565b565b606060008060006117298561164d565b905060008167ffffffffffffffff81111561174757611746612e2a565b5b6040519080825280602002602001820160405280156117755781602001602082028036833780820191505090505b509050611780612a68565b600061178a61201f565b90505b83861461184e5761179d81612696565b9150816040015161184357600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff16146117e857816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611842578083878060010198508151811061183557611834613ae6565b5b6020026020010181815250505b5b80600101905061178d565b508195505050505050919050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600380546118bb9061359f565b80601f01602080910402602001604051908101604052809291908181526020018280546118e79061359f565b80156119345780601f1061190957610100808354040283529160200191611934565b820191906000526020600020905b81548152906001019060200180831161191757829003601f168201915b5050505050905090565b6060818310611979576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061198461240c565b905061198e61201f565b8510156119a05761199d61201f565b94505b808411156119ac578093505b60006119b78761164d565b9050848610156119da5760008686039050818110156119d4578091505b506119df565b600090505b60008167ffffffffffffffff8111156119fb576119fa612e2a565b5b604051908082528060200260200182016040528015611a295781602001602082028036833780820191505090505b50905060008203611a405780945050505050611b43565b6000611a4b88611ce0565b905060008160400151611a6057816000015190505b60008990505b888114158015611a765750848714155b15611b3557611a8481612696565b92508260400151611b2a57600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614611acf57826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611b295780848880600101995081518110611b1c57611b1b613ae6565b5b6020026020010181815250505b5b806001019050611a66565b508583528296505050505050505b9392505050565b600c6020528060005260406000206000915090505481565b8060076000611b6f611f99565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611c1c611f99565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611c619190612b6b565b60405180910390a35050565b611c78848484610e4f565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611cda57611ca3848484846126c1565b611cd9576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b611ce8612a68565b611cf0612a68565b611cf861201f565b831080611d0c5750611d0861240c565b8310155b15611d1a5780915050611d45565b611d2383612696565b9050806040015115611d385780915050611d45565b611d4183612811565b9150505b919050565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60606009611d90600c600085815260200190815260200160002054612831565b604051602001611da1929190613bfa565b6040516020818303038152906040529050919050565b611dbf611fa1565b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600d60008481526020019081526020016000205414159050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611ebf611fa1565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611f2e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f2590613c9f565b60405180910390fd5b611f37816125d0565b50565b600081611f4561201f565b11158015611f54575060005482105b8015611f92575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b611fa9612991565b73ffffffffffffffffffffffffffffffffffffffff16611fc7611882565b73ffffffffffffffffffffffffffffffffffffffff161461201d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161201490613d0b565b60405180910390fd5b565b600090565b6000808290508061203361201f565b116120b9576000548110156120b85760006004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036120b6575b600081036120ac576004600083600190039350838152602001908152602001600020549050612082565b80925050506120eb565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8612178868684612999565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b60006121c583612024565b905060008190506000806121d8866120f0565b915091508415612241576121f481846121ef611f99565b612117565b6122405761220983612204611f99565b611e23565b61223f576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b61224f83600088600161215b565b801561225a57600082555b600160806001901b03600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612302836122bf85600088612161565b7c02000000000000000000000000000000000000000000000000000000007c01000000000000000000000000000000000000000000000000000000001717612189565b600460008881526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008516036123885760006001870190506000600460008381526020019081526020016000205403612386576000548114612385578460046000838152602001908152602001600020819055505b5b505b85600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46123f28360008860016121b4565b600160008154809291906001019190505550505050505050565b60008054905090565b60008054905060008203612455576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612462600084838561215b565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055506124d9836124ca6000866000612161565b6124d3856129a2565b17612189565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461257a57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460018101905061253f565b50600082036125b5576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060008190555050506125cb60008483856121b4565b505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61269e612a68565b6126ba60046000848152602001908152602001600020546129b2565b9050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026126e7611f99565b8786866040518563ffffffff1660e01b81526004016127099493929190613d80565b6020604051808303816000875af192505050801561274557506040513d601f19601f820116820180604052508101906127429190613de1565b60015b6127be573d8060008114612775576040519150601f19603f3d011682016040523d82523d6000602084013e61277a565b606091505b5060008151036127b6576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b612819612a68565b61282a61282583612024565b6129b2565b9050919050565b606060008203612878576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061298c565b600082905060005b600082146128aa57808061289390613e3d565b915050600a826128a39190613eb4565b9150612880565b60008167ffffffffffffffff8111156128c6576128c5612e2a565b5b6040519080825280601f01601f1916602001820160405280156128f85781602001600182028036833780820191505090505b5090505b60008514612985576001826129119190613ee5565b9150600a856129209190613f19565b603061292c9190613f4a565b60f81b81838151811061294257612941613ae6565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561297e9190613eb4565b94506128fc565b8093505050505b919050565b600033905090565b60009392505050565b60006001821460e11b9050919050565b6129ba612a68565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612b0081612acb565b8114612b0b57600080fd5b50565b600081359050612b1d81612af7565b92915050565b600060208284031215612b3957612b38612ac1565b5b6000612b4784828501612b0e565b91505092915050565b60008115159050919050565b612b6581612b50565b82525050565b6000602082019050612b806000830184612b5c565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612bc0578082015181840152602081019050612ba5565b60008484015250505050565b6000601f19601f8301169050919050565b6000612be882612b86565b612bf28185612b91565b9350612c02818560208601612ba2565b612c0b81612bcc565b840191505092915050565b60006020820190508181036000830152612c308184612bdd565b905092915050565b6000819050919050565b612c4b81612c38565b8114612c5657600080fd5b50565b600081359050612c6881612c42565b92915050565b600060208284031215612c8457612c83612ac1565b5b6000612c9284828501612c59565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612cc682612c9b565b9050919050565b612cd681612cbb565b82525050565b6000602082019050612cf16000830184612ccd565b92915050565b612d0081612cbb565b8114612d0b57600080fd5b50565b600081359050612d1d81612cf7565b92915050565b60008060408385031215612d3a57612d39612ac1565b5b6000612d4885828601612d0e565b9250506020612d5985828601612c59565b9150509250929050565b60008060408385031215612d7a57612d79612ac1565b5b6000612d8885828601612c59565b9250506020612d9985828601612c59565b9150509250929050565b612dac81612c38565b82525050565b6000602082019050612dc76000830184612da3565b92915050565b600080600060608486031215612de657612de5612ac1565b5b6000612df486828701612d0e565b9350506020612e0586828701612d0e565b9250506040612e1686828701612c59565b9150509250925092565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e6282612bcc565b810181811067ffffffffffffffff82111715612e8157612e80612e2a565b5b80604052505050565b6000612e94612ab7565b9050612ea08282612e59565b919050565b600067ffffffffffffffff821115612ec057612ebf612e2a565b5b612ec982612bcc565b9050602081019050919050565b82818337600083830152505050565b6000612ef8612ef384612ea5565b612e8a565b905082815260208101848484011115612f1457612f13612e25565b5b612f1f848285612ed6565b509392505050565b600082601f830112612f3c57612f3b612e20565b5b8135612f4c848260208601612ee5565b91505092915050565b600060208284031215612f6b57612f6a612ac1565b5b600082013567ffffffffffffffff811115612f8957612f88612ac6565b5b612f9584828501612f27565b91505092915050565b600080fd5b600080fd5b60008083601f840112612fbe57612fbd612e20565b5b8235905067ffffffffffffffff811115612fdb57612fda612f9e565b5b602083019150836020820283011115612ff757612ff6612fa3565b5b9250929050565b6000806020838503121561301557613014612ac1565b5b600083013567ffffffffffffffff81111561303357613032612ac6565b5b61303f85828601612fa8565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61308081612cbb565b82525050565b600067ffffffffffffffff82169050919050565b6130a381613086565b82525050565b6130b281612b50565b82525050565b600062ffffff82169050919050565b6130d0816130b8565b82525050565b6080820160008201516130ec6000850182613077565b5060208201516130ff602085018261309a565b50604082015161311260408501826130a9565b50606082015161312560608501826130c7565b50505050565b600061313783836130d6565b60808301905092915050565b6000602082019050919050565b600061315b8261304b565b6131658185613056565b935061317083613067565b8060005b838110156131a1578151613188888261312b565b975061319383613143565b925050600181019050613174565b5085935050505092915050565b600060208201905081810360008301526131c88184613150565b905092915050565b6000602082840312156131e6576131e5612ac1565b5b60006131f484828501612d0e565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61323281612c38565b82525050565b60006132448383613229565b60208301905092915050565b6000602082019050919050565b6000613268826131fd565b6132728185613208565b935061327d83613219565b8060005b838110156132ae5781516132958882613238565b97506132a083613250565b925050600181019050613281565b5085935050505092915050565b600060208201905081810360008301526132d5818461325d565b905092915050565b6000806000606084860312156132f6576132f5612ac1565b5b600061330486828701612d0e565b935050602061331586828701612c59565b925050604061332686828701612c59565b9150509250925092565b61333981612b50565b811461334457600080fd5b50565b60008135905061335681613330565b92915050565b6000806040838503121561337357613372612ac1565b5b600061338185828601612d0e565b925050602061339285828601613347565b9150509250929050565b600067ffffffffffffffff8211156133b7576133b6612e2a565b5b6133c082612bcc565b9050602081019050919050565b60006133e06133db8461339c565b612e8a565b9050828152602081018484840111156133fc576133fb612e25565b5b613407848285612ed6565b509392505050565b600082601f83011261342457613423612e20565b5b81356134348482602086016133cd565b91505092915050565b6000806000806080858703121561345757613456612ac1565b5b600061346587828801612d0e565b945050602061347687828801612d0e565b935050604061348787828801612c59565b925050606085013567ffffffffffffffff8111156134a8576134a7612ac6565b5b6134b48782880161340f565b91505092959194509250565b6080820160008201516134d66000850182613077565b5060208201516134e9602085018261309a565b5060408201516134fc60408501826130a9565b50606082015161350f60608501826130c7565b50505050565b600060808201905061352a60008301846134c0565b92915050565b6000806040838503121561354757613546612ac1565b5b600061355585828601612d0e565b925050602061356685828601612d0e565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806135b757607f821691505b6020821081036135ca576135c9613570565b5b50919050565b7f4d757374206f776e20746865204e465420746f20756e77726170210000000000600082015250565b6000613606601b83612b91565b9150613611826135d0565b602082019050919050565b60006020820190508181036000830152613635816135f9565b9050919050565b600081905092915050565b50565b600061365760008361363c565b915061366282613647565b600082019050919050565b60006136788261364a565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b60006136b8601083612b91565b91506136c382613682565b602082019050919050565b600060208201905081810360008301526136e7816136ab565b9050919050565b60006040820190506137036000830185612ccd565b6137106020830184612da3565b9392505050565b60008151905061372681613330565b92915050565b60006020828403121561374257613741612ac1565b5b600061375084828501613717565b91505092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026137bb7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261377e565b6137c5868361377e565b95508019841693508086168417925050509392505050565b6000819050919050565b60006138026137fd6137f884612c38565b6137dd565b612c38565b9050919050565b6000819050919050565b61381c836137e7565b61383061382882613809565b84845461378b565b825550505050565b600090565b613845613838565b613850818484613813565b505050565b5b818110156138745761386960008261383d565b600181019050613856565b5050565b601f8211156138b95761388a81613759565b6138938461376e565b810160208510156138a2578190505b6138b66138ae8561376e565b830182613855565b50505b505050565b600082821c905092915050565b60006138dc600019846008026138be565b1980831691505092915050565b60006138f583836138cb565b9150826002028217905092915050565b61390e82612b86565b67ffffffffffffffff81111561392757613926612e2a565b5b613931825461359f565b61393c828285613878565b600060209050601f83116001811461396f576000841561395d578287015190505b61396785826138e9565b8655506139cf565b601f19841661397d86613759565b60005b828110156139a557848901518255600182019150602085019450602081019050613980565b868310156139c257848901516139be601f8916826138cb565b8355505b6001600288020188555050505b505050505050565b7f5772617070696e672063757272656e746c792064697361626c65642e00000000600082015250565b6000613a0d601c83612b91565b9150613a18826139d7565b602082019050919050565b60006020820190508181036000830152613a3c81613a00565b9050919050565b7f4e6f7420612076616c6964207772617070657200000000000000000000000000600082015250565b6000613a79601383612b91565b9150613a8482613a43565b602082019050919050565b60006020820190508181036000830152613aa881613a6c565b9050919050565b6000606082019050613ac46000830186612ccd565b613ad16020830185612ccd565b613ade6040830184612da3565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081905092915050565b60008154613b2d8161359f565b613b378186613b15565b94506001821660008114613b525760018114613b6757613b9a565b60ff1983168652811515820286019350613b9a565b613b7085613759565b60005b83811015613b9257815481890152600182019150602081019050613b73565b838801955050505b50505092915050565b6000613bae82612b86565b613bb88185613b15565b9350613bc8818560208601612ba2565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000815250565b6000613c068285613b20565b9150613c128284613ba3565b9150613c1d82613bd4565b6005820191508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613c89602683612b91565b9150613c9482613c2d565b604082019050919050565b60006020820190508181036000830152613cb881613c7c565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613cf5602083612b91565b9150613d0082613cbf565b602082019050919050565b60006020820190508181036000830152613d2481613ce8565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000613d5282613d2b565b613d5c8185613d36565b9350613d6c818560208601612ba2565b613d7581612bcc565b840191505092915050565b6000608082019050613d956000830187612ccd565b613da26020830186612ccd565b613daf6040830185612da3565b8181036060830152613dc18184613d47565b905095945050505050565b600081519050613ddb81612af7565b92915050565b600060208284031215613df757613df6612ac1565b5b6000613e0584828501613dcc565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613e4882612c38565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613e7a57613e79613e0e565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613ebf82612c38565b9150613eca83612c38565b925082613eda57613ed9613e85565b5b828204905092915050565b6000613ef082612c38565b9150613efb83612c38565b9250828203905081811115613f1357613f12613e0e565b5b92915050565b6000613f2482612c38565b9150613f2f83612c38565b925082613f3f57613f3e613e85565b5b828206905092915050565b6000613f5582612c38565b9150613f6083612c38565b9250828201905080821115613f7857613f77613e0e565b5b9291505056fea264697066735822122037df7f79cb4aef1b7397ae8e4f6048f737faa037097f6c2290d39d69fc688dff64736f6c6343000811003368747470733a2f2f756e6976657273652e746865626c696e6b6c6573732e636f6d2f776f707469786a736f6e2f

Deployed Bytecode

0x6080604052600436106102295760003560e01c80636004ebfd116101235780639ead7222116100ab578063c87b56dd1161006f578063c87b56dd146107e1578063ca3f3e161461081e578063e485018e14610847578063e985e9c514610884578063f2fde38b146108c157610230565b80639ead7222146106f7578063a22cb46514610734578063b88d4fde1461075d578063c23dc68f14610779578063c733bb20146107b657610230565b80638462151c116100f25780638462151c146105fc5780638488bb4e146106395780638da5cb5b1461066457806395d89b411461068f57806399a2557a146106ba57610230565b80636004ebfd1461052e5780636352211e1461056b57806370a08231146105a8578063715018a6146105e557610230565b806323b872dd116101b157806342966c681161017557806342966c681461045a57806355d5204c1461048357806356cd40f8146104ac5780635bbb2177146104c85780635c3d25ca1461050557610230565b806323b872dd146103b757806338911230146103d35780633ccfd60b146103fc5780633db3f4df1461041357806342842e0e1461043e57610230565b806311b7cdf3116101f857806311b7cdf3146102f357806311c544f61461031c578063144b4c451461034557806315e519a01461037057806318160ddd1461038c57610230565b806301ffc9a71461023257806306fdde031461026f578063081812fc1461029a578063095ea7b3146102d757610230565b3661023057005b005b34801561023e57600080fd5b5061025960048036038101906102549190612b23565b6108ea565b6040516102669190612b6b565b60405180910390f35b34801561027b57600080fd5b5061028461097c565b6040516102919190612c16565b60405180910390f35b3480156102a657600080fd5b506102c160048036038101906102bc9190612c6e565b610a0e565b6040516102ce9190612cdc565b60405180910390f35b6102f160048036038101906102ec9190612d23565b610a8d565b005b3480156102ff57600080fd5b5061031a60048036038101906103159190612c6e565b610bd1565b005b34801561032857600080fd5b50610343600480360381019061033e9190612d63565b610be3565b005b34801561035157600080fd5b5061035a610c07565b6040516103679190612db2565b60405180910390f35b61038a60048036038101906103859190612c6e565b610c0d565b005b34801561039857600080fd5b506103a1610e38565b6040516103ae9190612db2565b60405180910390f35b6103d160048036038101906103cc9190612dcd565b610e4f565b005b3480156103df57600080fd5b506103fa60048036038101906103f59190612c6e565b611171565b005b34801561040857600080fd5b50610411611183565b005b34801561041f57600080fd5b50610428611273565b6040516104359190612db2565b60405180910390f35b61045860048036038101906104539190612dcd565b611279565b005b34801561046657600080fd5b50610481600480360381019061047c9190612c6e565b611299565b005b34801561048f57600080fd5b506104aa60048036038101906104a59190612f55565b6112a7565b005b6104c660048036038101906104c19190612c6e565b6112c2565b005b3480156104d457600080fd5b506104ef60048036038101906104ea9190612ffe565b611514565b6040516104fc91906131ae565b60405180910390f35b34801561051157600080fd5b5061052c600480360381019061052791906131d0565b6115d7565b005b34801561053a57600080fd5b5061055560048036038101906105509190612c6e565b611623565b6040516105629190612db2565b60405180910390f35b34801561057757600080fd5b50610592600480360381019061058d9190612c6e565b61163b565b60405161059f9190612cdc565b60405180910390f35b3480156105b457600080fd5b506105cf60048036038101906105ca91906131d0565b61164d565b6040516105dc9190612db2565b60405180910390f35b3480156105f157600080fd5b506105fa611705565b005b34801561060857600080fd5b50610623600480360381019061061e91906131d0565b611719565b60405161063091906132bb565b60405180910390f35b34801561064557600080fd5b5061064e61185c565b60405161065b9190612cdc565b60405180910390f35b34801561067057600080fd5b50610679611882565b6040516106869190612cdc565b60405180910390f35b34801561069b57600080fd5b506106a46118ac565b6040516106b19190612c16565b60405180910390f35b3480156106c657600080fd5b506106e160048036038101906106dc91906132dd565b61193e565b6040516106ee91906132bb565b60405180910390f35b34801561070357600080fd5b5061071e60048036038101906107199190612c6e565b611b4a565b60405161072b9190612db2565b60405180910390f35b34801561074057600080fd5b5061075b6004803603810190610756919061335c565b611b62565b005b6107776004803603810190610772919061343d565b611c6d565b005b34801561078557600080fd5b506107a0600480360381019061079b9190612c6e565b611ce0565b6040516107ad9190613515565b60405180910390f35b3480156107c257600080fd5b506107cb611d4a565b6040516107d89190612cdc565b60405180910390f35b3480156107ed57600080fd5b5061080860048036038101906108039190612c6e565b611d70565b6040516108159190612c16565b60405180910390f35b34801561082a57600080fd5b50610845600480360381019061084091906131d0565b611db7565b005b34801561085357600080fd5b5061086e60048036038101906108699190612c6e565b611e03565b60405161087b9190612b6b565b60405180910390f35b34801561089057600080fd5b506108ab60048036038101906108a69190613530565b611e23565b6040516108b89190612b6b565b60405180910390f35b3480156108cd57600080fd5b506108e860048036038101906108e391906131d0565b611eb7565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061094557506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806109755750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461098b9061359f565b80601f01602080910402602001604051908101604052809291908181526020018280546109b79061359f565b8015610a045780601f106109d957610100808354040283529160200191610a04565b820191906000526020600020905b8154815290600101906020018083116109e757829003601f168201915b5050505050905090565b6000610a1982611f3a565b610a4f576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a988261163b565b90508073ffffffffffffffffffffffffffffffffffffffff16610ab9611f99565b73ffffffffffffffffffffffffffffffffffffffff1614610b1c57610ae581610ae0611f99565b611e23565b610b1b576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b610bd9611fa1565b80600f8190555050565b610beb611fa1565b80600d6000848152602001908152602001600020819055505050565b600e5481565b3373ffffffffffffffffffffffffffffffffffffffff16610c2d8261163b565b73ffffffffffffffffffffffffffffffffffffffff1614610c83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c7a9061361c565b60405180910390fd5b600e54341015610c9257600080fd5b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1631604051610cf19061366d565b60006040518083038185875af1925050503d8060008114610d2e576040519150601f19603f3d011682016040523d82523d6000602084013e610d33565b606091505b5050905080610d77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6e906136ce565b60405180910390fd5b610d8082611299565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33600c6000868152602001908152602001600020546040518363ffffffff1660e01b8152600401610df09291906136ee565b6020604051808303816000875af1158015610e0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e33919061372c565b505050565b6000610e4261201f565b6001546000540303905090565b6000610e5a82612024565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610ec1576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610ecd846120f0565b91509150610ee38187610ede611f99565b612117565b610f2f57610ef886610ef3611f99565b611e23565b610f2e576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610f95576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610fa2868686600161215b565b8015610fad57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001019190508190555061107b85611057888887612161565b7c020000000000000000000000000000000000000000000000000000000017612189565b600460008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084160361110157600060018501905060006004600083815260200190815260200160002054036110ff5760005481146110fe578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461116986868660016121b4565b505050505050565b611179611fa1565b80600e8190555050565b61118b611fa1565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16316040516111ea9061366d565b60006040518083038185875af1925050503d8060008114611227576040519150601f19603f3d011682016040523d82523d6000602084013e61122c565b606091505b5050905080611270576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611267906136ce565b60405180910390fd5b50565b600f5481565b61129483838360405180602001604052806000815250611c6d565b505050565b6112a48160016121ba565b50565b6112af611fa1565b80600990816112be9190613905565b5050565b6001600f5414611307576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112fe90613a23565b60405180910390fd5b600e5434101561131657600080fd5b61131f81611e03565b61135e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135590613a8f565b60405180910390fd5b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16316040516113bd9061366d565b60006040518083038185875af1925050503d80600081146113fa576040519150601f19603f3d011682016040523d82523d6000602084013e6113ff565b606091505b5050905080611443576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161143a906136ce565b60405180910390fd5b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b81526004016114a293929190613aaf565b6020604051808303816000875af11580156114c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e5919061372c565b5081600c60006114f361240c565b815260200190815260200160002081905550611510336001612415565b5050565b6060600083839050905060008167ffffffffffffffff81111561153a57611539612e2a565b5b60405190808252806020026020018201604052801561157357816020015b611560612a68565b8152602001906001900390816115585790505b50905060005b8281146115cb576115a286868381811061159657611595613ae6565b5b90506020020135611ce0565b8282815181106115b5576115b4613ae6565b5b6020026020010181905250806001019050611579565b50809250505092915050565b6115df611fa1565b80600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600d6020528060005260406000206000915090505481565b600061164682612024565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036116b4576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b61170d611fa1565b61171760006125d0565b565b606060008060006117298561164d565b905060008167ffffffffffffffff81111561174757611746612e2a565b5b6040519080825280602002602001820160405280156117755781602001602082028036833780820191505090505b509050611780612a68565b600061178a61201f565b90505b83861461184e5761179d81612696565b9150816040015161184357600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff16146117e857816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611842578083878060010198508151811061183557611834613ae6565b5b6020026020010181815250505b5b80600101905061178d565b508195505050505050919050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600380546118bb9061359f565b80601f01602080910402602001604051908101604052809291908181526020018280546118e79061359f565b80156119345780601f1061190957610100808354040283529160200191611934565b820191906000526020600020905b81548152906001019060200180831161191757829003601f168201915b5050505050905090565b6060818310611979576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061198461240c565b905061198e61201f565b8510156119a05761199d61201f565b94505b808411156119ac578093505b60006119b78761164d565b9050848610156119da5760008686039050818110156119d4578091505b506119df565b600090505b60008167ffffffffffffffff8111156119fb576119fa612e2a565b5b604051908082528060200260200182016040528015611a295781602001602082028036833780820191505090505b50905060008203611a405780945050505050611b43565b6000611a4b88611ce0565b905060008160400151611a6057816000015190505b60008990505b888114158015611a765750848714155b15611b3557611a8481612696565b92508260400151611b2a57600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614611acf57826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611b295780848880600101995081518110611b1c57611b1b613ae6565b5b6020026020010181815250505b5b806001019050611a66565b508583528296505050505050505b9392505050565b600c6020528060005260406000206000915090505481565b8060076000611b6f611f99565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611c1c611f99565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611c619190612b6b565b60405180910390a35050565b611c78848484610e4f565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611cda57611ca3848484846126c1565b611cd9576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b611ce8612a68565b611cf0612a68565b611cf861201f565b831080611d0c5750611d0861240c565b8310155b15611d1a5780915050611d45565b611d2383612696565b9050806040015115611d385780915050611d45565b611d4183612811565b9150505b919050565b600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60606009611d90600c600085815260200190815260200160002054612831565b604051602001611da1929190613bfa565b6040516020818303038152906040529050919050565b611dbf611fa1565b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600d60008481526020019081526020016000205414159050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611ebf611fa1565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611f2e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f2590613c9f565b60405180910390fd5b611f37816125d0565b50565b600081611f4561201f565b11158015611f54575060005482105b8015611f92575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b611fa9612991565b73ffffffffffffffffffffffffffffffffffffffff16611fc7611882565b73ffffffffffffffffffffffffffffffffffffffff161461201d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161201490613d0b565b60405180910390fd5b565b600090565b6000808290508061203361201f565b116120b9576000548110156120b85760006004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036120b6575b600081036120ac576004600083600190039350838152602001908152602001600020549050612082565b80925050506120eb565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8612178868684612999565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b60006121c583612024565b905060008190506000806121d8866120f0565b915091508415612241576121f481846121ef611f99565b612117565b6122405761220983612204611f99565b611e23565b61223f576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b61224f83600088600161215b565b801561225a57600082555b600160806001901b03600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612302836122bf85600088612161565b7c02000000000000000000000000000000000000000000000000000000007c01000000000000000000000000000000000000000000000000000000001717612189565b600460008881526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008516036123885760006001870190506000600460008381526020019081526020016000205403612386576000548114612385578460046000838152602001908152602001600020819055505b5b505b85600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46123f28360008860016121b4565b600160008154809291906001019190505550505050505050565b60008054905090565b60008054905060008203612455576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612462600084838561215b565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055506124d9836124ca6000866000612161565b6124d3856129a2565b17612189565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461257a57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460018101905061253f565b50600082036125b5576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060008190555050506125cb60008483856121b4565b505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61269e612a68565b6126ba60046000848152602001908152602001600020546129b2565b9050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026126e7611f99565b8786866040518563ffffffff1660e01b81526004016127099493929190613d80565b6020604051808303816000875af192505050801561274557506040513d601f19601f820116820180604052508101906127429190613de1565b60015b6127be573d8060008114612775576040519150601f19603f3d011682016040523d82523d6000602084013e61277a565b606091505b5060008151036127b6576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b612819612a68565b61282a61282583612024565b6129b2565b9050919050565b606060008203612878576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061298c565b600082905060005b600082146128aa57808061289390613e3d565b915050600a826128a39190613eb4565b9150612880565b60008167ffffffffffffffff8111156128c6576128c5612e2a565b5b6040519080825280601f01601f1916602001820160405280156128f85781602001600182028036833780820191505090505b5090505b60008514612985576001826129119190613ee5565b9150600a856129209190613f19565b603061292c9190613f4a565b60f81b81838151811061294257612941613ae6565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561297e9190613eb4565b94506128fc565b8093505050505b919050565b600033905090565b60009392505050565b60006001821460e11b9050919050565b6129ba612a68565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612b0081612acb565b8114612b0b57600080fd5b50565b600081359050612b1d81612af7565b92915050565b600060208284031215612b3957612b38612ac1565b5b6000612b4784828501612b0e565b91505092915050565b60008115159050919050565b612b6581612b50565b82525050565b6000602082019050612b806000830184612b5c565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612bc0578082015181840152602081019050612ba5565b60008484015250505050565b6000601f19601f8301169050919050565b6000612be882612b86565b612bf28185612b91565b9350612c02818560208601612ba2565b612c0b81612bcc565b840191505092915050565b60006020820190508181036000830152612c308184612bdd565b905092915050565b6000819050919050565b612c4b81612c38565b8114612c5657600080fd5b50565b600081359050612c6881612c42565b92915050565b600060208284031215612c8457612c83612ac1565b5b6000612c9284828501612c59565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612cc682612c9b565b9050919050565b612cd681612cbb565b82525050565b6000602082019050612cf16000830184612ccd565b92915050565b612d0081612cbb565b8114612d0b57600080fd5b50565b600081359050612d1d81612cf7565b92915050565b60008060408385031215612d3a57612d39612ac1565b5b6000612d4885828601612d0e565b9250506020612d5985828601612c59565b9150509250929050565b60008060408385031215612d7a57612d79612ac1565b5b6000612d8885828601612c59565b9250506020612d9985828601612c59565b9150509250929050565b612dac81612c38565b82525050565b6000602082019050612dc76000830184612da3565b92915050565b600080600060608486031215612de657612de5612ac1565b5b6000612df486828701612d0e565b9350506020612e0586828701612d0e565b9250506040612e1686828701612c59565b9150509250925092565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e6282612bcc565b810181811067ffffffffffffffff82111715612e8157612e80612e2a565b5b80604052505050565b6000612e94612ab7565b9050612ea08282612e59565b919050565b600067ffffffffffffffff821115612ec057612ebf612e2a565b5b612ec982612bcc565b9050602081019050919050565b82818337600083830152505050565b6000612ef8612ef384612ea5565b612e8a565b905082815260208101848484011115612f1457612f13612e25565b5b612f1f848285612ed6565b509392505050565b600082601f830112612f3c57612f3b612e20565b5b8135612f4c848260208601612ee5565b91505092915050565b600060208284031215612f6b57612f6a612ac1565b5b600082013567ffffffffffffffff811115612f8957612f88612ac6565b5b612f9584828501612f27565b91505092915050565b600080fd5b600080fd5b60008083601f840112612fbe57612fbd612e20565b5b8235905067ffffffffffffffff811115612fdb57612fda612f9e565b5b602083019150836020820283011115612ff757612ff6612fa3565b5b9250929050565b6000806020838503121561301557613014612ac1565b5b600083013567ffffffffffffffff81111561303357613032612ac6565b5b61303f85828601612fa8565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61308081612cbb565b82525050565b600067ffffffffffffffff82169050919050565b6130a381613086565b82525050565b6130b281612b50565b82525050565b600062ffffff82169050919050565b6130d0816130b8565b82525050565b6080820160008201516130ec6000850182613077565b5060208201516130ff602085018261309a565b50604082015161311260408501826130a9565b50606082015161312560608501826130c7565b50505050565b600061313783836130d6565b60808301905092915050565b6000602082019050919050565b600061315b8261304b565b6131658185613056565b935061317083613067565b8060005b838110156131a1578151613188888261312b565b975061319383613143565b925050600181019050613174565b5085935050505092915050565b600060208201905081810360008301526131c88184613150565b905092915050565b6000602082840312156131e6576131e5612ac1565b5b60006131f484828501612d0e565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61323281612c38565b82525050565b60006132448383613229565b60208301905092915050565b6000602082019050919050565b6000613268826131fd565b6132728185613208565b935061327d83613219565b8060005b838110156132ae5781516132958882613238565b97506132a083613250565b925050600181019050613281565b5085935050505092915050565b600060208201905081810360008301526132d5818461325d565b905092915050565b6000806000606084860312156132f6576132f5612ac1565b5b600061330486828701612d0e565b935050602061331586828701612c59565b925050604061332686828701612c59565b9150509250925092565b61333981612b50565b811461334457600080fd5b50565b60008135905061335681613330565b92915050565b6000806040838503121561337357613372612ac1565b5b600061338185828601612d0e565b925050602061339285828601613347565b9150509250929050565b600067ffffffffffffffff8211156133b7576133b6612e2a565b5b6133c082612bcc565b9050602081019050919050565b60006133e06133db8461339c565b612e8a565b9050828152602081018484840111156133fc576133fb612e25565b5b613407848285612ed6565b509392505050565b600082601f83011261342457613423612e20565b5b81356134348482602086016133cd565b91505092915050565b6000806000806080858703121561345757613456612ac1565b5b600061346587828801612d0e565b945050602061347687828801612d0e565b935050604061348787828801612c59565b925050606085013567ffffffffffffffff8111156134a8576134a7612ac6565b5b6134b48782880161340f565b91505092959194509250565b6080820160008201516134d66000850182613077565b5060208201516134e9602085018261309a565b5060408201516134fc60408501826130a9565b50606082015161350f60608501826130c7565b50505050565b600060808201905061352a60008301846134c0565b92915050565b6000806040838503121561354757613546612ac1565b5b600061355585828601612d0e565b925050602061356685828601612d0e565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806135b757607f821691505b6020821081036135ca576135c9613570565b5b50919050565b7f4d757374206f776e20746865204e465420746f20756e77726170210000000000600082015250565b6000613606601b83612b91565b9150613611826135d0565b602082019050919050565b60006020820190508181036000830152613635816135f9565b9050919050565b600081905092915050565b50565b600061365760008361363c565b915061366282613647565b600082019050919050565b60006136788261364a565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b60006136b8601083612b91565b91506136c382613682565b602082019050919050565b600060208201905081810360008301526136e7816136ab565b9050919050565b60006040820190506137036000830185612ccd565b6137106020830184612da3565b9392505050565b60008151905061372681613330565b92915050565b60006020828403121561374257613741612ac1565b5b600061375084828501613717565b91505092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026137bb7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261377e565b6137c5868361377e565b95508019841693508086168417925050509392505050565b6000819050919050565b60006138026137fd6137f884612c38565b6137dd565b612c38565b9050919050565b6000819050919050565b61381c836137e7565b61383061382882613809565b84845461378b565b825550505050565b600090565b613845613838565b613850818484613813565b505050565b5b818110156138745761386960008261383d565b600181019050613856565b5050565b601f8211156138b95761388a81613759565b6138938461376e565b810160208510156138a2578190505b6138b66138ae8561376e565b830182613855565b50505b505050565b600082821c905092915050565b60006138dc600019846008026138be565b1980831691505092915050565b60006138f583836138cb565b9150826002028217905092915050565b61390e82612b86565b67ffffffffffffffff81111561392757613926612e2a565b5b613931825461359f565b61393c828285613878565b600060209050601f83116001811461396f576000841561395d578287015190505b61396785826138e9565b8655506139cf565b601f19841661397d86613759565b60005b828110156139a557848901518255600182019150602085019450602081019050613980565b868310156139c257848901516139be601f8916826138cb565b8355505b6001600288020188555050505b505050505050565b7f5772617070696e672063757272656e746c792064697361626c65642e00000000600082015250565b6000613a0d601c83612b91565b9150613a18826139d7565b602082019050919050565b60006020820190508181036000830152613a3c81613a00565b9050919050565b7f4e6f7420612076616c6964207772617070657200000000000000000000000000600082015250565b6000613a79601383612b91565b9150613a8482613a43565b602082019050919050565b60006020820190508181036000830152613aa881613a6c565b9050919050565b6000606082019050613ac46000830186612ccd565b613ad16020830185612ccd565b613ade6040830184612da3565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081905092915050565b60008154613b2d8161359f565b613b378186613b15565b94506001821660008114613b525760018114613b6757613b9a565b60ff1983168652811515820286019350613b9a565b613b7085613759565b60005b83811015613b9257815481890152600182019150602081019050613b73565b838801955050505b50505092915050565b6000613bae82612b86565b613bb88185613b15565b9350613bc8818560208601612ba2565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000815250565b6000613c068285613b20565b9150613c128284613ba3565b9150613c1d82613bd4565b6005820191508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613c89602683612b91565b9150613c9482613c2d565b604082019050919050565b60006020820190508181036000830152613cb881613c7c565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613cf5602083612b91565b9150613d0082613cbf565b602082019050919050565b60006020820190508181036000830152613d2481613ce8565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000613d5282613d2b565b613d5c8185613d36565b9350613d6c818560208601612ba2565b613d7581612bcc565b840191505092915050565b6000608082019050613d956000830187612ccd565b613da26020830186612ccd565b613daf6040830185612da3565b8181036060830152613dc18184613d47565b905095945050505050565b600081519050613ddb81612af7565b92915050565b600060208284031215613df757613df6612ac1565b5b6000613e0584828501613dcc565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613e4882612c38565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613e7a57613e79613e0e565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613ebf82612c38565b9150613eca83612c38565b925082613eda57613ed9613e85565b5b828204905092915050565b6000613ef082612c38565b9150613efb83612c38565b9250828203905081811115613f1357613f12613e0e565b5b92915050565b6000613f2482612c38565b9150613f2f83612c38565b925082613f3f57613f3e613e85565b5b828206905092915050565b6000613f5582612c38565b9150613f6083612c38565b9250828201905080821115613f7857613f77613e0e565b5b9291505056fea264697066735822122037df7f79cb4aef1b7397ae8e4f6048f737faa037097f6c2290d39d69fc688dff64736f6c63430008110033

Deployed Bytecode Sourcemap

70419:4316:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24212:639;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25114:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31605:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31038:408;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73558:94;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73706:121;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70964:40;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72460:641;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;20865:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35244:2825;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73413:94;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74387:184;;;;;;;;;;;;;:::i;:::-;;71011:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38165:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57726:94;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73888:104;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;71624:826;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;59474:528;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74223:114;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70868:48;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26507:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22049:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69528:103;;;;;;;;;;;;;:::i;:::-;;63350:900;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70575:72;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68880:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25290:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60390:2513;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70781:44;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32163:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;38956:407;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58887:428;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70675:73;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73154:202;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74050:108;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;71487:129;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32554:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69786:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;24212:639;24297:4;24636:10;24621:25;;:11;:25;;;;:102;;;;24713:10;24698:25;;:11;:25;;;;24621:102;:179;;;;24790:10;24775:25;;:11;:25;;;;24621:179;24601:199;;24212:639;;;:::o;25114:100::-;25168:13;25201:5;25194:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25114:100;:::o;31605:218::-;31681:7;31706:16;31714:7;31706;:16::i;:::-;31701:64;;31731:34;;;;;;;;;;;;;;31701:64;31785:15;:24;31801:7;31785:24;;;;;;;;;;;:30;;;;;;;;;;;;31778:37;;31605:218;;;:::o;31038:408::-;31127:13;31143:16;31151:7;31143;:16::i;:::-;31127:32;;31199:5;31176:28;;:19;:17;:19::i;:::-;:28;;;31172:175;;31224:44;31241:5;31248:19;:17;:19::i;:::-;31224:16;:44::i;:::-;31219:128;;31296:35;;;;;;;;;;;;;;31219:128;31172:175;31392:2;31359:15;:24;31375:7;31359:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;31430:7;31426:2;31410:28;;31419:5;31410:28;;;;;;;;;;;;31116:330;31038:408;;:::o;73558:94::-;68766:13;:11;:13::i;:::-;73636:8:::1;73626:7;:18;;;;73558:94:::0;:::o;73706:121::-;68766:13;:11;:13::i;:::-;73813:6:::1;73791:13;:19;73805:4;73791:19;;;;;;;;;;;:28;;;;73706:121:::0;;:::o;70964:40::-;;;;:::o;72460:641::-;72591:10;72570:31;;:17;72578:8;72570:7;:17::i;:::-;:31;;;72562:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;72703:11;;72690:9;:24;;72682:33;;;;;;72757:12;72783;;;;;;;;;;;72775:26;;72817:4;72809:21;;;72775:60;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72756:79;;;72854:7;72846:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;72919:14;72924:8;72919:4;:14::i;:::-;73018:13;;;;;;;;;;;73011:30;;;73042:10;73054:9;:19;73064:8;73054:19;;;;;;;;;;;;73011:64;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;72513:588;72460:641;:::o;20865:323::-;20926:7;21154:15;:13;:15::i;:::-;21139:12;;21123:13;;:28;:46;21116:53;;20865:323;:::o;35244:2825::-;35386:27;35416;35435:7;35416:18;:27::i;:::-;35386:57;;35501:4;35460:45;;35476:19;35460:45;;;35456:86;;35514:28;;;;;;;;;;;;;;35456:86;35556:27;35585:23;35612:35;35639:7;35612:26;:35::i;:::-;35555:92;;;;35747:68;35772:15;35789:4;35795:19;:17;:19::i;:::-;35747:24;:68::i;:::-;35742:180;;35835:43;35852:4;35858:19;:17;:19::i;:::-;35835:16;:43::i;:::-;35830:92;;35887:35;;;;;;;;;;;;;;35830:92;35742:180;35953:1;35939:16;;:2;:16;;;35935:52;;35964:23;;;;;;;;;;;;;;35935:52;36000:43;36022:4;36028:2;36032:7;36041:1;36000:21;:43::i;:::-;36136:15;36133:160;;;36276:1;36255:19;36248:30;36133:160;36673:18;:24;36692:4;36673:24;;;;;;;;;;;;;;;;36671:26;;;;;;;;;;;;36742:18;:22;36761:2;36742:22;;;;;;;;;;;;;;;;36740:24;;;;;;;;;;;37064:146;37101:2;37150:45;37165:4;37171:2;37175:19;37150:14;:45::i;:::-;17264:8;37122:73;37064:18;:146::i;:::-;37035:17;:26;37053:7;37035:26;;;;;;;;;;;:175;;;;37381:1;17264:8;37330:19;:47;:52;37326:627;;37403:19;37435:1;37425:7;:11;37403:33;;37592:1;37558:17;:30;37576:11;37558:30;;;;;;;;;;;;:35;37554:384;;37696:13;;37681:11;:28;37677:242;;37876:19;37843:17;:30;37861:11;37843:30;;;;;;;;;;;:52;;;;37677:242;37554:384;37384:569;37326:627;38000:7;37996:2;37981:27;;37990:4;37981:27;;;;;;;;;;;;38019:42;38040:4;38046:2;38050:7;38059:1;38019:20;:42::i;:::-;35375:2694;;;35244:2825;;;:::o;73413:94::-;68766:13;:11;:13::i;:::-;73495:4:::1;73481:11;:18;;;;73413:94:::0;:::o;74387:184::-;68766:13;:11;:13::i;:::-;74438:12:::1;74464;;;;;;;;;;;74456:26;;74498:4;74490:21;;;74456:60;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74437:79;;;74535:7;74527:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;74426:145;74387:184::o:0;71011:26::-;;;;:::o;38165:193::-;38311:39;38328:4;38334:2;38338:7;38311:39;;;;;;;;;;;;:16;:39::i;:::-;38165:193;;;:::o;57726:94::-;57792:20;57798:7;57807:4;57792:5;:20::i;:::-;57726:94;:::o;73888:104::-;68766:13;:11;:13::i;:::-;73979:5:::1;73964:12;:20;;;;;;:::i;:::-;;73888:104:::0;:::o;71624:826::-;71737:1;71726:7;;:12;71718:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;71848:11;;71835:9;:24;;71827:33;;;;;;71932:23;71947:7;71932:14;:23::i;:::-;71924:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;72021:12;72047;;;;;;;;;;;72039:26;;72081:4;72073:21;;;72039:60;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72020:79;;;72118:7;72110:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;72231:13;;;;;;;;;;;72224:34;;;72259:10;72278:4;72284:7;72224:69;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;72362:7;72334:9;:25;72344:14;:12;:14::i;:::-;72334:25;;;;;;;;;;;:35;;;;72410:20;72416:10;72428:1;72410:5;:20::i;:::-;71674:776;71624:826;:::o;59474:528::-;59618:23;59684:22;59709:8;;:15;;59684:40;;59739:34;59797:14;59776:36;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;59739:73;;59832:9;59827:125;59848:14;59843:1;:19;59827:125;;59904:32;59924:8;;59933:1;59924:11;;;;;;;:::i;:::-;;;;;;;;59904:19;:32::i;:::-;59888:10;59899:1;59888:13;;;;;;;;:::i;:::-;;;;;;;:48;;;;59864:3;;;;;59827:125;;;;59973:10;59966:17;;;;59474:528;;;;:::o;74223:114::-;68766:13;:11;:13::i;:::-;74316::::1;74301:12;;:28;;;;;;;;;;;;;;;;;;74223:114:::0;:::o;70868:48::-;;;;;;;;;;;;;;;;;:::o;26507:152::-;26579:7;26622:27;26641:7;26622:18;:27::i;:::-;26599:52;;26507:152;;;:::o;22049:233::-;22121:7;22162:1;22145:19;;:5;:19;;;22141:60;;22173:28;;;;;;;;;;;;;;22141:60;16208:13;22219:18;:25;22238:5;22219:25;;;;;;;;;;;;;;;;:55;22212:62;;22049:233;;;:::o;69528:103::-;68766:13;:11;:13::i;:::-;69593:30:::1;69620:1;69593:18;:30::i;:::-;69528:103::o:0;63350:900::-;63428:16;63482:19;63516:25;63556:22;63581:16;63591:5;63581:9;:16::i;:::-;63556:41;;63612:25;63654:14;63640:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63612:57;;63684:31;;:::i;:::-;63735:9;63747:15;:13;:15::i;:::-;63735:27;;63730:472;63779:14;63764:11;:29;63730:472;;63831:15;63844:1;63831:12;:15::i;:::-;63819:27;;63869:9;:16;;;63910:8;63865:73;63986:1;63960:28;;:9;:14;;;:28;;;63956:111;;64033:9;:14;;;64013:34;;63956:111;64110:5;64089:26;;:17;:26;;;64085:102;;64166:1;64140:8;64149:13;;;;;;64140:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;64085:102;63730:472;63795:3;;;;;63730:472;;;;64223:8;64216:15;;;;;;;63350:900;;;:::o;70575:72::-;;;;;;;;;;;;;:::o;68880:87::-;68926:7;68953:6;;;;;;;;;;;68946:13;;68880:87;:::o;25290:104::-;25346:13;25379:7;25372:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25290:104;:::o;60390:2513::-;60533:16;60600:4;60591:5;:13;60587:45;;60613:19;;;;;;;;;;;;;;60587:45;60647:19;60681:17;60701:14;:12;:14::i;:::-;60681:34;;60801:15;:13;:15::i;:::-;60793:5;:23;60789:87;;;60845:15;:13;:15::i;:::-;60837:23;;60789:87;60952:9;60945:4;:16;60941:73;;;60989:9;60982:16;;60941:73;61028:25;61056:16;61066:5;61056:9;:16::i;:::-;61028:44;;61250:4;61242:5;:12;61238:278;;;61275:19;61304:5;61297:4;:12;61275:34;;61346:17;61332:11;:31;61328:111;;;61408:11;61388:31;;61328:111;61256:198;61238:278;;;61499:1;61479:21;;61238:278;61530:25;61572:17;61558:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61530:60;;61630:1;61609:17;:22;61605:78;;61659:8;61652:15;;;;;;;;61605:78;61827:31;61861:26;61881:5;61861:19;:26::i;:::-;61827:60;;61902:25;62147:9;:16;;;62142:92;;62204:9;:14;;;62184:34;;62142:92;62253:9;62265:5;62253:17;;62248:478;62277:4;62272:1;:9;;:45;;;;;62300:17;62285:11;:32;;62272:45;62248:478;;;62355:15;62368:1;62355:12;:15::i;:::-;62343:27;;62393:9;:16;;;62434:8;62389:73;62510:1;62484:28;;:9;:14;;;:28;;;62480:111;;62557:9;:14;;;62537:34;;62480:111;62634:5;62613:26;;:17;:26;;;62609:102;;62690:1;62664:8;62673:13;;;;;;62664:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;62609:102;62248:478;62319:3;;;;;62248:478;;;;62828:11;62818:8;62811:29;62876:8;62869:15;;;;;;;;60390:2513;;;;;;:::o;70781:44::-;;;;;;;;;;;;;;;;;:::o;32163:234::-;32310:8;32258:18;:39;32277:19;:17;:19::i;:::-;32258:39;;;;;;;;;;;;;;;:49;32298:8;32258:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;32370:8;32334:55;;32349:19;:17;:19::i;:::-;32334:55;;;32380:8;32334:55;;;;;;:::i;:::-;;;;;;;;32163:234;;:::o;38956:407::-;39131:31;39144:4;39150:2;39154:7;39131:12;:31::i;:::-;39195:1;39177:2;:14;;;:19;39173:183;;39216:56;39247:4;39253:2;39257:7;39266:5;39216:30;:56::i;:::-;39211:145;;39300:40;;;;;;;;;;;;;;39211:145;39173:183;38956:407;;;;:::o;58887:428::-;58971:21;;:::i;:::-;59005:31;;:::i;:::-;59061:15;:13;:15::i;:::-;59051:7;:25;:54;;;;59091:14;:12;:14::i;:::-;59080:7;:25;;59051:54;59047:103;;;59129:9;59122:16;;;;;59047:103;59172:21;59185:7;59172:12;:21::i;:::-;59160:33;;59208:9;:16;;;59204:65;;;59248:9;59241:16;;;;;59204:65;59286:21;59299:7;59286:12;:21::i;:::-;59279:28;;;58887:428;;;;:::o;70675:73::-;;;;;;;;;;;;;:::o;73154:202::-;73233:18;73290:12;73303:36;73320:9;:18;73330:7;73320:18;;;;;;;;;;;;73303:16;:36::i;:::-;73276:72;;;;;;;;;:::i;:::-;;;;;;;;;;;;;73269:79;;73154:202;;;:::o;74050:108::-;68766:13;:11;:13::i;:::-;74141:9:::1;74125:13;;:25;;;;;;;;;;;;;;;;;;74050:108:::0;:::o;71487:129::-;71548:13;71607:1;71581:13;:22;71595:7;71581:22;;;;;;;;;;;;:27;;71574:34;;71487:129;;;:::o;32554:164::-;32651:4;32675:18;:25;32694:5;32675:25;;;;;;;;;;;;;;;:35;32701:8;32675:35;;;;;;;;;;;;;;;;;;;;;;;;;32668:42;;32554:164;;;;:::o;69786:201::-;68766:13;:11;:13::i;:::-;69895:1:::1;69875:22;;:8;:22;;::::0;69867:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;69951:28;69970:8;69951:18;:28::i;:::-;69786:201:::0;:::o;32976:282::-;33041:4;33097:7;33078:15;:13;:15::i;:::-;:26;;:66;;;;;33131:13;;33121:7;:23;33078:66;:153;;;;;33230:1;16984:8;33182:17;:26;33200:7;33182:26;;;;;;;;;;;;:44;:49;33078:153;33058:173;;32976:282;;;:::o;55284:105::-;55344:7;55371:10;55364:17;;55284:105;:::o;69045:132::-;69120:12;:10;:12::i;:::-;69109:23;;:7;:5;:7::i;:::-;:23;;;69101:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;69045:132::o;20381:92::-;20437:7;20381:92;:::o;27662:1275::-;27729:7;27749:12;27764:7;27749:22;;27832:4;27813:15;:13;:15::i;:::-;:23;27809:1061;;27866:13;;27859:4;:20;27855:1015;;;27904:14;27921:17;:23;27939:4;27921:23;;;;;;;;;;;;27904:40;;28038:1;16984:8;28010:6;:24;:29;28006:845;;28675:113;28692:1;28682:6;:11;28675:113;;28735:17;:25;28753:6;;;;;;;28735:25;;;;;;;;;;;;28726:34;;28675:113;;;28821:6;28814:13;;;;;;28006:845;27881:989;27855:1015;27809:1061;28898:31;;;;;;;;;;;;;;27662:1275;;;;:::o;34139:485::-;34241:27;34270:23;34311:38;34352:15;:24;34368:7;34352:24;;;;;;;;;;;34311:65;;34529:18;34506:41;;34586:19;34580:26;34561:45;;34491:126;34139:485;;;:::o;33367:659::-;33516:11;33681:16;33674:5;33670:28;33661:37;;33841:16;33830:9;33826:32;33813:45;;33991:15;33980:9;33977:30;33969:5;33958:9;33955:20;33952:56;33942:66;;33367:659;;;;;:::o;40025:159::-;;;;;:::o;54593:311::-;54728:7;54748:16;17388:3;54774:19;:41;;54748:68;;17388:3;54842:31;54853:4;54859:2;54863:9;54842:10;:31::i;:::-;54834:40;;:62;;54827:69;;;54593:311;;;;;:::o;29485:450::-;29565:14;29733:16;29726:5;29722:28;29713:37;;29910:5;29896:11;29871:23;29867:41;29864:52;29857:5;29854:63;29844:73;;29485:450;;;;:::o;40849:158::-;;;;;:::o;49813:3081::-;49893:27;49923;49942:7;49923:18;:27::i;:::-;49893:57;;49963:12;49994:19;49963:52;;50029:27;50058:23;50085:35;50112:7;50085:26;:35::i;:::-;50028:92;;;;50137:13;50133:316;;;50258:68;50283:15;50300:4;50306:19;:17;:19::i;:::-;50258:24;:68::i;:::-;50253:184;;50350:43;50367:4;50373:19;:17;:19::i;:::-;50350:16;:43::i;:::-;50345:92;;50402:35;;;;;;;;;;;;;;50345:92;50253:184;50133:316;50461:51;50483:4;50497:1;50501:7;50510:1;50461:21;:51::i;:::-;50605:15;50602:160;;;50745:1;50724:19;50717:30;50602:160;51423:1;16473:3;51393:1;:26;;51392:32;51364:18;:24;51383:4;51364:24;;;;;;;;;;;;;;;;:60;;;;;;;;;;;51691:176;51728:4;51799:53;51814:4;51828:1;51832:19;51799:14;:53::i;:::-;17264:8;16984;51752:43;51751:101;51691:18;:176::i;:::-;51662:17;:26;51680:7;51662:26;;;;;;;;;;;:205;;;;52038:1;17264:8;51987:19;:47;:52;51983:627;;52060:19;52092:1;52082:7;:11;52060:33;;52249:1;52215:17;:30;52233:11;52215:30;;;;;;;;;;;;:35;52211:384;;52353:13;;52338:11;:28;52334:242;;52533:19;52500:17;:30;52518:11;52500:30;;;;;;;;;;;:52;;;;52334:242;52211:384;52041:569;51983:627;52665:7;52661:1;52638:35;;52647:4;52638:35;;;;;;;;;;;;52684:50;52705:4;52719:1;52723:7;52732:1;52684:20;:50::i;:::-;52861:12;;:14;;;;;;;;;;;;;49882:3012;;;;49813:3081;;:::o;20552:103::-;20607:7;20634:13;;20627:20;;20552:103;:::o;42625:2966::-;42698:20;42721:13;;42698:36;;42761:1;42749:8;:13;42745:44;;42771:18;;;;;;;;;;;;;;42745:44;42802:61;42832:1;42836:2;42840:12;42854:8;42802:21;:61::i;:::-;43346:1;16346:2;43316:1;:26;;43315:32;43303:8;:45;43277:18;:22;43296:2;43277:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;43625:139;43662:2;43716:33;43739:1;43743:2;43747:1;43716:14;:33::i;:::-;43683:30;43704:8;43683:20;:30::i;:::-;:66;43625:18;:139::i;:::-;43591:17;:31;43609:12;43591:31;;;;;;;;;;;:173;;;;43781:16;43812:11;43841:8;43826:12;:23;43812:37;;44362:16;44358:2;44354:25;44342:37;;44734:12;44694:8;44653:1;44591:25;44532:1;44471;44444:335;45105:1;45091:12;45087:20;45045:346;45146:3;45137:7;45134:16;45045:346;;45364:7;45354:8;45351:1;45324:25;45321:1;45318;45313:59;45199:1;45190:7;45186:15;45175:26;;45045:346;;;45049:77;45436:1;45424:8;:13;45420:45;;45446:19;;;;;;;;;;;;;;45420:45;45498:3;45482:13;:19;;;;43051:2462;;45523:60;45552:1;45556:2;45560:12;45574:8;45523:20;:60::i;:::-;42687:2904;42625:2966;;:::o;70147:191::-;70221:16;70240:6;;;;;;;;;;;70221:25;;70266:8;70257:6;;:17;;;;;;;;;;;;;;;;;;70321:8;70290:40;;70311:8;70290:40;;;;;;;;;;;;70210:128;70147:191;:::o;27110:161::-;27178:21;;:::i;:::-;27219:44;27238:17;:24;27256:5;27238:24;;;;;;;;;;;;27219:18;:44::i;:::-;27212:51;;27110:161;;;:::o;41447:716::-;41610:4;41656:2;41631:45;;;41677:19;:17;:19::i;:::-;41698:4;41704:7;41713:5;41631:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;41627:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41931:1;41914:6;:13;:18;41910:235;;41960:40;;;;;;;;;;;;;;41910:235;42103:6;42097:13;42088:6;42084:2;42080:15;42073:38;41627:529;41800:54;;;41790:64;;;:6;:64;;;;41783:71;;;41447:716;;;;;;:::o;26848:166::-;26918:21;;:::i;:::-;26959:47;26978:27;26997:7;26978:18;:27::i;:::-;26959:18;:47::i;:::-;26952:54;;26848:166;;;:::o;64685:723::-;64741:13;64971:1;64962:5;:10;64958:53;;64989:10;;;;;;;;;;;;;;;;;;;;;64958:53;65021:12;65036:5;65021:20;;65052:14;65077:78;65092:1;65084:4;:9;65077:78;;65110:8;;;;;:::i;:::-;;;;65141:2;65133:10;;;;;:::i;:::-;;;65077:78;;;65165:19;65197:6;65187:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65165:39;;65215:154;65231:1;65222:5;:10;65215:154;;65259:1;65249:11;;;;;:::i;:::-;;;65326:2;65318:5;:10;;;;:::i;:::-;65305:2;:24;;;;:::i;:::-;65292:39;;65275:6;65282;65275:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;65355:2;65346:11;;;;;:::i;:::-;;;65215:154;;;65393:6;65379:21;;;;;64685:723;;;;:::o;67431:98::-;67484:7;67511:10;67504:17;;67431:98;:::o;54294:147::-;54431:6;54294:147;;;;;:::o;30037:324::-;30107:14;30340:1;30330:8;30327:15;30301:24;30297:46;30287:56;;30037:324;;;:::o;29036:366::-;29102:31;;:::i;:::-;29179:6;29146:9;:14;;:41;;;;;;;;;;;16867:3;29232:6;:33;;29198:9;:24;;:68;;;;;;;;;;;29324:1;16984:8;29296:6;:24;:29;;29277:9;:16;;:48;;;;;;;;;;;17388:3;29365:6;:28;;29336:9;:19;;:58;;;;;;;;;;;29036:366;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:77::-;2897:7;2926:5;2915:16;;2860:77;;;:::o;2943:122::-;3016:24;3034:5;3016:24;:::i;:::-;3009:5;3006:35;2996:63;;3055:1;3052;3045:12;2996:63;2943:122;:::o;3071:139::-;3117:5;3155:6;3142:20;3133:29;;3171:33;3198:5;3171:33;:::i;:::-;3071:139;;;;:::o;3216:329::-;3275:6;3324:2;3312:9;3303:7;3299:23;3295:32;3292:119;;;3330:79;;:::i;:::-;3292:119;3450:1;3475:53;3520:7;3511:6;3500:9;3496:22;3475:53;:::i;:::-;3465:63;;3421:117;3216:329;;;;:::o;3551:126::-;3588:7;3628:42;3621:5;3617:54;3606:65;;3551:126;;;:::o;3683:96::-;3720:7;3749:24;3767:5;3749:24;:::i;:::-;3738:35;;3683:96;;;:::o;3785:118::-;3872:24;3890:5;3872:24;:::i;:::-;3867:3;3860:37;3785:118;;:::o;3909:222::-;4002:4;4040:2;4029:9;4025:18;4017:26;;4053:71;4121:1;4110:9;4106:17;4097:6;4053:71;:::i;:::-;3909:222;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:474::-;4478:6;4486;4535:2;4523:9;4514:7;4510:23;4506:32;4503:119;;;4541:79;;:::i;:::-;4503:119;4661:1;4686:53;4731:7;4722:6;4711:9;4707:22;4686:53;:::i;:::-;4676:63;;4632:117;4788:2;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4759:118;4410:474;;;;;:::o;4890:::-;4958:6;4966;5015:2;5003:9;4994:7;4990:23;4986:32;4983:119;;;5021:79;;:::i;:::-;4983:119;5141:1;5166:53;5211:7;5202:6;5191:9;5187:22;5166:53;:::i;:::-;5156:63;;5112:117;5268:2;5294:53;5339:7;5330:6;5319:9;5315:22;5294:53;:::i;:::-;5284:63;;5239:118;4890:474;;;;;:::o;5370:118::-;5457:24;5475:5;5457:24;:::i;:::-;5452:3;5445:37;5370:118;;:::o;5494:222::-;5587:4;5625:2;5614:9;5610:18;5602:26;;5638:71;5706:1;5695:9;5691:17;5682:6;5638:71;:::i;:::-;5494:222;;;;:::o;5722:619::-;5799:6;5807;5815;5864:2;5852:9;5843:7;5839:23;5835:32;5832:119;;;5870:79;;:::i;:::-;5832:119;5990:1;6015:53;6060:7;6051:6;6040:9;6036:22;6015:53;:::i;:::-;6005:63;;5961:117;6117:2;6143:53;6188:7;6179:6;6168:9;6164:22;6143:53;:::i;:::-;6133:63;;6088:118;6245:2;6271:53;6316:7;6307:6;6296:9;6292:22;6271:53;:::i;:::-;6261:63;;6216:118;5722:619;;;;;:::o;6347:117::-;6456:1;6453;6446:12;6470:117;6579:1;6576;6569:12;6593:180;6641:77;6638:1;6631:88;6738:4;6735:1;6728:15;6762:4;6759:1;6752:15;6779:281;6862:27;6884:4;6862:27;:::i;:::-;6854:6;6850:40;6992:6;6980:10;6977:22;6956:18;6944:10;6941:34;6938:62;6935:88;;;7003:18;;:::i;:::-;6935:88;7043:10;7039:2;7032:22;6822:238;6779:281;;:::o;7066:129::-;7100:6;7127:20;;:::i;:::-;7117:30;;7156:33;7184:4;7176:6;7156:33;:::i;:::-;7066:129;;;:::o;7201:308::-;7263:4;7353:18;7345:6;7342:30;7339:56;;;7375:18;;:::i;:::-;7339:56;7413:29;7435:6;7413:29;:::i;:::-;7405:37;;7497:4;7491;7487:15;7479:23;;7201:308;;;:::o;7515:146::-;7612:6;7607:3;7602;7589:30;7653:1;7644:6;7639:3;7635:16;7628:27;7515:146;;;:::o;7667:425::-;7745:5;7770:66;7786:49;7828:6;7786:49;:::i;:::-;7770:66;:::i;:::-;7761:75;;7859:6;7852:5;7845:21;7897:4;7890:5;7886:16;7935:3;7926:6;7921:3;7917:16;7914:25;7911:112;;;7942:79;;:::i;:::-;7911:112;8032:54;8079:6;8074:3;8069;8032:54;:::i;:::-;7751:341;7667:425;;;;;:::o;8112:340::-;8168:5;8217:3;8210:4;8202:6;8198:17;8194:27;8184:122;;8225:79;;:::i;:::-;8184:122;8342:6;8329:20;8367:79;8442:3;8434:6;8427:4;8419:6;8415:17;8367:79;:::i;:::-;8358:88;;8174:278;8112:340;;;;:::o;8458:509::-;8527:6;8576:2;8564:9;8555:7;8551:23;8547:32;8544:119;;;8582:79;;:::i;:::-;8544:119;8730:1;8719:9;8715:17;8702:31;8760:18;8752:6;8749:30;8746:117;;;8782:79;;:::i;:::-;8746:117;8887:63;8942:7;8933:6;8922:9;8918:22;8887:63;:::i;:::-;8877:73;;8673:287;8458:509;;;;:::o;8973:117::-;9082:1;9079;9072:12;9096:117;9205:1;9202;9195:12;9236:568;9309:8;9319:6;9369:3;9362:4;9354:6;9350:17;9346:27;9336:122;;9377:79;;:::i;:::-;9336:122;9490:6;9477:20;9467:30;;9520:18;9512:6;9509:30;9506:117;;;9542:79;;:::i;:::-;9506:117;9656:4;9648:6;9644:17;9632:29;;9710:3;9702:4;9694:6;9690:17;9680:8;9676:32;9673:41;9670:128;;;9717:79;;:::i;:::-;9670:128;9236:568;;;;;:::o;9810:559::-;9896:6;9904;9953:2;9941:9;9932:7;9928:23;9924:32;9921:119;;;9959:79;;:::i;:::-;9921:119;10107:1;10096:9;10092:17;10079:31;10137:18;10129:6;10126:30;10123:117;;;10159:79;;:::i;:::-;10123:117;10272:80;10344:7;10335:6;10324:9;10320:22;10272:80;:::i;:::-;10254:98;;;;10050:312;9810:559;;;;;:::o;10375:145::-;10473:6;10507:5;10501:12;10491:22;;10375:145;;;:::o;10526:215::-;10656:11;10690:6;10685:3;10678:19;10730:4;10725:3;10721:14;10706:29;;10526:215;;;;:::o;10747:163::-;10845:4;10868:3;10860:11;;10898:4;10893:3;10889:14;10881:22;;10747:163;;;:::o;10916:108::-;10993:24;11011:5;10993:24;:::i;:::-;10988:3;10981:37;10916:108;;:::o;11030:101::-;11066:7;11106:18;11099:5;11095:30;11084:41;;11030:101;;;:::o;11137:105::-;11212:23;11229:5;11212:23;:::i;:::-;11207:3;11200:36;11137:105;;:::o;11248:99::-;11319:21;11334:5;11319:21;:::i;:::-;11314:3;11307:34;11248:99;;:::o;11353:91::-;11389:7;11429:8;11422:5;11418:20;11407:31;;11353:91;;;:::o;11450:105::-;11525:23;11542:5;11525:23;:::i;:::-;11520:3;11513:36;11450:105;;:::o;11633:864::-;11782:4;11777:3;11773:14;11869:4;11862:5;11858:16;11852:23;11888:63;11945:4;11940:3;11936:14;11922:12;11888:63;:::i;:::-;11797:164;12053:4;12046:5;12042:16;12036:23;12072:61;12127:4;12122:3;12118:14;12104:12;12072:61;:::i;:::-;11971:172;12227:4;12220:5;12216:16;12210:23;12246:57;12297:4;12292:3;12288:14;12274:12;12246:57;:::i;:::-;12153:160;12400:4;12393:5;12389:16;12383:23;12419:61;12474:4;12469:3;12465:14;12451:12;12419:61;:::i;:::-;12323:167;11751:746;11633:864;;:::o;12503:303::-;12634:10;12655:108;12759:3;12751:6;12655:108;:::i;:::-;12795:4;12790:3;12786:14;12772:28;;12503:303;;;;:::o;12812:144::-;12913:4;12945;12940:3;12936:14;12928:22;;12812:144;;;:::o;13038:980::-;13219:3;13248:85;13327:5;13248:85;:::i;:::-;13349:117;13459:6;13454:3;13349:117;:::i;:::-;13342:124;;13490:87;13571:5;13490:87;:::i;:::-;13600:7;13631:1;13616:377;13641:6;13638:1;13635:13;13616:377;;;13717:6;13711:13;13744:125;13865:3;13850:13;13744:125;:::i;:::-;13737:132;;13892:91;13976:6;13892:91;:::i;:::-;13882:101;;13676:317;13663:1;13660;13656:9;13651:14;;13616:377;;;13620:14;14009:3;14002:10;;13224:794;;;13038:980;;;;:::o;14024:497::-;14229:4;14267:2;14256:9;14252:18;14244:26;;14316:9;14310:4;14306:20;14302:1;14291:9;14287:17;14280:47;14344:170;14509:4;14500:6;14344:170;:::i;:::-;14336:178;;14024:497;;;;:::o;14527:329::-;14586:6;14635:2;14623:9;14614:7;14610:23;14606:32;14603:119;;;14641:79;;:::i;:::-;14603:119;14761:1;14786:53;14831:7;14822:6;14811:9;14807:22;14786:53;:::i;:::-;14776:63;;14732:117;14527:329;;;;:::o;14862:114::-;14929:6;14963:5;14957:12;14947:22;;14862:114;;;:::o;14982:184::-;15081:11;15115:6;15110:3;15103:19;15155:4;15150:3;15146:14;15131:29;;14982:184;;;;:::o;15172:132::-;15239:4;15262:3;15254:11;;15292:4;15287:3;15283:14;15275:22;;15172:132;;;:::o;15310:108::-;15387:24;15405:5;15387:24;:::i;:::-;15382:3;15375:37;15310:108;;:::o;15424:179::-;15493:10;15514:46;15556:3;15548:6;15514:46;:::i;:::-;15592:4;15587:3;15583:14;15569:28;;15424:179;;;;:::o;15609:113::-;15679:4;15711;15706:3;15702:14;15694:22;;15609:113;;;:::o;15758:732::-;15877:3;15906:54;15954:5;15906:54;:::i;:::-;15976:86;16055:6;16050:3;15976:86;:::i;:::-;15969:93;;16086:56;16136:5;16086:56;:::i;:::-;16165:7;16196:1;16181:284;16206:6;16203:1;16200:13;16181:284;;;16282:6;16276:13;16309:63;16368:3;16353:13;16309:63;:::i;:::-;16302:70;;16395:60;16448:6;16395:60;:::i;:::-;16385:70;;16241:224;16228:1;16225;16221:9;16216:14;;16181:284;;;16185:14;16481:3;16474:10;;15882:608;;;15758:732;;;;:::o;16496:373::-;16639:4;16677:2;16666:9;16662:18;16654:26;;16726:9;16720:4;16716:20;16712:1;16701:9;16697:17;16690:47;16754:108;16857:4;16848:6;16754:108;:::i;:::-;16746:116;;16496:373;;;;:::o;16875:619::-;16952:6;16960;16968;17017:2;17005:9;16996:7;16992:23;16988:32;16985:119;;;17023:79;;:::i;:::-;16985:119;17143:1;17168:53;17213:7;17204:6;17193:9;17189:22;17168:53;:::i;:::-;17158:63;;17114:117;17270:2;17296:53;17341:7;17332:6;17321:9;17317:22;17296:53;:::i;:::-;17286:63;;17241:118;17398:2;17424:53;17469:7;17460:6;17449:9;17445:22;17424:53;:::i;:::-;17414:63;;17369:118;16875:619;;;;;:::o;17500:116::-;17570:21;17585:5;17570:21;:::i;:::-;17563:5;17560:32;17550:60;;17606:1;17603;17596:12;17550:60;17500:116;:::o;17622:133::-;17665:5;17703:6;17690:20;17681:29;;17719:30;17743:5;17719:30;:::i;:::-;17622:133;;;;:::o;17761:468::-;17826:6;17834;17883:2;17871:9;17862:7;17858:23;17854:32;17851:119;;;17889:79;;:::i;:::-;17851:119;18009:1;18034:53;18079:7;18070:6;18059:9;18055:22;18034:53;:::i;:::-;18024:63;;17980:117;18136:2;18162:50;18204:7;18195:6;18184:9;18180:22;18162:50;:::i;:::-;18152:60;;18107:115;17761:468;;;;;:::o;18235:307::-;18296:4;18386:18;18378:6;18375:30;18372:56;;;18408:18;;:::i;:::-;18372:56;18446:29;18468:6;18446:29;:::i;:::-;18438:37;;18530:4;18524;18520:15;18512:23;;18235:307;;;:::o;18548:423::-;18625:5;18650:65;18666:48;18707:6;18666:48;:::i;:::-;18650:65;:::i;:::-;18641:74;;18738:6;18731:5;18724:21;18776:4;18769:5;18765:16;18814:3;18805:6;18800:3;18796:16;18793:25;18790:112;;;18821:79;;:::i;:::-;18790:112;18911:54;18958:6;18953:3;18948;18911:54;:::i;:::-;18631:340;18548:423;;;;;:::o;18990:338::-;19045:5;19094:3;19087:4;19079:6;19075:17;19071:27;19061:122;;19102:79;;:::i;:::-;19061:122;19219:6;19206:20;19244:78;19318:3;19310:6;19303:4;19295:6;19291:17;19244:78;:::i;:::-;19235:87;;19051:277;18990:338;;;;:::o;19334:943::-;19429:6;19437;19445;19453;19502:3;19490:9;19481:7;19477:23;19473:33;19470:120;;;19509:79;;:::i;:::-;19470:120;19629:1;19654:53;19699:7;19690:6;19679:9;19675:22;19654:53;:::i;:::-;19644:63;;19600:117;19756:2;19782:53;19827:7;19818:6;19807:9;19803:22;19782:53;:::i;:::-;19772:63;;19727:118;19884:2;19910:53;19955:7;19946:6;19935:9;19931:22;19910:53;:::i;:::-;19900:63;;19855:118;20040:2;20029:9;20025:18;20012:32;20071:18;20063:6;20060:30;20057:117;;;20093:79;;:::i;:::-;20057:117;20198:62;20252:7;20243:6;20232:9;20228:22;20198:62;:::i;:::-;20188:72;;19983:287;19334:943;;;;;;;:::o;20355:874::-;20514:4;20509:3;20505:14;20601:4;20594:5;20590:16;20584:23;20620:63;20677:4;20672:3;20668:14;20654:12;20620:63;:::i;:::-;20529:164;20785:4;20778:5;20774:16;20768:23;20804:61;20859:4;20854:3;20850:14;20836:12;20804:61;:::i;:::-;20703:172;20959:4;20952:5;20948:16;20942:23;20978:57;21029:4;21024:3;21020:14;21006:12;20978:57;:::i;:::-;20885:160;21132:4;21125:5;21121:16;21115:23;21151:61;21206:4;21201:3;21197:14;21183:12;21151:61;:::i;:::-;21055:167;20483:746;20355:874;;:::o;21235:347::-;21390:4;21428:3;21417:9;21413:19;21405:27;;21442:133;21572:1;21561:9;21557:17;21548:6;21442:133;:::i;:::-;21235:347;;;;:::o;21588:474::-;21656:6;21664;21713:2;21701:9;21692:7;21688:23;21684:32;21681:119;;;21719:79;;:::i;:::-;21681:119;21839:1;21864:53;21909:7;21900:6;21889:9;21885:22;21864:53;:::i;:::-;21854:63;;21810:117;21966:2;21992:53;22037:7;22028:6;22017:9;22013:22;21992:53;:::i;:::-;21982:63;;21937:118;21588:474;;;;;:::o;22068:180::-;22116:77;22113:1;22106:88;22213:4;22210:1;22203:15;22237:4;22234:1;22227:15;22254:320;22298:6;22335:1;22329:4;22325:12;22315:22;;22382:1;22376:4;22372:12;22403:18;22393:81;;22459:4;22451:6;22447:17;22437:27;;22393:81;22521:2;22513:6;22510:14;22490:18;22487:38;22484:84;;22540:18;;:::i;:::-;22484:84;22305:269;22254:320;;;:::o;22580:177::-;22720:29;22716:1;22708:6;22704:14;22697:53;22580:177;:::o;22763:366::-;22905:3;22926:67;22990:2;22985:3;22926:67;:::i;:::-;22919:74;;23002:93;23091:3;23002:93;:::i;:::-;23120:2;23115:3;23111:12;23104:19;;22763:366;;;:::o;23135:419::-;23301:4;23339:2;23328:9;23324:18;23316:26;;23388:9;23382:4;23378:20;23374:1;23363:9;23359:17;23352:47;23416:131;23542:4;23416:131;:::i;:::-;23408:139;;23135:419;;;:::o;23560:147::-;23661:11;23698:3;23683:18;;23560:147;;;;:::o;23713:114::-;;:::o;23833:398::-;23992:3;24013:83;24094:1;24089:3;24013:83;:::i;:::-;24006:90;;24105:93;24194:3;24105:93;:::i;:::-;24223:1;24218:3;24214:11;24207:18;;23833:398;;;:::o;24237:379::-;24421:3;24443:147;24586:3;24443:147;:::i;:::-;24436:154;;24607:3;24600:10;;24237:379;;;:::o;24622:166::-;24762:18;24758:1;24750:6;24746:14;24739:42;24622:166;:::o;24794:366::-;24936:3;24957:67;25021:2;25016:3;24957:67;:::i;:::-;24950:74;;25033:93;25122:3;25033:93;:::i;:::-;25151:2;25146:3;25142:12;25135:19;;24794:366;;;:::o;25166:419::-;25332:4;25370:2;25359:9;25355:18;25347:26;;25419:9;25413:4;25409:20;25405:1;25394:9;25390:17;25383:47;25447:131;25573:4;25447:131;:::i;:::-;25439:139;;25166:419;;;:::o;25591:332::-;25712:4;25750:2;25739:9;25735:18;25727:26;;25763:71;25831:1;25820:9;25816:17;25807:6;25763:71;:::i;:::-;25844:72;25912:2;25901:9;25897:18;25888:6;25844:72;:::i;:::-;25591:332;;;;;:::o;25929:137::-;25983:5;26014:6;26008:13;25999:22;;26030:30;26054:5;26030:30;:::i;:::-;25929:137;;;;:::o;26072:345::-;26139:6;26188:2;26176:9;26167:7;26163:23;26159:32;26156:119;;;26194:79;;:::i;:::-;26156:119;26314:1;26339:61;26392:7;26383:6;26372:9;26368:22;26339:61;:::i;:::-;26329:71;;26285:125;26072:345;;;;:::o;26423:141::-;26472:4;26495:3;26487:11;;26518:3;26515:1;26508:14;26552:4;26549:1;26539:18;26531:26;;26423:141;;;:::o;26570:93::-;26607:6;26654:2;26649;26642:5;26638:14;26634:23;26624:33;;26570:93;;;:::o;26669:107::-;26713:8;26763:5;26757:4;26753:16;26732:37;;26669:107;;;;:::o;26782:393::-;26851:6;26901:1;26889:10;26885:18;26924:97;26954:66;26943:9;26924:97;:::i;:::-;27042:39;27072:8;27061:9;27042:39;:::i;:::-;27030:51;;27114:4;27110:9;27103:5;27099:21;27090:30;;27163:4;27153:8;27149:19;27142:5;27139:30;27129:40;;26858:317;;26782:393;;;;;:::o;27181:60::-;27209:3;27230:5;27223:12;;27181:60;;;:::o;27247:142::-;27297:9;27330:53;27348:34;27357:24;27375:5;27357:24;:::i;:::-;27348:34;:::i;:::-;27330:53;:::i;:::-;27317:66;;27247:142;;;:::o;27395:75::-;27438:3;27459:5;27452:12;;27395:75;;;:::o;27476:269::-;27586:39;27617:7;27586:39;:::i;:::-;27647:91;27696:41;27720:16;27696:41;:::i;:::-;27688:6;27681:4;27675:11;27647:91;:::i;:::-;27641:4;27634:105;27552:193;27476:269;;;:::o;27751:73::-;27796:3;27751:73;:::o;27830:189::-;27907:32;;:::i;:::-;27948:65;28006:6;27998;27992:4;27948:65;:::i;:::-;27883:136;27830:189;;:::o;28025:186::-;28085:120;28102:3;28095:5;28092:14;28085:120;;;28156:39;28193:1;28186:5;28156:39;:::i;:::-;28129:1;28122:5;28118:13;28109:22;;28085:120;;;28025:186;;:::o;28217:543::-;28318:2;28313:3;28310:11;28307:446;;;28352:38;28384:5;28352:38;:::i;:::-;28436:29;28454:10;28436:29;:::i;:::-;28426:8;28422:44;28619:2;28607:10;28604:18;28601:49;;;28640:8;28625:23;;28601:49;28663:80;28719:22;28737:3;28719:22;:::i;:::-;28709:8;28705:37;28692:11;28663:80;:::i;:::-;28322:431;;28307:446;28217:543;;;:::o;28766:117::-;28820:8;28870:5;28864:4;28860:16;28839:37;;28766:117;;;;:::o;28889:169::-;28933:6;28966:51;29014:1;29010:6;29002:5;28999:1;28995:13;28966:51;:::i;:::-;28962:56;29047:4;29041;29037:15;29027:25;;28940:118;28889:169;;;;:::o;29063:295::-;29139:4;29285:29;29310:3;29304:4;29285:29;:::i;:::-;29277:37;;29347:3;29344:1;29340:11;29334:4;29331:21;29323:29;;29063:295;;;;:::o;29363:1395::-;29480:37;29513:3;29480:37;:::i;:::-;29582:18;29574:6;29571:30;29568:56;;;29604:18;;:::i;:::-;29568:56;29648:38;29680:4;29674:11;29648:38;:::i;:::-;29733:67;29793:6;29785;29779:4;29733:67;:::i;:::-;29827:1;29851:4;29838:17;;29883:2;29875:6;29872:14;29900:1;29895:618;;;;30557:1;30574:6;30571:77;;;30623:9;30618:3;30614:19;30608:26;30599:35;;30571:77;30674:67;30734:6;30727:5;30674:67;:::i;:::-;30668:4;30661:81;30530:222;29865:887;;29895:618;29947:4;29943:9;29935:6;29931:22;29981:37;30013:4;29981:37;:::i;:::-;30040:1;30054:208;30068:7;30065:1;30062:14;30054:208;;;30147:9;30142:3;30138:19;30132:26;30124:6;30117:42;30198:1;30190:6;30186:14;30176:24;;30245:2;30234:9;30230:18;30217:31;;30091:4;30088:1;30084:12;30079:17;;30054:208;;;30290:6;30281:7;30278:19;30275:179;;;30348:9;30343:3;30339:19;30333:26;30391:48;30433:4;30425:6;30421:17;30410:9;30391:48;:::i;:::-;30383:6;30376:64;30298:156;30275:179;30500:1;30496;30488:6;30484:14;30480:22;30474:4;30467:36;29902:611;;;29865:887;;29455:1303;;;29363:1395;;:::o;30764:178::-;30904:30;30900:1;30892:6;30888:14;30881:54;30764:178;:::o;30948:366::-;31090:3;31111:67;31175:2;31170:3;31111:67;:::i;:::-;31104:74;;31187:93;31276:3;31187:93;:::i;:::-;31305:2;31300:3;31296:12;31289:19;;30948:366;;;:::o;31320:419::-;31486:4;31524:2;31513:9;31509:18;31501:26;;31573:9;31567:4;31563:20;31559:1;31548:9;31544:17;31537:47;31601:131;31727:4;31601:131;:::i;:::-;31593:139;;31320:419;;;:::o;31745:169::-;31885:21;31881:1;31873:6;31869:14;31862:45;31745:169;:::o;31920:366::-;32062:3;32083:67;32147:2;32142:3;32083:67;:::i;:::-;32076:74;;32159:93;32248:3;32159:93;:::i;:::-;32277:2;32272:3;32268:12;32261:19;;31920:366;;;:::o;32292:419::-;32458:4;32496:2;32485:9;32481:18;32473:26;;32545:9;32539:4;32535:20;32531:1;32520:9;32516:17;32509:47;32573:131;32699:4;32573:131;:::i;:::-;32565:139;;32292:419;;;:::o;32717:442::-;32866:4;32904:2;32893:9;32889:18;32881:26;;32917:71;32985:1;32974:9;32970:17;32961:6;32917:71;:::i;:::-;32998:72;33066:2;33055:9;33051:18;33042:6;32998:72;:::i;:::-;33080;33148:2;33137:9;33133:18;33124:6;33080:72;:::i;:::-;32717:442;;;;;;:::o;33165:180::-;33213:77;33210:1;33203:88;33310:4;33307:1;33300:15;33334:4;33331:1;33324:15;33351:148;33453:11;33490:3;33475:18;;33351:148;;;;:::o;33529:874::-;33632:3;33669:5;33663:12;33698:36;33724:9;33698:36;:::i;:::-;33750:89;33832:6;33827:3;33750:89;:::i;:::-;33743:96;;33870:1;33859:9;33855:17;33886:1;33881:166;;;;34061:1;34056:341;;;;33848:549;;33881:166;33965:4;33961:9;33950;33946:25;33941:3;33934:38;34027:6;34020:14;34013:22;34005:6;34001:35;33996:3;33992:45;33985:52;;33881:166;;34056:341;34123:38;34155:5;34123:38;:::i;:::-;34183:1;34197:154;34211:6;34208:1;34205:13;34197:154;;;34285:7;34279:14;34275:1;34270:3;34266:11;34259:35;34335:1;34326:7;34322:15;34311:26;;34233:4;34230:1;34226:12;34221:17;;34197:154;;;34380:6;34375:3;34371:16;34364:23;;34063:334;;33848:549;;33636:767;;33529:874;;;;:::o;34409:390::-;34515:3;34543:39;34576:5;34543:39;:::i;:::-;34598:89;34680:6;34675:3;34598:89;:::i;:::-;34591:96;;34696:65;34754:6;34749:3;34742:4;34735:5;34731:16;34696:65;:::i;:::-;34786:6;34781:3;34777:16;34770:23;;34519:280;34409:390;;;;:::o;34805:182::-;34973:7;34968:3;34961:20;34805:182;:::o;34993:693::-;35260:3;35282:92;35370:3;35361:6;35282:92;:::i;:::-;35275:99;;35391:95;35482:3;35473:6;35391:95;:::i;:::-;35384:102;;35496:137;35629:3;35496:137;:::i;:::-;35658:1;35653:3;35649:11;35642:18;;35677:3;35670:10;;34993:693;;;;;:::o;35692:225::-;35832:34;35828:1;35820:6;35816:14;35809:58;35901:8;35896:2;35888:6;35884:15;35877:33;35692:225;:::o;35923:366::-;36065:3;36086:67;36150:2;36145:3;36086:67;:::i;:::-;36079:74;;36162:93;36251:3;36162:93;:::i;:::-;36280:2;36275:3;36271:12;36264:19;;35923:366;;;:::o;36295:419::-;36461:4;36499:2;36488:9;36484:18;36476:26;;36548:9;36542:4;36538:20;36534:1;36523:9;36519:17;36512:47;36576:131;36702:4;36576:131;:::i;:::-;36568:139;;36295:419;;;:::o;36720:182::-;36860:34;36856:1;36848:6;36844:14;36837:58;36720:182;:::o;36908:366::-;37050:3;37071:67;37135:2;37130:3;37071:67;:::i;:::-;37064:74;;37147:93;37236:3;37147:93;:::i;:::-;37265:2;37260:3;37256:12;37249:19;;36908:366;;;:::o;37280:419::-;37446:4;37484:2;37473:9;37469:18;37461:26;;37533:9;37527:4;37523:20;37519:1;37508:9;37504:17;37497:47;37561:131;37687:4;37561:131;:::i;:::-;37553:139;;37280:419;;;:::o;37705:98::-;37756:6;37790:5;37784:12;37774:22;;37705:98;;;:::o;37809:168::-;37892:11;37926:6;37921:3;37914:19;37966:4;37961:3;37957:14;37942:29;;37809:168;;;;:::o;37983:373::-;38069:3;38097:38;38129:5;38097:38;:::i;:::-;38151:70;38214:6;38209:3;38151:70;:::i;:::-;38144:77;;38230:65;38288:6;38283:3;38276:4;38269:5;38265:16;38230:65;:::i;:::-;38320:29;38342:6;38320:29;:::i;:::-;38315:3;38311:39;38304:46;;38073:283;37983:373;;;;:::o;38362:640::-;38557:4;38595:3;38584:9;38580:19;38572:27;;38609:71;38677:1;38666:9;38662:17;38653:6;38609:71;:::i;:::-;38690:72;38758:2;38747:9;38743:18;38734:6;38690:72;:::i;:::-;38772;38840:2;38829:9;38825:18;38816:6;38772:72;:::i;:::-;38891:9;38885:4;38881:20;38876:2;38865:9;38861:18;38854:48;38919:76;38990:4;38981:6;38919:76;:::i;:::-;38911:84;;38362:640;;;;;;;:::o;39008:141::-;39064:5;39095:6;39089:13;39080:22;;39111:32;39137:5;39111:32;:::i;:::-;39008:141;;;;:::o;39155:349::-;39224:6;39273:2;39261:9;39252:7;39248:23;39244:32;39241:119;;;39279:79;;:::i;:::-;39241:119;39399:1;39424:63;39479:7;39470:6;39459:9;39455:22;39424:63;:::i;:::-;39414:73;;39370:127;39155:349;;;;:::o;39510:180::-;39558:77;39555:1;39548:88;39655:4;39652:1;39645:15;39679:4;39676:1;39669:15;39696:233;39735:3;39758:24;39776:5;39758:24;:::i;:::-;39749:33;;39804:66;39797:5;39794:77;39791:103;;39874:18;;:::i;:::-;39791:103;39921:1;39914:5;39910:13;39903:20;;39696:233;;;:::o;39935:180::-;39983:77;39980:1;39973:88;40080:4;40077:1;40070:15;40104:4;40101:1;40094:15;40121:185;40161:1;40178:20;40196:1;40178:20;:::i;:::-;40173:25;;40212:20;40230:1;40212:20;:::i;:::-;40207:25;;40251:1;40241:35;;40256:18;;:::i;:::-;40241:35;40298:1;40295;40291:9;40286:14;;40121:185;;;;:::o;40312:194::-;40352:4;40372:20;40390:1;40372:20;:::i;:::-;40367:25;;40406:20;40424:1;40406:20;:::i;:::-;40401:25;;40450:1;40447;40443:9;40435:17;;40474:1;40468:4;40465:11;40462:37;;;40479:18;;:::i;:::-;40462:37;40312:194;;;;:::o;40512:176::-;40544:1;40561:20;40579:1;40561:20;:::i;:::-;40556:25;;40595:20;40613:1;40595:20;:::i;:::-;40590:25;;40634:1;40624:35;;40639:18;;:::i;:::-;40624:35;40680:1;40677;40673:9;40668:14;;40512:176;;;;:::o;40694:191::-;40734:3;40753:20;40771:1;40753:20;:::i;:::-;40748:25;;40787:20;40805:1;40787:20;:::i;:::-;40782:25;;40830:1;40827;40823:9;40816:16;;40851:3;40848:1;40845:10;40842:36;;;40858:18;;:::i;:::-;40842:36;40694:191;;;;:::o

Swarm Source

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