Token Bulldog Bowlers

Overview CRC721

Total Supply:
6,000 Bulldog

Holders:
241 addresses
Balance
2 Bulldog
0x634a5dc4cda63ea8d0699d9387cdcfffc6408b84
Loading
[ Download CSV Export  ] 
Loading
[ Download CSV Export  ] 
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
BulldogNFT

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at cronoscan.com on 2022-06-09
*/

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

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


// OpenZeppelin Contracts v4.4.1 (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 Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

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

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

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

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

// File: @openzeppelin\contracts\utils\Address.sol


// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: @openzeppelin\contracts\utils\Strings.sol


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

pragma solidity ^0.8.0;

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

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

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

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

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

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


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

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @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);

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

// File: contracts\nft\IERC721A.sol


// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

// File: contracts\nft\extensions\IERC721AQueryable.sol


// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;


/**
 * @dev Interface of an ERC721AQueryable compliant contract.
 */
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`
     *
     * If the `tokenId` is burned:
     *   - `addr` = `<Address of owner before token was burned>`
     *   - `startTimestamp` = `<Timestamp when token was burned>`
     *   - `burned = `true`
     *
     * Otherwise:
     *   - `addr` = `<Address of owner>`
     *   - `startTimestamp` = `<Timestamp of start of ownership>`
     *   - `burned = `false`
     */
    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 pfp collections should be fine).
     */
    function tokensOfOwner(address owner) external view returns (uint256[] memory);
}

// File: contracts\nft\ERC721A.sol


// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;


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

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

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

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

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

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

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

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

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

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

    // Mapping from token ID to approved address.
    mapping(uint256 => address) private _tokenApprovals;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

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

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overriden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return '';
    }

    /**
     * @dev Casts the address to uint256 without masking.
     */
    function _addressToUint256(address value) private pure returns (uint256 result) {
        assembly {
            result := value
        }
    }

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

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

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

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

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

        return _tokenApprovals[tokenId];
    }

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

        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, '');
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        _transfer(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        return
            _startTokenId() <= tokenId &&
            tokenId < _currentIndex && // If within bounds,
            _packedOwnerships[tokenId] & BITMASK_BURNED == 0; // and not burned.
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) private {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

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

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

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

        _beforeTokenTransfers(from, to, tokenId, 1);

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

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

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

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

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

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

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

        address from = address(uint160(prevOwnershipPacked));

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

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

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

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

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

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

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

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

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

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkContractOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (
            bytes4 retval
        ) {
            return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
        } catch (bytes memory reason) {
            if (reason.length == 0) {
                revert TransferToNonERC721ReceiverImplementer();
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

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

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

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

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

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

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

// File: contracts\nft\extensions\ERC721AQueryable.sol


// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;



/**
 * @title ERC721A Queryable
 * @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`
     *
     * If the `tokenId` is burned:
     *   - `addr` = `<Address of owner before token was burned>`
     *   - `startTimestamp` = `<Timestamp when token was burned>`
     *   - `burned = `true`
     *
     * Otherwise:
     *   - `addr` = `<Address of owner>`
     *   - `startTimestamp` = `<Timestamp of start of ownership>`
     *   - `burned = `false`
     */
    function explicitOwnershipOf(uint256 tokenId) public view 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[] memory tokenIds) external view 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 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 pfp collections should be fine).
     */
    function tokensOfOwner(address owner) external view 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: contracts\nft\Bulldog.sol



pragma solidity ^0.8.4;







contract BulldogNFT is ERC721AQueryable, Ownable {
    using Address for address;
    using Strings for uint256;

    uint16 public pubsaleSupply = 6000;
    uint8 public limitPerAddress = 10;

    bool public revealed;

    bool public pubsaleOpen;

    uint256 public cost = 100 ether;

    mapping(address => uint256) public addressMints;

    string public baseURI;
    string public norevealedURI;
    string public baseExtension;

    IERC20 public token;

    constructor(IERC20 _token) ERC721A("Bulldog Bowlers", "Bulldog") {
      token = _token;
    }

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

    function setCost(uint256 _cost) external onlyOwner {
        cost = _cost;
    }

    function setLimitPerAddress(uint8 _limit) external onlyOwner {
        limitPerAddress = _limit;
    }

    function startPubsale() external onlyOwner {
        pubsaleOpen = true;
    }

    function endPubsale() external onlyOwner {
        pubsaleOpen = false;
    }

    function premint(address to, uint amount)
        external
        payable
        onlyOwner
    {
        _mint(to, amount);
    }

    function mint(uint256 amount) external {
        require(
            addressMints[msg.sender] + amount <= limitPerAddress,
            "ERROR: NFT limit"
        );
        require(totalSupply() + amount <= pubsaleSupply, "Invalid amount");
        require(pubsaleOpen, "Pubsale is not open");

        uint256 totalCost = cost * amount;
        require(token.balanceOf(msg.sender) >= totalCost, "Insufficient payment");

        token.transferFrom(msg.sender, address(this), totalCost);

        _mint(msg.sender, amount);
        addressMints[msg.sender] += amount;
    }

    function tokenURI(uint256 tokenId) public view override returns (string memory) {
        require(
            ownerOf(tokenId) != address(0),
            "ERC721Metadata: URI query for nonexistent token"
        );

        if (revealed == false) {
            return norevealedURI;
        }

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

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

    function setUnrevealedURI(string memory _uri) external onlyOwner {
        norevealedURI = _uri;
    }

    function setBaseExtension(string memory _ext) external onlyOwner {
        baseExtension = _ext;
    }

    function setPubsaleSupply(uint16 _amount) external onlyOwner {
        pubsaleSupply = _amount;
    }

    function reveal() external onlyOwner {
        revealed = true;
    }

    function withdraw(address payable to) external onlyOwner {
        Address.sendValue(to, address(this).balance);
    }

    function recoverToken(address to) external onlyOwner {
        token.transfer(to, token.balanceOf(address(this)));
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IERC20","name":"_token","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addressMints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endPubsale","outputs":[],"stateMutability":"nonpayable","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":"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":"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":[],"name":"limitPerAddress","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"norevealedURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"premint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"pubsaleOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pubsaleSupply","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"recoverToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_ext","type":"string"}],"name":"setBaseExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cost","type":"uint256"}],"name":"setCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_limit","type":"uint8"}],"name":"setLimitPerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_amount","type":"uint16"}],"name":"setPubsaleSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"name":"setUnrevealedURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startPubsale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"to","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526008805462ffffff60a01b191661a17760a41b17905568056bc75e2d631000006009553480156200003457600080fd5b5060405162002bf138038062002bf18339810160408190526200005791620001f4565b604080518082018252600f81526e42756c6c646f6720426f776c65727360881b60208083019182528351808501909452600784526642756c6c646f6760c81b908401528151919291620000ad916002916200014e565b508051620000c39060039060208401906200014e565b5050600160005550620000d633620000fc565b600e80546001600160a01b0319166001600160a01b039290921691909117905562000261565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8280546200015c9062000224565b90600052602060002090601f016020900481019282620001805760008555620001cb565b82601f106200019b57805160ff1916838001178555620001cb565b82800160010185558215620001cb579182015b82811115620001cb578251825591602001919060010190620001ae565b50620001d9929150620001dd565b5090565b5b80821115620001d95760008155600101620001de565b60006020828403121562000206578081fd5b81516001600160a01b03811681146200021d578182fd5b9392505050565b600181811c908216806200023957607f821691505b602082108114156200025b57634e487b7160e01b600052602260045260246000fd5b50919050565b61298080620002716000396000f3fe6080604052600436106102675760003560e01c80638462151c11610144578063b584b78d116100b6578063cfbe73551161007a578063cfbe735514610755578063da3ef23f14610775578063e985e9c514610795578063f2fde38b146107b5578063fc0c546a146107d5578063fe2c7fee146107f557600080fd5b8063b584b78d146106be578063b88d4fde146106d3578063c23dc68f146106f3578063c668286214610720578063c87b56dd1461073557600080fd5b806399a2557a1161010857806399a2557a146106085780639be65a60146106285780639c3e73c314610648578063a0712d6814610669578063a22cb46514610689578063a475b5dd146106a957600080fd5b80638462151c146105665780638611244c146105935780638da5cb5b146105a857806395d89b41146105c6578063964c33b5146105db57600080fd5b806342ca1d09116101dd5780635bbb2177116101a15780635bbb2177146104af5780636352211e146104dc5780636833a228146104fc5780636c0360eb1461051c57806370a0823114610531578063715018a61461055157600080fd5b806342ca1d09146103f957806344a0d68a1461042e578063518302271461044e57806351cff8d91461046f57806355f804b31461048f57600080fd5b806313faede61161022f57806313faede61461033257806318160ddd1461035657806323b872dd146103735780632a484ad4146103935780632b5e3e26146103c657806342842e0e146103d957600080fd5b806301ffc9a71461026c57806303a17969146102a157806306fdde03146102b8578063081812fc146102da578063095ea7b314610312575b600080fd5b34801561027857600080fd5b5061028c61028736600461246d565b610815565b60405190151581526020015b60405180910390f35b3480156102ad57600080fd5b506102b6610867565b005b3480156102c457600080fd5b506102cd6108a9565b604051610298919061272a565b3480156102e657600080fd5b506102fa6102f536600461250c565b61093b565b6040516001600160a01b039091168152602001610298565b34801561031e57600080fd5b506102b661032d36600461234b565b61097f565b34801561033e57600080fd5b5061034860095481565b604051908152602001610298565b34801561036257600080fd5b506001546000540360001901610348565b34801561037f57600080fd5b506102b661038e366004612262565b610a52565b34801561039f57600080fd5b506008546103b490600160b01b900460ff1681565b60405160ff9091168152602001610298565b6102b66103d436600461234b565b610a62565b3480156103e557600080fd5b506102b66103f4366004612262565b610a9a565b34801561040557600080fd5b5060085461041b90600160a01b900461ffff1681565b60405161ffff9091168152602001610298565b34801561043a57600080fd5b506102b661044936600461250c565b610ab5565b34801561045a57600080fd5b5060085461028c90600160b81b900460ff1681565b34801561047b57600080fd5b506102b661048a36600461220e565b610ae4565b34801561049b57600080fd5b506102b66104aa3660046124a5565b610b1b565b3480156104bb57600080fd5b506104cf6104ca3660046123aa565b610b58565b6040516102989190612688565b3480156104e857600080fd5b506102fa6104f736600461250c565b610c48565b34801561050857600080fd5b506102b661051736600461253c565b610c53565b34801561052857600080fd5b506102cd610c9d565b34801561053d57600080fd5b5061034861054c36600461220e565b610d2b565b34801561055d57600080fd5b506102b6610d79565b34801561057257600080fd5b5061058661058136600461220e565b610daf565b60405161029891906126f2565b34801561059f57600080fd5b506102b6610ed3565b3480156105b457600080fd5b506008546001600160a01b03166102fa565b3480156105d257600080fd5b506102cd610f12565b3480156105e757600080fd5b506103486105f636600461220e565b600a6020526000908152604090205481565b34801561061457600080fd5b50610586610623366004612376565b610f21565b34801561063457600080fd5b506102b661064336600461220e565b6110c8565b34801561065457600080fd5b5060085461028c90600160c01b900460ff1681565b34801561067557600080fd5b506102b661068436600461250c565b6111f5565b34801561069557600080fd5b506102b66106a436600461231e565b6114ac565b3480156106b557600080fd5b506102b6611542565b3480156106ca57600080fd5b506102cd611581565b3480156106df57600080fd5b506102b66106ee3660046122a2565b61158e565b3480156106ff57600080fd5b5061071361070e36600461250c565b6115d8565b6040516102989190612772565b34801561072c57600080fd5b506102cd61164d565b34801561074157600080fd5b506102cd61075036600461250c565b61165a565b34801561076157600080fd5b506102b66107703660046124ea565b61185a565b34801561078157600080fd5b506102b66107903660046124a5565b6118a6565b3480156107a157600080fd5b5061028c6107b036600461222a565b6118e3565b3480156107c157600080fd5b506102b66107d036600461220e565b611911565b3480156107e157600080fd5b50600e546102fa906001600160a01b031681565b34801561080157600080fd5b506102b66108103660046124a5565b6119a9565b60006301ffc9a760e01b6001600160e01b03198316148061084657506380ac58cd60e01b6001600160e01b03198316145b806108615750635b5e139f60e01b6001600160e01b03198316145b92915050565b6008546001600160a01b0316331461089a5760405162461bcd60e51b81526004016108919061273d565b60405180910390fd5b6008805460ff60c01b19169055565b6060600280546108b890612865565b80601f01602080910402602001604051908101604052809291908181526020018280546108e490612865565b80156109315780601f1061090657610100808354040283529160200191610931565b820191906000526020600020905b81548152906001019060200180831161091457829003601f168201915b5050505050905090565b6000610946826119e6565b610963576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b600061098a82611a1b565b9050806001600160a01b0316836001600160a01b031614156109bf5760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b038216146109f6576109d981336118e3565b6109f6576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b610a5d838383611a84565b505050565b6008546001600160a01b03163314610a8c5760405162461bcd60e51b81526004016108919061273d565b610a968282611c27565b5050565b610a5d8383836040518060200160405280600081525061158e565b6008546001600160a01b03163314610adf5760405162461bcd60e51b81526004016108919061273d565b600955565b6008546001600160a01b03163314610b0e5760405162461bcd60e51b81526004016108919061273d565b610b188147611d05565b50565b6008546001600160a01b03163314610b455760405162461bcd60e51b81526004016108919061273d565b8051610a9690600b90602084019061211e565b80516060906000816001600160401b03811115610b8557634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610bd057816020015b6040805160608101825260008082526020808301829052928201528252600019909201910181610ba35790505b50905060005b828114610c4057610c0d858281518110610c0057634e487b7160e01b600052603260045260246000fd5b60200260200101516115d8565b828281518110610c2d57634e487b7160e01b600052603260045260246000fd5b6020908102919091010152600101610bd6565b509392505050565b600061086182611a1b565b6008546001600160a01b03163314610c7d5760405162461bcd60e51b81526004016108919061273d565b6008805460ff909216600160b01b0260ff60b01b19909216919091179055565b600b8054610caa90612865565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd690612865565b8015610d235780601f10610cf857610100808354040283529160200191610d23565b820191906000526020600020905b815481529060010190602001808311610d0657829003601f168201915b505050505081565b60006001600160a01b038216610d54576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6008546001600160a01b03163314610da35760405162461bcd60e51b81526004016108919061273d565b610dad6000611e1e565b565b60606000806000610dbf85610d2b565b90506000816001600160401b03811115610de957634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610e12578160200160208202803683370190505b509050610e38604080516060810182526000808252602082018190529181019190915290565b60015b838614610ec757610e4b81611e70565b9150816040015115610e5c57610ebf565b81516001600160a01b031615610e7157815194505b876001600160a01b0316856001600160a01b03161415610ebf5780838780600101985081518110610eb257634e487b7160e01b600052603260045260246000fd5b6020026020010181815250505b600101610e3b565b50909695505050505050565b6008546001600160a01b03163314610efd5760405162461bcd60e51b81526004016108919061273d565b6008805460ff60c01b1916600160c01b179055565b6060600380546108b890612865565b6060818310610f4357604051631960ccad60e11b815260040160405180910390fd5b600080610f4f60005490565b90506001851015610f5f57600194505b80841115610f6b578093505b6000610f7687610d2b565b905084861015610f955785850381811015610f8f578091505b50610f99565b5060005b6000816001600160401b03811115610fc157634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610fea578160200160208202803683370190505b50905081610ffd5793506110c192505050565b6000611008886115d8565b905060008160400151611019575080515b885b88811415801561102b5750848714155b156110b55761103981611e70565b925082604001511561104a576110ad565b82516001600160a01b03161561105f57825191505b8a6001600160a01b0316826001600160a01b031614156110ad57808488806001019950815181106110a057634e487b7160e01b600052603260045260246000fd5b6020026020010181815250505b60010161101b565b50505092835250909150505b9392505050565b6008546001600160a01b031633146110f25760405162461bcd60e51b81526004016108919061273d565b600e546040516370a0823160e01b81523060048201526001600160a01b039091169063a9059cbb90839083906370a082319060240160206040518083038186803b15801561113f57600080fd5b505afa158015611153573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111779190612524565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b1580156111bd57600080fd5b505af11580156111d1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a969190612451565b600854336000908152600a6020526040902054600160b01b90910460ff169061121f9083906127d7565b11156112605760405162461bcd60e51b815260206004820152601060248201526f11549493d48e88139195081b1a5b5a5d60821b6044820152606401610891565b600854600160a01b900461ffff16816112826001546000546000199190030190565b61128c91906127d7565b11156112cb5760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606401610891565b600854600160c01b900460ff1661131a5760405162461bcd60e51b8152602060048201526013602482015272283ab139b0b6329034b9903737ba1037b832b760691b6044820152606401610891565b60008160095461132a9190612803565b600e546040516370a0823160e01b815233600482015291925082916001600160a01b03909116906370a082319060240160206040518083038186803b15801561137257600080fd5b505afa158015611386573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113aa9190612524565b10156113ef5760405162461bcd60e51b8152602060048201526014602482015273125b9cdd59999a58da595b9d081c185e5b595b9d60621b6044820152606401610891565b600e546040516323b872dd60e01b8152336004820152306024820152604481018390526001600160a01b03909116906323b872dd90606401602060405180830381600087803b15801561144157600080fd5b505af1158015611455573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114799190612451565b506114843383611c27565b336000908152600a6020526040812080548492906114a39084906127d7565b90915550505050565b6001600160a01b0382163314156114d65760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6008546001600160a01b0316331461156c5760405162461bcd60e51b81526004016108919061273d565b6008805460ff60b81b1916600160b81b179055565b600c8054610caa90612865565b611599848484611a84565b6001600160a01b0383163b156115d2576115b584848484611ea5565b6115d2576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b6040805160608082018352600080835260208084018290528385018290528451928301855281835282018190529281019290925290600183108061161e57506000548310155b156116295792915050565b61163283611e70565b90508060400151156116445792915050565b6110c183611f9d565b600d8054610caa90612865565b6060600061166783610c48565b6001600160a01b031614156116d65760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610891565b600854600160b81b900460ff1661177957600c80546116f490612865565b80601f016020809104026020016040519081016040528092919081815260200182805461172090612865565b801561176d5780601f106117425761010080835404028352916020019161176d565b820191906000526020600020905b81548152906001019060200180831161175057829003601f168201915b50505050509050919050565b6000600b805461178890612865565b80601f01602080910402602001604051908101604052809291908181526020018280546117b490612865565b80156118015780601f106117d657610100808354040283529160200191611801565b820191906000526020600020905b8154815290600101906020018083116117e457829003601f168201915b50505050509050600081511161182657604051806020016040528060008152506110c1565b8061183084611fcb565b600d60405160200161184493929190612589565b6040516020818303038152906040529392505050565b6008546001600160a01b031633146118845760405162461bcd60e51b81526004016108919061273d565b6008805461ffff909216600160a01b0261ffff60a01b19909216919091179055565b6008546001600160a01b031633146118d05760405162461bcd60e51b81526004016108919061273d565b8051610a9690600d90602084019061211e565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b6008546001600160a01b0316331461193b5760405162461bcd60e51b81526004016108919061273d565b6001600160a01b0381166119a05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610891565b610b1881611e1e565b6008546001600160a01b031633146119d35760405162461bcd60e51b81526004016108919061273d565b8051610a9690600c90602084019061211e565b6000816001111580156119fa575060005482105b8015610861575050600090815260046020526040902054600160e01b161590565b60008180600111611a6b57600054811015611a6b57600081815260046020526040902054600160e01b8116611a69575b806110c1575060001901600081815260046020526040902054611a4b565b505b604051636f96cda160e11b815260040160405180910390fd5b6000611a8f82611a1b565b9050836001600160a01b0316816001600160a01b031614611ac25760405162a1148160e81b815260040160405180910390fd5b6000336001600160a01b0386161480611ae05750611ae085336118e3565b80611afb575033611af08461093b565b6001600160a01b0316145b905080611b1b57604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038416611b4257604051633a954ecd60e21b815260040160405180910390fd5b600083815260066020908152604080832080546001600160a01b03191690556001600160a01b038881168452600583528184208054600019019055871683528083208054600101905585835260049091529020600160e11b4260a01b861781179091558216611bdf5760018301600081815260046020526040902054611bdd576000548114611bdd5760008181526004602052604090208390555b505b82846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050505050565b6000546001600160a01b038316611c5057604051622e076360e81b815260040160405180910390fd5b81611c6e5760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b03831660009081526005602090815260408083208054680100000000000000018702019055838352600490915290204260a01b84176001841460e11b179055808083015b6040516001830192906001600160a01b038716906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4808210611cb95750600055505050565b80471015611d555760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610891565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611da2576040519150601f19603f3d011682016040523d82523d6000602084013e611da7565b606091505b5050905080610a5d5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610891565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6040805160608101825260008082526020820181905291810191909152600082815260046020526040902054610861906120e4565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290611eda90339089908890889060040161264b565b602060405180830381600087803b158015611ef457600080fd5b505af1925050508015611f24575060408051601f3d908101601f19168201909252611f2191810190612489565b60015b611f7f573d808015611f52576040519150601f19603f3d011682016040523d82523d6000602084013e611f57565b606091505b508051611f77576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b6040805160608101825260008082526020820181905291810191909152610861611fc683611a1b565b6120e4565b606081611fef5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156120195780612003816128a0565b91506120129050600a836127ef565b9150611ff3565b6000816001600160401b0381111561204157634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561206b576020820181803683370190505b5090505b8415611f9557612080600183612822565b915061208d600a866128bb565b6120989060306127d7565b60f81b8183815181106120bb57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506120dd600a866127ef565b945061206f565b604080516060810182526001600160a01b038316815260a083901c6001600160401b03166020820152600160e01b90921615159082015290565b82805461212a90612865565b90600052602060002090601f01602090048101928261214c5760008555612192565b82601f1061216557805160ff1916838001178555612192565b82800160010185558215612192579182015b82811115612192578251825591602001919060010190612177565b5061219e9291506121a2565b5090565b5b8082111561219e57600081556001016121a3565b60006001600160401b038311156121d0576121d06128fb565b6121e3601f8401601f19166020016127a7565b90508281528383830111156121f757600080fd5b828260208301376000602084830101529392505050565b60006020828403121561221f578081fd5b81356110c181612911565b6000806040838503121561223c578081fd5b823561224781612911565b9150602083013561225781612911565b809150509250929050565b600080600060608486031215612276578081fd5b833561228181612911565b9250602084013561229181612911565b929592945050506040919091013590565b600080600080608085870312156122b7578081fd5b84356122c281612911565b935060208501356122d281612911565b92506040850135915060608501356001600160401b038111156122f3578182fd5b8501601f81018713612303578182fd5b612312878235602084016121b7565b91505092959194509250565b60008060408385031215612330578182fd5b823561233b81612911565b9150602083013561225781612926565b6000806040838503121561235d578182fd5b823561236881612911565b946020939093013593505050565b60008060006060848603121561238a578283fd5b833561239581612911565b95602085013595506040909401359392505050565b600060208083850312156123bc578182fd5b82356001600160401b03808211156123d2578384fd5b818501915085601f8301126123e5578384fd5b8135818111156123f7576123f76128fb565b8060051b91506124088483016127a7565b8181528481019084860184860187018a1015612422578788fd5b8795505b83861015612444578035835260019590950194918601918601612426565b5098975050505050505050565b600060208284031215612462578081fd5b81516110c181612926565b60006020828403121561247e578081fd5b81356110c181612934565b60006020828403121561249a578081fd5b81516110c181612934565b6000602082840312156124b6578081fd5b81356001600160401b038111156124cb578182fd5b8201601f810184136124db578182fd5b611f95848235602084016121b7565b6000602082840312156124fb578081fd5b813561ffff811681146110c1578182fd5b60006020828403121561251d578081fd5b5035919050565b600060208284031215612535578081fd5b5051919050565b60006020828403121561254d578081fd5b813560ff811681146110c1578182fd5b60008151808452612575816020860160208601612839565b601f01601f19169290920160200192915050565b60008451602061259c8285838a01612839565b8551918401916125af8184848a01612839565b85549201918390600181811c90808316806125cb57607f831692505b8583108114156125e957634e487b7160e01b88526022600452602488fd5b8080156125fd576001811461260e5761263a565b60ff1985168852838801955061263a565b60008b815260209020895b858110156126325781548a820152908401908801612619565b505083880195505b50939b9a5050505050505050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061267e9083018461255d565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015610ec7576126df83855180516001600160a01b031682526020808201516001600160401b0316908301526040908101511515910152565b92840192606092909201916001016126a4565b6020808252825182820181905260009190848201906040850190845b81811015610ec75783518352928401929184019160010161270e565b6020815260006110c1602083018461255d565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b81516001600160a01b031681526020808301516001600160401b03169082015260408083015115159082015260608101610861565b604051601f8201601f191681016001600160401b03811182821017156127cf576127cf6128fb565b604052919050565b600082198211156127ea576127ea6128cf565b500190565b6000826127fe576127fe6128e5565b500490565b600081600019048311821515161561281d5761281d6128cf565b500290565b600082821015612834576128346128cf565b500390565b60005b8381101561285457818101518382015260200161283c565b838111156115d25750506000910152565b600181811c9082168061287957607f821691505b6020821081141561289a57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156128b4576128b46128cf565b5060010190565b6000826128ca576128ca6128e5565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610b1857600080fd5b8015158114610b1857600080fd5b6001600160e01b031981168114610b1857600080fdfea2646970667358221220581275337aaf4c9120848ac215650cc1bc16190c2ff1098bd3e4c49f121b4cff64736f6c63430008040033000000000000000000000000efd450027bd0ee84afafbc75f5a80c367efbf651

Deployed Bytecode

0x6080604052600436106102675760003560e01c80638462151c11610144578063b584b78d116100b6578063cfbe73551161007a578063cfbe735514610755578063da3ef23f14610775578063e985e9c514610795578063f2fde38b146107b5578063fc0c546a146107d5578063fe2c7fee146107f557600080fd5b8063b584b78d146106be578063b88d4fde146106d3578063c23dc68f146106f3578063c668286214610720578063c87b56dd1461073557600080fd5b806399a2557a1161010857806399a2557a146106085780639be65a60146106285780639c3e73c314610648578063a0712d6814610669578063a22cb46514610689578063a475b5dd146106a957600080fd5b80638462151c146105665780638611244c146105935780638da5cb5b146105a857806395d89b41146105c6578063964c33b5146105db57600080fd5b806342ca1d09116101dd5780635bbb2177116101a15780635bbb2177146104af5780636352211e146104dc5780636833a228146104fc5780636c0360eb1461051c57806370a0823114610531578063715018a61461055157600080fd5b806342ca1d09146103f957806344a0d68a1461042e578063518302271461044e57806351cff8d91461046f57806355f804b31461048f57600080fd5b806313faede61161022f57806313faede61461033257806318160ddd1461035657806323b872dd146103735780632a484ad4146103935780632b5e3e26146103c657806342842e0e146103d957600080fd5b806301ffc9a71461026c57806303a17969146102a157806306fdde03146102b8578063081812fc146102da578063095ea7b314610312575b600080fd5b34801561027857600080fd5b5061028c61028736600461246d565b610815565b60405190151581526020015b60405180910390f35b3480156102ad57600080fd5b506102b6610867565b005b3480156102c457600080fd5b506102cd6108a9565b604051610298919061272a565b3480156102e657600080fd5b506102fa6102f536600461250c565b61093b565b6040516001600160a01b039091168152602001610298565b34801561031e57600080fd5b506102b661032d36600461234b565b61097f565b34801561033e57600080fd5b5061034860095481565b604051908152602001610298565b34801561036257600080fd5b506001546000540360001901610348565b34801561037f57600080fd5b506102b661038e366004612262565b610a52565b34801561039f57600080fd5b506008546103b490600160b01b900460ff1681565b60405160ff9091168152602001610298565b6102b66103d436600461234b565b610a62565b3480156103e557600080fd5b506102b66103f4366004612262565b610a9a565b34801561040557600080fd5b5060085461041b90600160a01b900461ffff1681565b60405161ffff9091168152602001610298565b34801561043a57600080fd5b506102b661044936600461250c565b610ab5565b34801561045a57600080fd5b5060085461028c90600160b81b900460ff1681565b34801561047b57600080fd5b506102b661048a36600461220e565b610ae4565b34801561049b57600080fd5b506102b66104aa3660046124a5565b610b1b565b3480156104bb57600080fd5b506104cf6104ca3660046123aa565b610b58565b6040516102989190612688565b3480156104e857600080fd5b506102fa6104f736600461250c565b610c48565b34801561050857600080fd5b506102b661051736600461253c565b610c53565b34801561052857600080fd5b506102cd610c9d565b34801561053d57600080fd5b5061034861054c36600461220e565b610d2b565b34801561055d57600080fd5b506102b6610d79565b34801561057257600080fd5b5061058661058136600461220e565b610daf565b60405161029891906126f2565b34801561059f57600080fd5b506102b6610ed3565b3480156105b457600080fd5b506008546001600160a01b03166102fa565b3480156105d257600080fd5b506102cd610f12565b3480156105e757600080fd5b506103486105f636600461220e565b600a6020526000908152604090205481565b34801561061457600080fd5b50610586610623366004612376565b610f21565b34801561063457600080fd5b506102b661064336600461220e565b6110c8565b34801561065457600080fd5b5060085461028c90600160c01b900460ff1681565b34801561067557600080fd5b506102b661068436600461250c565b6111f5565b34801561069557600080fd5b506102b66106a436600461231e565b6114ac565b3480156106b557600080fd5b506102b6611542565b3480156106ca57600080fd5b506102cd611581565b3480156106df57600080fd5b506102b66106ee3660046122a2565b61158e565b3480156106ff57600080fd5b5061071361070e36600461250c565b6115d8565b6040516102989190612772565b34801561072c57600080fd5b506102cd61164d565b34801561074157600080fd5b506102cd61075036600461250c565b61165a565b34801561076157600080fd5b506102b66107703660046124ea565b61185a565b34801561078157600080fd5b506102b66107903660046124a5565b6118a6565b3480156107a157600080fd5b5061028c6107b036600461222a565b6118e3565b3480156107c157600080fd5b506102b66107d036600461220e565b611911565b3480156107e157600080fd5b50600e546102fa906001600160a01b031681565b34801561080157600080fd5b506102b66108103660046124a5565b6119a9565b60006301ffc9a760e01b6001600160e01b03198316148061084657506380ac58cd60e01b6001600160e01b03198316145b806108615750635b5e139f60e01b6001600160e01b03198316145b92915050565b6008546001600160a01b0316331461089a5760405162461bcd60e51b81526004016108919061273d565b60405180910390fd5b6008805460ff60c01b19169055565b6060600280546108b890612865565b80601f01602080910402602001604051908101604052809291908181526020018280546108e490612865565b80156109315780601f1061090657610100808354040283529160200191610931565b820191906000526020600020905b81548152906001019060200180831161091457829003601f168201915b5050505050905090565b6000610946826119e6565b610963576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b600061098a82611a1b565b9050806001600160a01b0316836001600160a01b031614156109bf5760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b038216146109f6576109d981336118e3565b6109f6576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b610a5d838383611a84565b505050565b6008546001600160a01b03163314610a8c5760405162461bcd60e51b81526004016108919061273d565b610a968282611c27565b5050565b610a5d8383836040518060200160405280600081525061158e565b6008546001600160a01b03163314610adf5760405162461bcd60e51b81526004016108919061273d565b600955565b6008546001600160a01b03163314610b0e5760405162461bcd60e51b81526004016108919061273d565b610b188147611d05565b50565b6008546001600160a01b03163314610b455760405162461bcd60e51b81526004016108919061273d565b8051610a9690600b90602084019061211e565b80516060906000816001600160401b03811115610b8557634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610bd057816020015b6040805160608101825260008082526020808301829052928201528252600019909201910181610ba35790505b50905060005b828114610c4057610c0d858281518110610c0057634e487b7160e01b600052603260045260246000fd5b60200260200101516115d8565b828281518110610c2d57634e487b7160e01b600052603260045260246000fd5b6020908102919091010152600101610bd6565b509392505050565b600061086182611a1b565b6008546001600160a01b03163314610c7d5760405162461bcd60e51b81526004016108919061273d565b6008805460ff909216600160b01b0260ff60b01b19909216919091179055565b600b8054610caa90612865565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd690612865565b8015610d235780601f10610cf857610100808354040283529160200191610d23565b820191906000526020600020905b815481529060010190602001808311610d0657829003601f168201915b505050505081565b60006001600160a01b038216610d54576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6008546001600160a01b03163314610da35760405162461bcd60e51b81526004016108919061273d565b610dad6000611e1e565b565b60606000806000610dbf85610d2b565b90506000816001600160401b03811115610de957634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610e12578160200160208202803683370190505b509050610e38604080516060810182526000808252602082018190529181019190915290565b60015b838614610ec757610e4b81611e70565b9150816040015115610e5c57610ebf565b81516001600160a01b031615610e7157815194505b876001600160a01b0316856001600160a01b03161415610ebf5780838780600101985081518110610eb257634e487b7160e01b600052603260045260246000fd5b6020026020010181815250505b600101610e3b565b50909695505050505050565b6008546001600160a01b03163314610efd5760405162461bcd60e51b81526004016108919061273d565b6008805460ff60c01b1916600160c01b179055565b6060600380546108b890612865565b6060818310610f4357604051631960ccad60e11b815260040160405180910390fd5b600080610f4f60005490565b90506001851015610f5f57600194505b80841115610f6b578093505b6000610f7687610d2b565b905084861015610f955785850381811015610f8f578091505b50610f99565b5060005b6000816001600160401b03811115610fc157634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610fea578160200160208202803683370190505b50905081610ffd5793506110c192505050565b6000611008886115d8565b905060008160400151611019575080515b885b88811415801561102b5750848714155b156110b55761103981611e70565b925082604001511561104a576110ad565b82516001600160a01b03161561105f57825191505b8a6001600160a01b0316826001600160a01b031614156110ad57808488806001019950815181106110a057634e487b7160e01b600052603260045260246000fd5b6020026020010181815250505b60010161101b565b50505092835250909150505b9392505050565b6008546001600160a01b031633146110f25760405162461bcd60e51b81526004016108919061273d565b600e546040516370a0823160e01b81523060048201526001600160a01b039091169063a9059cbb90839083906370a082319060240160206040518083038186803b15801561113f57600080fd5b505afa158015611153573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111779190612524565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b1580156111bd57600080fd5b505af11580156111d1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a969190612451565b600854336000908152600a6020526040902054600160b01b90910460ff169061121f9083906127d7565b11156112605760405162461bcd60e51b815260206004820152601060248201526f11549493d48e88139195081b1a5b5a5d60821b6044820152606401610891565b600854600160a01b900461ffff16816112826001546000546000199190030190565b61128c91906127d7565b11156112cb5760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606401610891565b600854600160c01b900460ff1661131a5760405162461bcd60e51b8152602060048201526013602482015272283ab139b0b6329034b9903737ba1037b832b760691b6044820152606401610891565b60008160095461132a9190612803565b600e546040516370a0823160e01b815233600482015291925082916001600160a01b03909116906370a082319060240160206040518083038186803b15801561137257600080fd5b505afa158015611386573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113aa9190612524565b10156113ef5760405162461bcd60e51b8152602060048201526014602482015273125b9cdd59999a58da595b9d081c185e5b595b9d60621b6044820152606401610891565b600e546040516323b872dd60e01b8152336004820152306024820152604481018390526001600160a01b03909116906323b872dd90606401602060405180830381600087803b15801561144157600080fd5b505af1158015611455573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114799190612451565b506114843383611c27565b336000908152600a6020526040812080548492906114a39084906127d7565b90915550505050565b6001600160a01b0382163314156114d65760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6008546001600160a01b0316331461156c5760405162461bcd60e51b81526004016108919061273d565b6008805460ff60b81b1916600160b81b179055565b600c8054610caa90612865565b611599848484611a84565b6001600160a01b0383163b156115d2576115b584848484611ea5565b6115d2576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b6040805160608082018352600080835260208084018290528385018290528451928301855281835282018190529281019290925290600183108061161e57506000548310155b156116295792915050565b61163283611e70565b90508060400151156116445792915050565b6110c183611f9d565b600d8054610caa90612865565b6060600061166783610c48565b6001600160a01b031614156116d65760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610891565b600854600160b81b900460ff1661177957600c80546116f490612865565b80601f016020809104026020016040519081016040528092919081815260200182805461172090612865565b801561176d5780601f106117425761010080835404028352916020019161176d565b820191906000526020600020905b81548152906001019060200180831161175057829003601f168201915b50505050509050919050565b6000600b805461178890612865565b80601f01602080910402602001604051908101604052809291908181526020018280546117b490612865565b80156118015780601f106117d657610100808354040283529160200191611801565b820191906000526020600020905b8154815290600101906020018083116117e457829003601f168201915b50505050509050600081511161182657604051806020016040528060008152506110c1565b8061183084611fcb565b600d60405160200161184493929190612589565b6040516020818303038152906040529392505050565b6008546001600160a01b031633146118845760405162461bcd60e51b81526004016108919061273d565b6008805461ffff909216600160a01b0261ffff60a01b19909216919091179055565b6008546001600160a01b031633146118d05760405162461bcd60e51b81526004016108919061273d565b8051610a9690600d90602084019061211e565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b6008546001600160a01b0316331461193b5760405162461bcd60e51b81526004016108919061273d565b6001600160a01b0381166119a05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610891565b610b1881611e1e565b6008546001600160a01b031633146119d35760405162461bcd60e51b81526004016108919061273d565b8051610a9690600c90602084019061211e565b6000816001111580156119fa575060005482105b8015610861575050600090815260046020526040902054600160e01b161590565b60008180600111611a6b57600054811015611a6b57600081815260046020526040902054600160e01b8116611a69575b806110c1575060001901600081815260046020526040902054611a4b565b505b604051636f96cda160e11b815260040160405180910390fd5b6000611a8f82611a1b565b9050836001600160a01b0316816001600160a01b031614611ac25760405162a1148160e81b815260040160405180910390fd5b6000336001600160a01b0386161480611ae05750611ae085336118e3565b80611afb575033611af08461093b565b6001600160a01b0316145b905080611b1b57604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038416611b4257604051633a954ecd60e21b815260040160405180910390fd5b600083815260066020908152604080832080546001600160a01b03191690556001600160a01b038881168452600583528184208054600019019055871683528083208054600101905585835260049091529020600160e11b4260a01b861781179091558216611bdf5760018301600081815260046020526040902054611bdd576000548114611bdd5760008181526004602052604090208390555b505b82846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050505050565b6000546001600160a01b038316611c5057604051622e076360e81b815260040160405180910390fd5b81611c6e5760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b03831660009081526005602090815260408083208054680100000000000000018702019055838352600490915290204260a01b84176001841460e11b179055808083015b6040516001830192906001600160a01b038716906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4808210611cb95750600055505050565b80471015611d555760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610891565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611da2576040519150601f19603f3d011682016040523d82523d6000602084013e611da7565b606091505b5050905080610a5d5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610891565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6040805160608101825260008082526020820181905291810191909152600082815260046020526040902054610861906120e4565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290611eda90339089908890889060040161264b565b602060405180830381600087803b158015611ef457600080fd5b505af1925050508015611f24575060408051601f3d908101601f19168201909252611f2191810190612489565b60015b611f7f573d808015611f52576040519150601f19603f3d011682016040523d82523d6000602084013e611f57565b606091505b508051611f77576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b6040805160608101825260008082526020820181905291810191909152610861611fc683611a1b565b6120e4565b606081611fef5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156120195780612003816128a0565b91506120129050600a836127ef565b9150611ff3565b6000816001600160401b0381111561204157634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561206b576020820181803683370190505b5090505b8415611f9557612080600183612822565b915061208d600a866128bb565b6120989060306127d7565b60f81b8183815181106120bb57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506120dd600a866127ef565b945061206f565b604080516060810182526001600160a01b038316815260a083901c6001600160401b03166020820152600160e01b90921615159082015290565b82805461212a90612865565b90600052602060002090601f01602090048101928261214c5760008555612192565b82601f1061216557805160ff1916838001178555612192565b82800160010185558215612192579182015b82811115612192578251825591602001919060010190612177565b5061219e9291506121a2565b5090565b5b8082111561219e57600081556001016121a3565b60006001600160401b038311156121d0576121d06128fb565b6121e3601f8401601f19166020016127a7565b90508281528383830111156121f757600080fd5b828260208301376000602084830101529392505050565b60006020828403121561221f578081fd5b81356110c181612911565b6000806040838503121561223c578081fd5b823561224781612911565b9150602083013561225781612911565b809150509250929050565b600080600060608486031215612276578081fd5b833561228181612911565b9250602084013561229181612911565b929592945050506040919091013590565b600080600080608085870312156122b7578081fd5b84356122c281612911565b935060208501356122d281612911565b92506040850135915060608501356001600160401b038111156122f3578182fd5b8501601f81018713612303578182fd5b612312878235602084016121b7565b91505092959194509250565b60008060408385031215612330578182fd5b823561233b81612911565b9150602083013561225781612926565b6000806040838503121561235d578182fd5b823561236881612911565b946020939093013593505050565b60008060006060848603121561238a578283fd5b833561239581612911565b95602085013595506040909401359392505050565b600060208083850312156123bc578182fd5b82356001600160401b03808211156123d2578384fd5b818501915085601f8301126123e5578384fd5b8135818111156123f7576123f76128fb565b8060051b91506124088483016127a7565b8181528481019084860184860187018a1015612422578788fd5b8795505b83861015612444578035835260019590950194918601918601612426565b5098975050505050505050565b600060208284031215612462578081fd5b81516110c181612926565b60006020828403121561247e578081fd5b81356110c181612934565b60006020828403121561249a578081fd5b81516110c181612934565b6000602082840312156124b6578081fd5b81356001600160401b038111156124cb578182fd5b8201601f810184136124db578182fd5b611f95848235602084016121b7565b6000602082840312156124fb578081fd5b813561ffff811681146110c1578182fd5b60006020828403121561251d578081fd5b5035919050565b600060208284031215612535578081fd5b5051919050565b60006020828403121561254d578081fd5b813560ff811681146110c1578182fd5b60008151808452612575816020860160208601612839565b601f01601f19169290920160200192915050565b60008451602061259c8285838a01612839565b8551918401916125af8184848a01612839565b85549201918390600181811c90808316806125cb57607f831692505b8583108114156125e957634e487b7160e01b88526022600452602488fd5b8080156125fd576001811461260e5761263a565b60ff1985168852838801955061263a565b60008b815260209020895b858110156126325781548a820152908401908801612619565b505083880195505b50939b9a5050505050505050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061267e9083018461255d565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015610ec7576126df83855180516001600160a01b031682526020808201516001600160401b0316908301526040908101511515910152565b92840192606092909201916001016126a4565b6020808252825182820181905260009190848201906040850190845b81811015610ec75783518352928401929184019160010161270e565b6020815260006110c1602083018461255d565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b81516001600160a01b031681526020808301516001600160401b03169082015260408083015115159082015260608101610861565b604051601f8201601f191681016001600160401b03811182821017156127cf576127cf6128fb565b604052919050565b600082198211156127ea576127ea6128cf565b500190565b6000826127fe576127fe6128e5565b500490565b600081600019048311821515161561281d5761281d6128cf565b500290565b600082821015612834576128346128cf565b500390565b60005b8381101561285457818101518382015260200161283c565b838111156115d25750506000910152565b600181811c9082168061287957607f821691505b6020821081141561289a57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156128b4576128b46128cf565b5060010190565b6000826128ca576128ca6128e5565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610b1857600080fd5b8015158114610b1857600080fd5b6001600160e01b031981168114610b1857600080fdfea2646970667358221220581275337aaf4c9120848ac215650cc1bc16190c2ff1098bd3e4c49f121b4cff64736f6c63430008040033

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

000000000000000000000000efd450027bd0ee84afafbc75f5a80c367efbf651

-----Decoded View---------------
Arg [0] : _token (address): 0xefd450027bd0ee84afafbc75f5a80c367efbf651

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000efd450027bd0ee84afafbc75f5a80c367efbf651


Deployed ByteCode Sourcemap

63913:3280:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32329:615;;;;;;;;;;-1:-1:-1;32329:615:0;;;;;:::i;:::-;;:::i;:::-;;;12232:14:1;;12225:22;12207:41;;12195:2;12180:18;32329:615:0;;;;;;;;64904:79;;;;;;;;;;;;;:::i;:::-;;37342:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;39410:204::-;;;;;;;;;;-1:-1:-1;39410:204:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;9501:32:1;;;9483:51;;9471:2;9456:18;39410:204:0;9438:102:1;38870:474:0;;;;;;;;;;-1:-1:-1;38870:474:0;;;;;:::i;:::-;;:::i;64179:31::-;;;;;;;;;;;;;;;;;;;16668:25:1;;;16656:2;16641:18;64179:31:0;16623:76:1;31383:315:0;;;;;;;;;;-1:-1:-1;64597:1:0;31649:12;31436:7;31633:13;:28;-1:-1:-1;;31633:46:0;31383:315;;40296:170;;;;;;;;;;-1:-1:-1;40296:170:0;;;;;:::i;:::-;;:::i;64076:33::-;;;;;;;;;;-1:-1:-1;64076:33:0;;;;-1:-1:-1;;;64076:33:0;;;;;;;;;16876:4:1;16864:17;;;16846:36;;16834:2;16819:18;64076:33:0;16801:87:1;64991:137:0;;;;;;:::i;:::-;;:::i;40537:185::-;;;;;;;;;;-1:-1:-1;40537:185:0;;;;;:::i;:::-;;:::i;64035:34::-;;;;;;;;;;-1:-1:-1;64035:34:0;;;;-1:-1:-1;;;64035:34:0;;;;;;;;;16503:6:1;16491:19;;;16473:38;;16461:2;16446:18;64035:34:0;16428:89:1;64614:82:0;;;;;;;;;;-1:-1:-1;64614:82:0;;;;;:::i;:::-;;:::i;64118:20::-;;;;;;;;;;-1:-1:-1;64118:20:0;;;;-1:-1:-1;;;64118:20:0;;;;;;66940:120;;;;;;;;;;-1:-1:-1;66940:120:0;;;;;:::i;:::-;;:::i;66418:100::-;;;;;;;;;;-1:-1:-1;66418:100:0;;;;;:::i;:::-;;:::i;59121:468::-;;;;;;;;;;-1:-1:-1;59121:468:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;37131:144::-;;;;;;;;;;-1:-1:-1;37131:144:0;;;;;:::i;:::-;;:::i;64704:104::-;;;;;;;;;;-1:-1:-1;64704:104:0;;;;;:::i;:::-;;:::i;64275:21::-;;;;;;;;;;;;;:::i;33008:224::-;;;;;;;;;;-1:-1:-1;33008:224:0;;;;;:::i;:::-;;:::i;2529:103::-;;;;;;;;;;;;;:::i;62933:892::-;;;;;;;;;;-1:-1:-1;62933:892:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;64816:80::-;;;;;;;;;;;;;:::i;1878:87::-;;;;;;;;;;-1:-1:-1;1951:6:0;;-1:-1:-1;;;;;1951:6:0;1878:87;;37511:104;;;;;;;;;;;;;:::i;64219:47::-;;;;;;;;;;-1:-1:-1;64219:47:0;;;;;:::i;:::-;;;;;;;;;;;;;;59979:2505;;;;;;;;;;-1:-1:-1;59979:2505:0;;;;;:::i;:::-;;:::i;67068:122::-;;;;;;;;;;-1:-1:-1;67068:122:0;;;;;:::i;:::-;;:::i;64147:23::-;;;;;;;;;;-1:-1:-1;64147:23:0;;;;-1:-1:-1;;;64147:23:0;;;;;;65136:589;;;;;;;;;;-1:-1:-1;65136:589:0;;;;;:::i;:::-;;:::i;39686:308::-;;;;;;;;;;-1:-1:-1;39686:308:0;;;;;:::i;:::-;;:::i;66861:71::-;;;;;;;;;;;;;:::i;64303:27::-;;;;;;;;;;;;;:::i;40793:396::-;;;;;;;;;;-1:-1:-1;40793:396:0;;;;;:::i;:::-;;:::i;58542:420::-;;;;;;;;;;-1:-1:-1;58542:420:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;64337:27::-;;;;;;;;;;;;;:::i;65733:677::-;;;;;;;;;;-1:-1:-1;65733:677:0;;;;;:::i;:::-;;:::i;66750:103::-;;;;;;;;;;-1:-1:-1;66750:103:0;;;;;:::i;:::-;;:::i;66638:104::-;;;;;;;;;;-1:-1:-1;66638:104:0;;;;;:::i;:::-;;:::i;40065:164::-;;;;;;;;;;-1:-1:-1;40065:164:0;;;;;:::i;:::-;;:::i;2787:201::-;;;;;;;;;;-1:-1:-1;2787:201:0;;;;;:::i;:::-;;:::i;64373:19::-;;;;;;;;;;-1:-1:-1;64373:19:0;;;;-1:-1:-1;;;;;64373:19:0;;;66526:104;;;;;;;;;;-1:-1:-1;66526:104:0;;;;;:::i;:::-;;:::i;32329:615::-;32414:4;-1:-1:-1;;;;;;;;;32714:25:0;;;;:102;;-1:-1:-1;;;;;;;;;;32791:25:0;;;32714:102;:179;;;-1:-1:-1;;;;;;;;;;32868:25:0;;;32714:179;32694:199;32329:615;-1:-1:-1;;32329:615:0:o;64904:79::-;1951:6;;-1:-1:-1;;;;;1951:6:0;682:10;2098:23;2090:68;;;;-1:-1:-1;;;2090:68:0;;;;;;;:::i;:::-;;;;;;;;;64956:11:::1;:19:::0;;-1:-1:-1;;;;64956:19:0::1;::::0;;64904:79::o;37342:100::-;37396:13;37429:5;37422:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37342:100;:::o;39410:204::-;39478:7;39503:16;39511:7;39503;:16::i;:::-;39498:64;;39528:34;;-1:-1:-1;;;39528:34:0;;;;;;;;;;;39498:64;-1:-1:-1;39582:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;39582:24:0;;39410:204::o;38870:474::-;38943:13;38975:27;38994:7;38975:18;:27::i;:::-;38943:61;;39025:5;-1:-1:-1;;;;;39019:11:0;:2;-1:-1:-1;;;;;39019:11:0;;39015:48;;;39039:24;;-1:-1:-1;;;39039:24:0;;;;;;;;;;;39015:48;682:10;-1:-1:-1;;;;;39080:28:0;;;39076:175;;39128:44;39145:5;682:10;40065:164;:::i;39128:44::-;39123:128;;39200:35;;-1:-1:-1;;;39200:35:0;;;;;;;;;;;39123:128;39263:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;39263:29:0;-1:-1:-1;;;;;39263:29:0;;;;;;;;;39308:28;;39263:24;;39308:28;;;;;;;38870:474;;;:::o;40296:170::-;40430:28;40440:4;40446:2;40450:7;40430:9;:28::i;:::-;40296:170;;;:::o;64991:137::-;1951:6;;-1:-1:-1;;;;;1951:6:0;682:10;2098:23;2090:68;;;;-1:-1:-1;;;2090:68:0;;;;;;;:::i;:::-;65103:17:::1;65109:2;65113:6;65103:5;:17::i;:::-;64991:137:::0;;:::o;40537:185::-;40675:39;40692:4;40698:2;40702:7;40675:39;;;;;;;;;;;;:16;:39::i;64614:82::-;1951:6;;-1:-1:-1;;;;;1951:6:0;682:10;2098:23;2090:68;;;;-1:-1:-1;;;2090:68:0;;;;;;;:::i;:::-;64676:4:::1;:12:::0;64614:82::o;66940:120::-;1951:6;;-1:-1:-1;;;;;1951:6:0;682:10;2098:23;2090:68;;;;-1:-1:-1;;;2090:68:0;;;;;;;:::i;:::-;67008:44:::1;67026:2;67030:21;67008:17;:44::i;:::-;66940:120:::0;:::o;66418:100::-;1951:6;;-1:-1:-1;;;;;1951:6:0;682:10;2098:23;2090:68;;;;-1:-1:-1;;;2090:68:0;;;;;;;:::i;:::-;66492:18;;::::1;::::0;:7:::1;::::0;:18:::1;::::0;::::1;::::0;::::1;:::i;59121:468::-:0;59296:15;;59210:23;;59271:22;59296:15;-1:-1:-1;;;;;59363:36:0;;;;;-1:-1:-1;;;59363:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;59363:36:0;;-1:-1:-1;;59363:36:0;;;;;;;;;;;;59326:73;;59419:9;59414:125;59435:14;59430:1;:19;59414:125;;59491:32;59511:8;59520:1;59511:11;;;;;;-1:-1:-1;;;59511:11:0;;;;;;;;;;;;;;;59491:19;:32::i;:::-;59475:10;59486:1;59475:13;;;;;;-1:-1:-1;;;59475:13:0;;;;;;;;;;;;;;;;;;:48;59451:3;;59414:125;;;-1:-1:-1;59560:10:0;59121:468;-1:-1:-1;;;59121:468:0:o;37131:144::-;37195:7;37238:27;37257:7;37238:18;:27::i;64704:104::-;1951:6;;-1:-1:-1;;;;;1951:6:0;682:10;2098:23;2090:68;;;;-1:-1:-1;;;2090:68:0;;;;;;;:::i;:::-;64776:15:::1;:24:::0;;::::1;::::0;;::::1;-1:-1:-1::0;;;64776:24:0::1;-1:-1:-1::0;;;;64776:24:0;;::::1;::::0;;;::::1;::::0;;64704:104::o;64275:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;33008:224::-;33072:7;-1:-1:-1;;;;;33096:19:0;;33092:60;;33124:28;;-1:-1:-1;;;33124:28:0;;;;;;;;;;;33092:60;-1:-1:-1;;;;;;33170:25:0;;;;;:18;:25;;;;;;-1:-1:-1;;;;;33170:54:0;;33008:224::o;2529:103::-;1951:6;;-1:-1:-1;;;;;1951:6:0;682:10;2098:23;2090:68;;;;-1:-1:-1;;;2090:68:0;;;;;;;:::i;:::-;2594:30:::1;2621:1;2594:18;:30::i;:::-;2529:103::o:0;62933:892::-;63003:16;63057:19;63091:25;63131:22;63156:16;63166:5;63156:9;:16::i;:::-;63131:41;;63187:25;63229:14;-1:-1:-1;;;;;63215:29:0;;;;;-1:-1:-1;;;63215:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63215:29:0;;63187:57;;63259:31;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;63259:31:0;64597:1;63305:472;63354:14;63339:11;:29;63305:472;;63406:15;63419:1;63406:12;:15::i;:::-;63394:27;;63444:9;:16;;;63440:73;;;63485:8;;63440:73;63535:14;;-1:-1:-1;;;;;63535:28:0;;63531:111;;63608:14;;;-1:-1:-1;63531:111:0;63685:5;-1:-1:-1;;;;;63664:26:0;:17;-1:-1:-1;;;;;63664:26:0;;63660:102;;;63741:1;63715:8;63724:13;;;;;;63715:23;;;;;;-1:-1:-1;;;63715:23:0;;;;;;;;;;;;;;:27;;;;;63660:102;63370:3;;63305:472;;;-1:-1:-1;63798:8:0;;62933:892;-1:-1:-1;;;;;;62933:892:0:o;64816:80::-;1951:6;;-1:-1:-1;;;;;1951:6:0;682:10;2098:23;2090:68;;;;-1:-1:-1;;;2090:68:0;;;;;;;:::i;:::-;64870:11:::1;:18:::0;;-1:-1:-1;;;;64870:18:0::1;-1:-1:-1::0;;;64870:18:0::1;::::0;;64816:80::o;37511:104::-;37567:13;37600:7;37593:14;;;;;:::i;59979:2505::-;60114:16;60181:4;60172:5;:13;60168:45;;60194:19;;-1:-1:-1;;;60194:19:0;;;;;;;;;;;60168:45;60228:19;60262:17;60282:14;31124:7;31151:13;;31077:95;60282:14;60262:34;-1:-1:-1;64597:1:0;60374:5;:23;60370:87;;;64597:1;60418:23;;60370:87;60533:9;60526:4;:16;60522:73;;;60570:9;60563:16;;60522:73;60609:25;60637:16;60647:5;60637:9;:16::i;:::-;60609:44;;60831:4;60823:5;:12;60819:278;;;60878:12;;;60913:31;;;60909:111;;;60989:11;60969:31;;60909:111;60819:278;;;;-1:-1:-1;61080:1:0;60819:278;61111:25;61153:17;-1:-1:-1;;;;;61139:32:0;;;;;-1:-1:-1;;;61139:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;61139:32:0;-1:-1:-1;61111:60:0;-1:-1:-1;61190:22:0;61186:78;;61240:8;-1:-1:-1;61233:15:0;;-1:-1:-1;;;61233:15:0;61186:78;61408:31;61442:26;61462:5;61442:19;:26::i;:::-;61408:60;;61483:25;61728:9;:16;;;61723:92;;-1:-1:-1;61785:14:0;;61723:92;61846:5;61829:478;61858:4;61853:1;:9;;:45;;;;;61881:17;61866:11;:32;;61853:45;61829:478;;;61936:15;61949:1;61936:12;:15::i;:::-;61924:27;;61974:9;:16;;;61970:73;;;62015:8;;61970:73;62065:14;;-1:-1:-1;;;;;62065:28:0;;62061:111;;62138:14;;;-1:-1:-1;62061:111:0;62215:5;-1:-1:-1;;;;;62194:26:0;:17;-1:-1:-1;;;;;62194:26:0;;62190:102;;;62271:1;62245:8;62254:13;;;;;;62245:23;;;;;;-1:-1:-1;;;62245:23:0;;;;;;;;;;;;;;:27;;;;;62190:102;61900:3;;61829:478;;;-1:-1:-1;;;62392:29:0;;;-1:-1:-1;62399:8:0;;-1:-1:-1;;59979:2505:0;;;;;;:::o;67068:122::-;1951:6;;-1:-1:-1;;;;;1951:6:0;682:10;2098:23;2090:68;;;;-1:-1:-1;;;2090:68:0;;;;;;;:::i;:::-;67132:5:::1;::::0;67151:30:::1;::::0;-1:-1:-1;;;67151:30:0;;67175:4:::1;67151:30;::::0;::::1;9483:51:1::0;-1:-1:-1;;;;;67132:5:0;;::::1;::::0;:14:::1;::::0;67147:2;;67132:5;;67151:15:::1;::::0;9456:18:1;;67151:30:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;67132:50;::::0;-1:-1:-1;;;;;;67132:50:0::1;::::0;;;;;;-1:-1:-1;;;;;10610:32:1;;;67132:50:0::1;::::0;::::1;10592:51:1::0;10659:18;;;10652:34;10565:18;;67132:50:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;65136:589::-:0;65245:15;;65221:10;65208:24;;;;:12;:24;;;;;;-1:-1:-1;;;65245:15:0;;;;;;65208:33;;65235:6;;65208:33;:::i;:::-;:52;;65186:118;;;;-1:-1:-1;;;65186:118:0;;13657:2:1;65186:118:0;;;13639:21:1;13696:2;13676:18;;;13669:30;-1:-1:-1;;;13715:18:1;;;13708:46;13771:18;;65186:118:0;13629:166:1;65186:118:0;65349:13;;-1:-1:-1;;;65349:13:0;;;;65339:6;65323:13;64597:1;31649:12;31436:7;31633:13;-1:-1:-1;;31633:28:0;;;:46;;31383:315;65323:13;:22;;;;:::i;:::-;:39;;65315:66;;;;-1:-1:-1;;;65315:66:0;;13314:2:1;65315:66:0;;;13296:21:1;13353:2;13333:18;;;13326:30;-1:-1:-1;;;13372:18:1;;;13365:44;13426:18;;65315:66:0;13286:164:1;65315:66:0;65400:11;;-1:-1:-1;;;65400:11:0;;;;65392:43;;;;-1:-1:-1;;;65392:43:0;;15913:2:1;65392:43:0;;;15895:21:1;15952:2;15932:18;;;15925:30;-1:-1:-1;;;15971:18:1;;;15964:49;16030:18;;65392:43:0;15885:169:1;65392:43:0;65448:17;65475:6;65468:4;;:13;;;;:::i;:::-;65500:5;;:27;;-1:-1:-1;;;65500:27:0;;65516:10;65500:27;;;9483:51:1;65448:33:0;;-1:-1:-1;65448:33:0;;-1:-1:-1;;;;;65500:5:0;;;;:15;;9456:18:1;;65500:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:40;;65492:73;;;;-1:-1:-1;;;65492:73:0;;14787:2:1;65492:73:0;;;14769:21:1;14826:2;14806:18;;;14799:30;-1:-1:-1;;;14845:18:1;;;14838:50;14905:18;;65492:73:0;14759:170:1;65492:73:0;65578:5;;:56;;-1:-1:-1;;;65578:56:0;;65597:10;65578:56;;;9785:34:1;65617:4:0;9835:18:1;;;9828:43;9887:18;;;9880:34;;;-1:-1:-1;;;;;65578:5:0;;;;:18;;9720::1;;65578:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;65647:25;65653:10;65665:6;65647:5;:25::i;:::-;65696:10;65683:24;;;;:12;:24;;;;;:34;;65711:6;;65683:24;:34;;65711:6;;65683:34;:::i;:::-;;;;-1:-1:-1;;;;65136:589:0:o;39686:308::-;-1:-1:-1;;;;;39785:31:0;;682:10;39785:31;39781:61;;;39825:17;;-1:-1:-1;;;39825:17:0;;;;;;;;;;;39781:61;682:10;39855:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;39855:49:0;;;;;;;;;;;;:60;;-1:-1:-1;;39855:60:0;;;;;;;;;;39931:55;;12207:41:1;;;39855:49:0;;682:10;39931:55;;12180:18:1;39931:55:0;;;;;;;39686:308;;:::o;66861:71::-;1951:6;;-1:-1:-1;;;;;1951:6:0;682:10;2098:23;2090:68;;;;-1:-1:-1;;;2090:68:0;;;;;;;:::i;:::-;66909:8:::1;:15:::0;;-1:-1:-1;;;;66909:15:0::1;-1:-1:-1::0;;;66909:15:0::1;::::0;;66861:71::o;64303:27::-;;;;;;;:::i;40793:396::-;40960:28;40970:4;40976:2;40980:7;40960:9;:28::i;:::-;-1:-1:-1;;;;;41003:14:0;;;:19;40999:183;;41042:56;41073:4;41079:2;41083:7;41092:5;41042:30;:56::i;:::-;41037:145;;41126:40;;-1:-1:-1;;;41126:40:0;;;;;;;;;;;41037:145;40793:396;;;;:::o;58542:420::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64597:1:0;58698:25;;;:54;;-1:-1:-1;31124:7:0;31151:13;58727:7;:25;;58698:54;58694:103;;;58776:9;58542:420;-1:-1:-1;;58542:420:0:o;58694:103::-;58819:21;58832:7;58819:12;:21::i;:::-;58807:33;;58855:9;:16;;;58851:65;;;58895:9;58542:420;-1:-1:-1;;58542:420:0:o;58851:65::-;58933:21;58946:7;58933:12;:21::i;64337:27::-;;;;;;;:::i;65733:677::-;65798:13;65874:1;65846:16;65854:7;65846;:16::i;:::-;-1:-1:-1;;;;;65846:30:0;;;65824:127;;;;-1:-1:-1;;;65824:127:0;;15497:2:1;65824:127:0;;;15479:21:1;15536:2;15516:18;;;15509:30;15575:34;15555:18;;;15548:62;-1:-1:-1;;;15626:18:1;;;15619:45;15681:19;;65824:127:0;15469:237:1;65824:127:0;65968:8;;-1:-1:-1;;;65968:8:0;;;;65964:70;;66009:13;66002:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65733:677;;;:::o;65964:70::-;66046:28;66077:7;66046:38;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66146:1;66121:14;66115:28;:32;:287;;;;;;;;;;;;;;;;;66239:14;66280:18;:7;:16;:18::i;:::-;66325:13;66196:165;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;66095:307;65733:677;-1:-1:-1;;;65733:677:0:o;66750:103::-;1951:6;;-1:-1:-1;;;;;1951:6:0;682:10;2098:23;2090:68;;;;-1:-1:-1;;;2090:68:0;;;;;;;:::i;:::-;66822:13:::1;:23:::0;;::::1;::::0;;::::1;-1:-1:-1::0;;;66822:23:0::1;-1:-1:-1::0;;;;66822:23:0;;::::1;::::0;;;::::1;::::0;;66750:103::o;66638:104::-;1951:6;;-1:-1:-1;;;;;1951:6:0;682:10;2098:23;2090:68;;;;-1:-1:-1;;;2090:68:0;;;;;;;:::i;:::-;66714:20;;::::1;::::0;:13:::1;::::0;:20:::1;::::0;::::1;::::0;::::1;:::i;40065:164::-:0;-1:-1:-1;;;;;40186:25:0;;;40162:4;40186:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;40065:164::o;2787:201::-;1951:6;;-1:-1:-1;;;;;1951:6:0;682:10;2098:23;2090:68;;;;-1:-1:-1;;;2090:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;2876:22:0;::::1;2868:73;;;::::0;-1:-1:-1;;;2868:73:0;;12907:2:1;2868:73:0::1;::::0;::::1;12889:21:1::0;12946:2;12926:18;;;12919:30;12985:34;12965:18;;;12958:62;-1:-1:-1;;;13036:18:1;;;13029:36;13082:19;;2868:73:0::1;12879:228:1::0;2868:73:0::1;2952:28;2971:8;2952:18;:28::i;66526:104::-:0;1951:6;;-1:-1:-1;;;;;1951:6:0;682:10;2098:23;2090:68;;;;-1:-1:-1;;;2090:68:0;;;;;;;:::i;:::-;66602:20;;::::1;::::0;:13:::1;::::0;:20:::1;::::0;::::1;::::0;::::1;:::i;41444:273::-:0;41501:4;41557:7;64597:1;41538:26;;:66;;;;;41591:13;;41581:7;:23;41538:66;:152;;;;-1:-1:-1;;41642:26:0;;;;:17;:26;;;;;;-1:-1:-1;;;41642:43:0;:48;;41444:273::o;34646:1129::-;34713:7;34748;;64597:1;34797:23;34793:915;;34850:13;;34843:4;:20;34839:869;;;34888:14;34905:23;;;:17;:23;;;;;;-1:-1:-1;;;34994:23:0;;34990:699;;35513:113;35520:11;35513:113;;-1:-1:-1;;;35591:6:0;35573:25;;;;:17;:25;;;;;;35513:113;;34990:699;34839:869;;35736:31;;-1:-1:-1;;;35736:31:0;;;;;;;;;;;46683:2515;46798:27;46828;46847:7;46828:18;:27::i;:::-;46798:57;;46913:4;-1:-1:-1;;;;;46872:45:0;46888:19;-1:-1:-1;;;;;46872:45:0;;46868:86;;46926:28;;-1:-1:-1;;;46926:28:0;;;;;;;;;;;46868:86;46967:22;682:10;-1:-1:-1;;;;;46993:27:0;;;;:87;;-1:-1:-1;47037:43:0;47054:4;682:10;40065:164;:::i;47037:43::-;46993:147;;;-1:-1:-1;682:10:0;47097:20;47109:7;47097:11;:20::i;:::-;-1:-1:-1;;;;;47097:43:0;;46993:147;46967:174;;47159:17;47154:66;;47185:35;;-1:-1:-1;;;47185:35:0;;;;;;;;;;;47154:66;-1:-1:-1;;;;;47235:16:0;;47231:52;;47260:23;;-1:-1:-1;;;47260:23:0;;;;;;;;;;;47231:52;47412:24;;;;:15;:24;;;;;;;;47405:31;;-1:-1:-1;;;;;;47405:31:0;;;-1:-1:-1;;;;;47804:24:0;;;;;:18;:24;;;;;47802:26;;-1:-1:-1;;47802:26:0;;;47873:22;;;;;;;47871:24;;-1:-1:-1;47871:24:0;;;48166:26;;;:17;:26;;;;;-1:-1:-1;;;48254:15:0;29001:3;48254:41;48212:84;;:128;;48166:174;;;48460:46;;48456:626;;48564:1;48554:11;;48532:19;48687:30;;;:17;:30;;;;;;48683:384;;48825:13;;48810:11;:28;48806:242;;48972:30;;;;:17;:30;;;;;:52;;;48806:242;48456:626;;49129:7;49125:2;-1:-1:-1;;;;;49110:27:0;49119:4;-1:-1:-1;;;;;49110:27:0;;;;;;;;;;;46683:2515;;;;;:::o;44773:1656::-;44838:20;44861:13;-1:-1:-1;;;;;44889:16:0;;44885:48;;44914:19;;-1:-1:-1;;;44914:19:0;;;;;;;;;;;44885:48;44948:13;44944:44;;44970:18;;-1:-1:-1;;;44970:18:0;;;;;;;;;;;44944:44;-1:-1:-1;;;;;45537:22:0;;;;;;:18;:22;;;;28484:2;45537:22;;;:70;;45575:31;45563:44;;45537:70;;;45850:31;;;:17;:31;;;;;45943:15;29001:3;45943:41;45901:84;;-1:-1:-1;46021:13:0;;29264:3;46006:56;45901:162;45850:213;;:31;46144:23;;;46184:111;46211:40;;46236:14;;;;;-1:-1:-1;;;;;46211:40:0;;;46228:1;;46211:40;;46228:1;;46211:40;46290:3;46275:12;:18;46184:111;;-1:-1:-1;46311:13:0;:28;40296:170;;;:::o;5840:317::-;5955:6;5930:21;:31;;5922:73;;;;-1:-1:-1;;;5922:73:0;;14429:2:1;5922:73:0;;;14411:21:1;14468:2;14448:18;;;14441:30;14507:31;14487:18;;;14480:59;14556:18;;5922:73:0;14401:179:1;5922:73:0;6009:12;6027:9;-1:-1:-1;;;;;6027:14:0;6049:6;6027:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6008:52;;;6079:7;6071:78;;;;-1:-1:-1;;;6071:78:0;;14002:2:1;6071:78:0;;;13984:21:1;14041:2;14021:18;;;14014:30;14080:34;14060:18;;;14053:62;14151:28;14131:18;;;14124:56;14197:19;;6071:78:0;13974:248:1;3148:191:0;3241:6;;;-1:-1:-1;;;;;3258:17:0;;;-1:-1:-1;;;;;;3258:17:0;;;;;;;3291:40;;3241:6;;;3258:17;3241:6;;3291:40;;3222:16;;3291:40;3148:191;;:::o;36255:153::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;36375:24:0;;;;:17;:24;;;;;;36356:44;;:18;:44::i;52895:716::-;53079:88;;-1:-1:-1;;;53079:88:0;;53058:4;;-1:-1:-1;;;;;53079:45:0;;;;;:88;;682:10;;53146:4;;53152:7;;53161:5;;53079:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53079:88:0;;;;;;;;-1:-1:-1;;53079:88:0;;;;;;;;;;;;:::i;:::-;;;53075:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53362:13:0;;53358:235;;53408:40;;-1:-1:-1;;;53408:40:0;;;;;;;;;;;53358:235;53551:6;53545:13;53536:6;53532:2;53528:15;53521:38;53075:529;-1:-1:-1;;;;;;53238:64:0;-1:-1:-1;;;53238:64:0;;-1:-1:-1;53075:529:0;52895:716;;;;;;:::o;36911:158::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;37014:47:0;37033:27;37052:7;37033:18;:27::i;:::-;37014:18;:47::i;12214:723::-;12270:13;12491:10;12487:53;;-1:-1:-1;;12518:10:0;;;;;;;;;;;;-1:-1:-1;;;12518:10:0;;;;;12214:723::o;12487:53::-;12565:5;12550:12;12606:78;12613:9;;12606:78;;12639:8;;;;:::i;:::-;;-1:-1:-1;12662:10:0;;-1:-1:-1;12670:2:0;12662:10;;:::i;:::-;;;12606:78;;;12694:19;12726:6;-1:-1:-1;;;;;12716:17:0;;;;;-1:-1:-1;;;12716:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12716:17:0;;12694:39;;12744:154;12751:10;;12744:154;;12778:11;12788:1;12778:11;;:::i;:::-;;-1:-1:-1;12847:10:0;12855:2;12847:5;:10;:::i;:::-;12834:24;;:2;:24;:::i;:::-;12821:39;;12804:6;12811;12804:14;;;;;;-1:-1:-1;;;12804:14:0;;;;;;;;;;;;:56;-1:-1:-1;;;;;12804:56:0;;;;;;;;-1:-1:-1;12875:11:0;12884:2;12875:11;;:::i;:::-;;;12744:154;;35869:295;-1:-1:-1;;;;;;;;;;;;;35979:41:0;;;;29001:3;36065:32;;;-1:-1:-1;;;;;36031:67:0;-1:-1:-1;;;36031:67:0;-1:-1:-1;;;36128:23:0;;;:28;;-1:-1:-1;;;36109:47:0;-1:-1:-1;35869:295:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:406:1;78:5;-1:-1:-1;;;;;104:6:1;101:30;98:2;;;134:18;;:::i;:::-;172:57;217:2;196:15;;-1:-1:-1;;192:29:1;223:4;188:40;172:57;:::i;:::-;163:66;;252:6;245:5;238:21;292:3;283:6;278:3;274:16;271:25;268:2;;;309:1;306;299:12;268:2;358:6;353:3;346:4;339:5;335:16;322:43;412:1;405:4;396:6;389:5;385:18;381:29;374:40;88:332;;;;;:::o;425:257::-;484:6;537:2;525:9;516:7;512:23;508:32;505:2;;;558:6;550;543:22;505:2;602:9;589:23;621:31;646:5;621:31;:::i;957:398::-;1025:6;1033;1086:2;1074:9;1065:7;1061:23;1057:32;1054:2;;;1107:6;1099;1092:22;1054:2;1151:9;1138:23;1170:31;1195:5;1170:31;:::i;:::-;1220:5;-1:-1:-1;1277:2:1;1262:18;;1249:32;1290:33;1249:32;1290:33;:::i;:::-;1342:7;1332:17;;;1044:311;;;;;:::o;1360:466::-;1437:6;1445;1453;1506:2;1494:9;1485:7;1481:23;1477:32;1474:2;;;1527:6;1519;1512:22;1474:2;1571:9;1558:23;1590:31;1615:5;1590:31;:::i;:::-;1640:5;-1:-1:-1;1697:2:1;1682:18;;1669:32;1710:33;1669:32;1710:33;:::i;:::-;1464:362;;1762:7;;-1:-1:-1;;;1816:2:1;1801:18;;;;1788:32;;1464:362::o;1831:824::-;1926:6;1934;1942;1950;2003:3;1991:9;1982:7;1978:23;1974:33;1971:2;;;2025:6;2017;2010:22;1971:2;2069:9;2056:23;2088:31;2113:5;2088:31;:::i;:::-;2138:5;-1:-1:-1;2195:2:1;2180:18;;2167:32;2208:33;2167:32;2208:33;:::i;:::-;2260:7;-1:-1:-1;2314:2:1;2299:18;;2286:32;;-1:-1:-1;2369:2:1;2354:18;;2341:32;-1:-1:-1;;;;;2385:30:1;;2382:2;;;2433:6;2425;2418:22;2382:2;2461:22;;2514:4;2506:13;;2502:27;-1:-1:-1;2492:2:1;;2548:6;2540;2533:22;2492:2;2576:73;2641:7;2636:2;2623:16;2618:2;2614;2610:11;2576:73;:::i;:::-;2566:83;;;1961:694;;;;;;;:::o;2660:392::-;2725:6;2733;2786:2;2774:9;2765:7;2761:23;2757:32;2754:2;;;2807:6;2799;2792:22;2754:2;2851:9;2838:23;2870:31;2895:5;2870:31;:::i;:::-;2920:5;-1:-1:-1;2977:2:1;2962:18;;2949:32;2990:30;2949:32;2990:30;:::i;3057:325::-;3125:6;3133;3186:2;3174:9;3165:7;3161:23;3157:32;3154:2;;;3207:6;3199;3192:22;3154:2;3251:9;3238:23;3270:31;3295:5;3270:31;:::i;:::-;3320:5;3372:2;3357:18;;;;3344:32;;-1:-1:-1;;;3144:238:1:o;3387:393::-;3464:6;3472;3480;3533:2;3521:9;3512:7;3508:23;3504:32;3501:2;;;3554:6;3546;3539:22;3501:2;3598:9;3585:23;3617:31;3642:5;3617:31;:::i;:::-;3667:5;3719:2;3704:18;;3691:32;;-1:-1:-1;3770:2:1;3755:18;;;3742:32;;3491:289;-1:-1:-1;;;3491:289:1:o;3785:1002::-;3869:6;3900:2;3943;3931:9;3922:7;3918:23;3914:32;3911:2;;;3964:6;3956;3949:22;3911:2;4009:9;3996:23;-1:-1:-1;;;;;4079:2:1;4071:6;4068:14;4065:2;;;4100:6;4092;4085:22;4065:2;4143:6;4132:9;4128:22;4118:32;;4188:7;4181:4;4177:2;4173:13;4169:27;4159:2;;4215:6;4207;4200:22;4159:2;4256;4243:16;4278:2;4274;4271:10;4268:2;;;4284:18;;:::i;:::-;4330:2;4327:1;4323:10;4313:20;;4353:28;4377:2;4373;4369:11;4353:28;:::i;:::-;4415:15;;;4446:12;;;;4478:11;;;4508;;;4504:20;;4501:33;-1:-1:-1;4498:2:1;;;4552:6;4544;4537:22;4498:2;4579:6;4570:15;;4594:163;4608:2;4605:1;4602:9;4594:163;;;4665:17;;4653:30;;4626:1;4619:9;;;;;4703:12;;;;4735;;4594:163;;;-1:-1:-1;4776:5:1;3880:907;-1:-1:-1;;;;;;;;3880:907:1:o;4792:255::-;4859:6;4912:2;4900:9;4891:7;4887:23;4883:32;4880:2;;;4933:6;4925;4918:22;4880:2;4970:9;4964:16;4989:28;5011:5;4989:28;:::i;5052:255::-;5110:6;5163:2;5151:9;5142:7;5138:23;5134:32;5131:2;;;5184:6;5176;5169:22;5131:2;5228:9;5215:23;5247:30;5271:5;5247:30;:::i;5312:259::-;5381:6;5434:2;5422:9;5413:7;5409:23;5405:32;5402:2;;;5455:6;5447;5440:22;5402:2;5492:9;5486:16;5511:30;5535:5;5511:30;:::i;5576:480::-;5645:6;5698:2;5686:9;5677:7;5673:23;5669:32;5666:2;;;5719:6;5711;5704:22;5666:2;5764:9;5751:23;-1:-1:-1;;;;;5789:6:1;5786:30;5783:2;;;5834:6;5826;5819:22;5783:2;5862:22;;5915:4;5907:13;;5903:27;-1:-1:-1;5893:2:1;;5949:6;5941;5934:22;5893:2;5977:73;6042:7;6037:2;6024:16;6019:2;6015;6011:11;5977:73;:::i;6061:292::-;6119:6;6172:2;6160:9;6151:7;6147:23;6143:32;6140:2;;;6193:6;6185;6178:22;6140:2;6237:9;6224:23;6287:6;6280:5;6276:18;6269:5;6266:29;6256:2;;6314:6;6306;6299:22;6358:190;6417:6;6470:2;6458:9;6449:7;6445:23;6441:32;6438:2;;;6491:6;6483;6476:22;6438:2;-1:-1:-1;6519:23:1;;6428:120;-1:-1:-1;6428:120:1:o;6553:194::-;6623:6;6676:2;6664:9;6655:7;6651:23;6647:32;6644:2;;;6697:6;6689;6682:22;6644:2;-1:-1:-1;6725:16:1;;6634:113;-1:-1:-1;6634:113:1:o;6752:289::-;6809:6;6862:2;6850:9;6841:7;6837:23;6833:32;6830:2;;;6883:6;6875;6868:22;6830:2;6927:9;6914:23;6977:4;6970:5;6966:16;6959:5;6956:27;6946:2;;7002:6;6994;6987:22;7046:257;7087:3;7125:5;7119:12;7152:6;7147:3;7140:19;7168:63;7224:6;7217:4;7212:3;7208:14;7201:4;7194:5;7190:16;7168:63;:::i;:::-;7285:2;7264:15;-1:-1:-1;;7260:29:1;7251:39;;;;7292:4;7247:50;;7095:208;-1:-1:-1;;7095:208:1:o;7591:1531::-;7815:3;7853:6;7847:13;7879:4;7892:51;7936:6;7931:3;7926:2;7918:6;7914:15;7892:51;:::i;:::-;8006:13;;7965:16;;;;8028:55;8006:13;7965:16;8050:15;;;8028:55;:::i;:::-;8174:13;;8105:20;;;8145:3;;8234:1;8256:18;;;;8309;;;;8336:2;;8414:4;8404:8;8400:19;8388:31;;8336:2;8477;8467:8;8464:16;8444:18;8441:40;8438:2;;;-1:-1:-1;;;8504:33:1;;8560:4;8557:1;8550:15;8590:4;8511:3;8578:17;8438:2;8621:18;8648:110;;;;8772:1;8767:330;;;;8614:483;;8648:110;-1:-1:-1;;8683:24:1;;8669:39;;8728:20;;;;-1:-1:-1;8648:110:1;;8767:330;17220:4;17239:17;;;17289:4;17273:21;;8862:3;8878:169;8892:8;8889:1;8886:15;8878:169;;;8974:14;;8959:13;;;8952:37;9017:16;;;;8909:10;;8878:169;;;8882:3;;9078:8;9071:5;9067:20;9060:27;;8614:483;-1:-1:-1;9113:3:1;;7823:1299;-1:-1:-1;;;;;;;;;;;7823:1299:1:o;9925:488::-;-1:-1:-1;;;;;10194:15:1;;;10176:34;;10246:15;;10241:2;10226:18;;10219:43;10293:2;10278:18;;10271:34;;;10341:3;10336:2;10321:18;;10314:31;;;10119:4;;10362:45;;10387:19;;10379:6;10362:45;:::i;:::-;10354:53;10128:285;-1:-1:-1;;;;;;10128:285:1:o;10697:725::-;10930:2;10982:21;;;11052:13;;10955:18;;;11074:22;;;10901:4;;10930:2;11153:15;;;;11127:2;11112:18;;;10901:4;11199:197;11213:6;11210:1;11207:13;11199:197;;;11262:52;11310:3;11301:6;11295:13;7392:12;;-1:-1:-1;;;;;7388:38:1;7376:51;;7480:4;7469:16;;;7463:23;-1:-1:-1;;;;;7459:48:1;7443:14;;;7436:72;7571:4;7560:16;;;7554:23;7547:31;7540:39;7524:14;;7517:63;7366:220;11262:52;11371:15;;;;11343:4;11334:14;;;;;11235:1;11228:9;11199:197;;11427:635;11598:2;11650:21;;;11720:13;;11623:18;;;11742:22;;;11569:4;;11598:2;11821:15;;;;11795:2;11780:18;;;11569:4;11867:169;11881:6;11878:1;11875:13;11867:169;;;11942:13;;11930:26;;12011:15;;;;11976:12;;;;11903:1;11896:9;11867:169;;12481:219;12630:2;12619:9;12612:21;12593:4;12650:44;12690:2;12679:9;12675:18;12667:6;12650:44;:::i;14934:356::-;15136:2;15118:21;;;15155:18;;;15148:30;15214:34;15209:2;15194:18;;15187:62;15281:2;15266:18;;15108:182::o;16059:265::-;7392:12;;-1:-1:-1;;;;;7388:38:1;7376:51;;7480:4;7469:16;;;7463:23;-1:-1:-1;;;;;7459:48:1;7443:14;;;7436:72;7571:4;7560:16;;;7554:23;7547:31;7540:39;7524:14;;;7517:63;16255:2;16240:18;;16267:51;7366:220;16893:275;16964:2;16958:9;17029:2;17010:13;;-1:-1:-1;;17006:27:1;16994:40;;-1:-1:-1;;;;;17049:34:1;;17085:22;;;17046:62;17043:2;;;17111:18;;:::i;:::-;17147:2;17140:22;16938:230;;-1:-1:-1;16938:230:1:o;17305:128::-;17345:3;17376:1;17372:6;17369:1;17366:13;17363:2;;;17382:18;;:::i;:::-;-1:-1:-1;17418:9:1;;17353:80::o;17438:120::-;17478:1;17504;17494:2;;17509:18;;:::i;:::-;-1:-1:-1;17543:9:1;;17484:74::o;17563:168::-;17603:7;17669:1;17665;17661:6;17657:14;17654:1;17651:21;17646:1;17639:9;17632:17;17628:45;17625:2;;;17676:18;;:::i;:::-;-1:-1:-1;17716:9:1;;17615:116::o;17736:125::-;17776:4;17804:1;17801;17798:8;17795:2;;;17809:18;;:::i;:::-;-1:-1:-1;17846:9:1;;17785:76::o;17866:258::-;17938:1;17948:113;17962:6;17959:1;17956:13;17948:113;;;18038:11;;;18032:18;18019:11;;;18012:39;17984:2;17977:10;17948:113;;;18079:6;18076:1;18073:13;18070:2;;;-1:-1:-1;;18114:1:1;18096:16;;18089:27;17919:205::o;18129:380::-;18208:1;18204:12;;;;18251;;;18272:2;;18326:4;18318:6;18314:17;18304:27;;18272:2;18379;18371:6;18368:14;18348:18;18345:38;18342:2;;;18425:10;18420:3;18416:20;18413:1;18406:31;18460:4;18457:1;18450:15;18488:4;18485:1;18478:15;18342:2;;18184:325;;;:::o;18514:135::-;18553:3;-1:-1:-1;;18574:17:1;;18571:2;;;18594:18;;:::i;:::-;-1:-1:-1;18641:1:1;18630:13;;18561:88::o;18654:112::-;18686:1;18712;18702:2;;18717:18;;:::i;:::-;-1:-1:-1;18751:9:1;;18692:74::o;18771:127::-;18832:10;18827:3;18823:20;18820:1;18813:31;18863:4;18860:1;18853:15;18887:4;18884:1;18877:15;18903:127;18964:10;18959:3;18955:20;18952:1;18945:31;18995:4;18992:1;18985:15;19019:4;19016:1;19009:15;19035:127;19096:10;19091:3;19087:20;19084:1;19077:31;19127:4;19124:1;19117:15;19151:4;19148:1;19141:15;19167:131;-1:-1:-1;;;;;19242:31:1;;19232:42;;19222:2;;19288:1;19285;19278:12;19303:118;19389:5;19382:13;19375:21;19368:5;19365:32;19355:2;;19411:1;19408;19401:12;19426:131;-1:-1:-1;;;;;;19500:32:1;;19490:43;;19480:2;;19547:1;19544;19537:12

Swarm Source

ipfs://581275337aaf4c9120848ac215650cc1bc16190c2ff1098bd3e4c49f121b4cff
Loading