ETH Price: $1,974.88 (+0.64%)
 

Overview

Max Total Supply

379 FlywheelSTR

Holders

254

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
2 FlywheelSTR
0x66eac659b3aa86834a5cf740131e7e32e766bb2c
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
NFT

Compiler Version
v0.8.30+commit.73712a01

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, None license
/**
 *Submitted for verification at Etherscan.io on 2025-10-04
*/

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

library Str {
    function toString(uint256 value) internal pure returns (string memory) {
        if (value == 0) return "0";
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) { digits++; temp /= 10; }
        bytes memory buf = new bytes(digits);
        while (value != 0) {
            digits--;
            buf[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buf);
    }

    function toString(int256 value) internal pure returns (string memory) {
        return value >= 0 ? toString(uint256(value))
                          : string.concat("-", toString(uint256(-value)));
    }

    function toString(bool b) internal pure returns (string memory) {
        return b ? "true" : "false";
    }
}

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * The `tokenIds` must be strictly ascending.
     */
    error TokenIdsNotStrictlyAscending();

    /**
     * `_sequentialUpTo()` must be greater than `_startTokenId()`.
     */
    error SequentialUpToTooSmall();

    /**
     * The `tokenId` of a sequential mint exceeds `_sequentialUpTo()`.
     */
    error SequentialMintExceedsLimit();

    /**
     * Spot minting requires a `tokenId` greater than `_sequentialUpTo()`.
     */
    error SpotMintTokenIdTooSmall();

    /**
     * Cannot mint over a token that already exists.
     */
    error TokenAlreadyExists();

    /**
     * The feature is not compatible with spot mints.
     */
    error NotCompatibleWithSpotMints();

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

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

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

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see {_totalMinted}.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

    // Mask of an entry in packed address data.
    uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;

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

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

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

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

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

    // The bit mask of the `burned` bit in packed ownership.
    uint256 private constant _BITMASK_BURNED = 1 << 224;

    // The bit position of the `nextInitialized` bit in packed ownership.
    uint256 private constant _BITPOS_NEXT_INITIALIZED = 225;

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

    // The bit position of `extraData` in packed ownership.
    uint256 private constant _BITPOS_EXTRA_DATA = 232;

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

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

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

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

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

    // The next token ID to be minted.
    uint256 private _currentIndex;

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

    // The amount of tokens minted above `_sequentialUpTo()`.
    // We call these spot mints (i.e. non-sequential mints).
    uint256 private _spotMinted;

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

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

        if (_sequentialUpTo() < _startTokenId()) _revert(SequentialUpToTooSmall.selector);
    }

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

    /**
     * @dev Returns the starting token ID for sequential mints.
     *
     * Override this function to change the starting token ID for sequential mints.
     *
     * Note: The value returned must never change after any tokens have been minted.
     */
    function _startTokenId() internal view virtual returns (uint256) {
        return 0;
    }

    /**
     * @dev Returns the maximum token ID (inclusive) for sequential mints.
     *
     * Override this function to return a value less than 2**256 - 1,
     * but greater than `_startTokenId()`, to enable spot (non-sequential) mints.
     *
     * Note: The value returned must never change after any tokens have been minted.
     */
    function _sequentialUpTo() internal view virtual returns (uint256) {
        return type(uint256).max;
    }

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

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see {_totalMinted}.
     */
    function totalSupply() public view virtual override returns (uint256 result) {
        // Counter underflow is impossible as `_burnCounter` cannot be incremented
        // more than `_currentIndex + _spotMinted - _startTokenId()` times.
        unchecked {
            // With spot minting, the intermediate `result` can be temporarily negative,
            // and the computation must be unchecked.
            result = _currentIndex - _burnCounter - _startTokenId();
            if (_sequentialUpTo() != type(uint256).max) result += _spotMinted;
        }
    }

    /**
     * @dev Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() internal view virtual returns (uint256 result) {
        // Counter underflow is impossible as `_currentIndex` does not decrement,
        // and it is initialized to `_startTokenId()`.
        unchecked {
            result = _currentIndex - _startTokenId();
            if (_sequentialUpTo() != type(uint256).max) result += _spotMinted;
        }
    }

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

    /**
     * @dev Returns the total number of tokens that are spot-minted.
     */
    function _totalSpotMinted() internal view virtual returns (uint256) {
        return _spotMinted;
    }

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

    /**
     * @dev Returns the number of tokens in `owner`'s account.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        if (owner == address(0)) _revert(BalanceQueryForZeroAddress.selector);
        return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY;
    }

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

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

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

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

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

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30000 gas.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        // The interface IDs are constants representing the first 4 bytes
        // of the XOR of all function selectors in the interface.
        // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165)
        // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`)
        return
            interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
            interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
            interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
    }

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

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

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

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        if (!_exists(tokenId)) _revert(URIQueryForNonexistentToken.selector);

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

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

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

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

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

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

    /**
     * @dev Returns whether the ownership slot at `index` is initialized.
     * An uninitialized slot does not necessarily mean that the slot has no owner.
     */
    function _ownershipIsInitialized(uint256 index) internal view virtual returns (bool) {
        return _packedOwnerships[index] != 0;
    }

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

    /**
     * @dev Returns the packed ownership data of `tokenId`.
     */
    function _packedOwnershipOf(uint256 tokenId) private view returns (uint256 packed) {
        if (_startTokenId() <= tokenId) {
            packed = _packedOwnerships[tokenId];

            if (tokenId > _sequentialUpTo()) {
                if (_packedOwnershipExists(packed)) return packed;
                _revert(OwnerQueryForNonexistentToken.selector);
            }

            // If the data at the starting slot does not exist, start the scan.
            if (packed == uint256(0)) {
                if (tokenId >= _currentIndex) _revert(OwnerQueryForNonexistentToken.selector);
                // Invariant:
                // There will always be an initialized ownership slot
                // (i.e. `ownership.addr != address(0) && ownership.burned == false`)
                // before an unintialized ownership slot
                // (i.e. `ownership.addr == address(0) && ownership.burned == false`)
                // Hence, `tokenId` will not underflow.
                //
                // We can directly compare the packed value.
                // If the address is zero, packed will be zero.
                for (;;) {
                    unchecked {
                        packed = _packedOwnerships[--tokenId];
                    }
                    if (packed == uint256(0)) continue;
                    if (packed & _BITMASK_BURNED == uint256(0)) return packed;
                    // Otherwise, the token is burned, and we must revert.
                    // This handles the case of batch burned tokens, where only the burned bit
                    // of the starting slot is set, and remaining slots are left uninitialized.
                    _revert(OwnerQueryForNonexistentToken.selector);
                }
            }
            // Otherwise, the data exists and we can skip the scan.
            // This is possible because we have already achieved the target condition.
            // This saves 2143 gas on transfers of initialized tokens.
            // If the token is not burned, return `packed`. Otherwise, revert.
            if (packed & _BITMASK_BURNED == uint256(0)) return packed;
        }
        _revert(OwnerQueryForNonexistentToken.selector);
    }

    /**
     * @dev Returns the unpacked `TokenOwnership` struct from `packed`.
     */
    function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) {
        ownership.addr = address(uint160(packed));
        ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP);
        ownership.burned = packed & _BITMASK_BURNED != 0;
        ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA);
    }

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

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

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

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account. See {ERC721A-_approve}.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     */
    function approve(address to, uint256 tokenId) public payable virtual override {
        _approve(to, tokenId, true);
    }

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

        return _tokenApprovals[tokenId].value;
    }

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom}
     * for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
    }

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

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted. See {_mint}.
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool result) {
        if (_startTokenId() <= tokenId) {
            if (tokenId > _sequentialUpTo()) return _packedOwnershipExists(_packedOwnerships[tokenId]);

            if (tokenId < _currentIndex) {
                uint256 packed;
                while ((packed = _packedOwnerships[tokenId]) == uint256(0)) --tokenId;
                result = packed & _BITMASK_BURNED == uint256(0);
            }
        }
    }

    /**
     * @dev Returns whether `packed` represents a token that exists.
     */
    function _packedOwnershipExists(uint256 packed) private pure returns (bool result) {
        assembly {
            // The following is equivalent to `owner != address(0) && burned == false`.
            // Symbolically tested.
            result := gt(and(packed, _BITMASK_ADDRESS), and(packed, _BITMASK_BURNED))
        }
    }

    /**
     * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`.
     */
    function _isSenderApprovedOrOwner(
        uint256 approvedAddressValue,
        uint256 ownerMasked,
        uint256 msgSenderMasked
    ) private pure returns (bool result) {
        assembly {
            result := or(eq(msgSenderMasked, ownerMasked), eq(msgSenderMasked, approvedAddressValue))
        }
    }

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

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

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token
     * by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable virtual override {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);
        uint256 fromMasked = uint160(from);

        if (uint160(prevOwnershipPacked) != fromMasked) _revert(TransferFromIncorrectOwner.selector);

        (uint256 approvedAddressSlot, uint256 approvedAddressValue) = _getApprovedSlotAndValue(tokenId);

        // The nested ifs save around 20+ gas over a compound boolean condition.
        if (!_isSenderApprovedOrOwner(approvedAddressValue, fromMasked, uint160(_msgSenderERC721A())))
            if (!isApprovedForAll(from, _msgSenderERC721A())) _revert(TransferCallerNotOwnerNorApproved.selector);

        _beforeTokenTransfers(from, to, tokenId, 1);

        assembly {
            if approvedAddressValue {
                sstore(approvedAddressSlot, 0) // Equivalent to `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] = _packOwnershipData(
                to,
                _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked)
            );

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == uint256(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] == uint256(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;
                    }
                }
            }
        }

        // Mask to the lower 160 bits, in case the upper bits somehow aren't clean.
        uint256 toMasked = uint160(to);
        assembly {
            // Emit the `Transfer` event.
            log4(
                0, // Start of data (0, since no data).
                0, // End of data (0, since no data).
                _TRANSFER_EVENT_SIGNATURE, // Signature.
                fromMasked, // `from`.
                toMasked, // `to`.
                tokenId // `tokenId`.
            )
        }
        if (toMasked == uint256(0)) _revert(TransferToZeroAddress.selector);

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

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable virtual override {
        safeTransferFrom(from, to, tokenId, '');
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token
     * by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement
     * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public payable virtual override {
        transferFrom(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                _revert(TransferToNonERC721ReceiverImplementer.selector);
            }
    }

    /**
     * @dev Equivalent to `_batchTransferFrom(from, to, tokenIds)`.
     */
    function _batchTransferFrom(
        address from,
        address to,
        uint256[] memory tokenIds
    ) internal virtual {
        _batchTransferFrom(address(0), from, to, tokenIds);
    }

    /**
     * @dev Transfers `tokenIds` in batch from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenIds` tokens must be owned by `from`.
     * - `tokenIds` must be strictly ascending.
     * - If `by` is not `from`, it must be approved to move these tokens
     * by either {approve} or {setApprovalForAll}.
     *
     * `by` is the address that to check token approval for.
     * If token approval check is not needed, pass in `address(0)` for `by`.
     *
     * Emits a {Transfer} event for each transfer.
     */
    function _batchTransferFrom(
        address by,
        address from,
        address to,
        uint256[] memory tokenIds
    ) internal virtual {
        uint256 byMasked = uint160(by);
        uint256 fromMasked = uint160(from);
        uint256 toMasked = uint160(to);
        // Disallow transfer to zero address.
        if (toMasked == uint256(0)) _revert(TransferToZeroAddress.selector);
        // Whether `by` may transfer the tokens.
        bool mayTransfer = _orERC721A(byMasked == uint256(0), byMasked == fromMasked) || isApprovedForAll(from, by);

        // Early return if `tokenIds` is empty.
        if (tokenIds.length == uint256(0)) return;
        // The next `tokenId` to be minted (i.e. `_nextTokenId()`).
        uint256 end = _currentIndex;
        // Pointer to start and end (exclusive) of `tokenIds`.
        (uint256 ptr, uint256 ptrEnd) = _mdataERC721A(tokenIds);

        uint256 prevTokenId;
        uint256 prevOwnershipPacked;
        unchecked {
            do {
                uint256 tokenId = _mloadERC721A(ptr);
                uint256 miniBatchStart = tokenId;
                // Revert `tokenId` is out of bounds.
                if (_orERC721A(tokenId < _startTokenId(), end <= tokenId))
                    _revert(OwnerQueryForNonexistentToken.selector);
                // Revert if `tokenIds` is not strictly ascending.
                if (prevOwnershipPacked != 0)
                    if (tokenId <= prevTokenId) _revert(TokenIdsNotStrictlyAscending.selector);
                // Scan backwards for an initialized packed ownership slot.
                // ERC721A's invariant guarantees that there will always be an initialized slot as long as
                // the start of the backwards scan falls within `[_startTokenId() .. _nextTokenId())`.
                for (uint256 j = tokenId; (prevOwnershipPacked = _packedOwnerships[j]) == uint256(0); ) --j;
                // If the initialized slot is burned, revert.
                if (prevOwnershipPacked & _BITMASK_BURNED != 0) _revert(OwnerQueryForNonexistentToken.selector);
                // Check that `tokenId` is owned by `from`.
                if (uint160(prevOwnershipPacked) != fromMasked) _revert(TransferFromIncorrectOwner.selector);

                do {
                    (uint256 approvedAddressSlot, uint256 approvedAddressValue) = _getApprovedSlotAndValue(tokenId);
                    _beforeTokenTransfers(address(uint160(fromMasked)), address(uint160(toMasked)), tokenId, 1);
                    // Revert if the sender is not authorized to transfer the token.
                    if (!mayTransfer)
                        if (byMasked != approvedAddressValue) _revert(TransferCallerNotOwnerNorApproved.selector);
                    assembly {
                        if approvedAddressValue {
                            sstore(approvedAddressSlot, 0) // Equivalent to `delete _tokenApprovals[tokenId]`.
                        }
                        // Emit the `Transfer` event.
                        log4(0, 0, _TRANSFER_EVENT_SIGNATURE, fromMasked, toMasked, tokenId)
                    }

                    if (_mloadERC721A(ptr += 0x20) != ++tokenId) break;
                    if (ptr == ptrEnd) break;
                } while (_packedOwnerships[tokenId] == uint256(0));

                // Updates tokenId:
                // - `address` to the next owner.
                // - `startTimestamp` to the timestamp of transferring.
                // - `burned` to `false`.
                // - `nextInitialized` to `false`, as it is optional.
                _packedOwnerships[miniBatchStart] = _packOwnershipData(
                    address(uint160(toMasked)),
                    _nextExtraData(address(uint160(fromMasked)), address(uint160(toMasked)), prevOwnershipPacked)
                );
                uint256 miniBatchLength = tokenId - miniBatchStart;
                // Update the address data.
                _packedAddressData[address(uint160(fromMasked))] -= miniBatchLength;
                _packedAddressData[address(uint160(toMasked))] += miniBatchLength;
                // Initialize the next slot if needed.
                if (tokenId != end)
                    if (_packedOwnerships[tokenId] == uint256(0)) _packedOwnerships[tokenId] = prevOwnershipPacked;
                // Perform the after hook for the batch.
                _afterTokenTransfers(
                    address(uint160(fromMasked)),
                    address(uint160(toMasked)),
                    miniBatchStart,
                    miniBatchLength
                );
                // Set the `prevTokenId` for checking that the `tokenIds` is strictly ascending.
                prevTokenId = tokenId - 1;
            } while (ptr != ptrEnd);
        }
    }

    /**
     * @dev Safely transfers `tokenIds` in batch from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenIds` tokens must be owned by `from`.
     * - If `by` is not `from`, it must be approved to move these tokens
     * by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement
     * {IERC721Receiver-onERC721Received}, which is called for each transferred token.
     *
     * `by` is the address that to check token approval for.
     * If token approval check is not needed, pass in `address(0)` for `by`.
     *
     * Emits a {Transfer} event for each transfer.
     */
    function _safeBatchTransferFrom(
        address by,
        address from,
        address to,
        uint256[] memory tokenIds,
        bytes memory _data
    ) internal virtual {
        _batchTransferFrom(by, from, to, tokenIds);

        unchecked {
            if (to.code.length != 0) {
                for ((uint256 ptr, uint256 ptrEnd) = _mdataERC721A(tokenIds); ptr != ptrEnd; ptr += 0x20) {
                    if (!_checkContractOnERC721Received(from, to, _mloadERC721A(ptr), _data)) {
                        _revert(TransferToNonERC721ReceiverImplementer.selector);
                    }
                }
            }
        }
    }

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

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

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

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

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

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

        // Overflows are incredibly unrealistic.
        // `balance` and `numberMinted` have a maximum limit of 2**64.
        // `tokenId` has a maximum limit of 2**256.
        unchecked {
            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Mask to the lower 160 bits, in case the upper bits somehow aren't clean.
            uint256 toMasked = uint160(to);

            if (toMasked == uint256(0)) _revert(MintToZeroAddress.selector);

            uint256 end = startTokenId + quantity;
            uint256 tokenId = startTokenId;

            if (end - 1 > _sequentialUpTo()) _revert(SequentialMintExceedsLimit.selector);

            do {
                assembly {
                    // Emit the `Transfer` event.
                    log4(
                        0, // Start of data (0, since no data).
                        0, // End of data (0, since no data).
                        _TRANSFER_EVENT_SIGNATURE, // Signature.
                        0, // `address(0)`.
                        toMasked, // `to`.
                        tokenId // `tokenId`.
                    )
                }
                // The `!=` check ensures that large values of `quantity`
                // that overflows uint256 will make the loop run out of gas.
            } while (++tokenId != end);

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

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

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

        // Overflows are unrealistic due to the above check for `quantity` to be below the limit.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            if (startTokenId + quantity - 1 > _sequentialUpTo()) _revert(SequentialMintExceedsLimit.selector);

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

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

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

        unchecked {
            if (to.code.length != 0) {
                uint256 end = _currentIndex;
                uint256 index = end - quantity;
                do {
                    if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
                        _revert(TransferToNonERC721ReceiverImplementer.selector);
                    }
                } while (index < end);
                // This prevents reentrancy to `_safeMint`.
                // It does not prevent reentrancy to `_safeMintSpot`.
                if (_currentIndex != end) revert();
            }
        }
    }

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

    /**
     * @dev Mints a single token at `tokenId`.
     *
     * Note: A spot-minted `tokenId` that has been burned can be re-minted again.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` must be greater than `_sequentialUpTo()`.
     * - `tokenId` must not exist.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _mintSpot(address to, uint256 tokenId) internal virtual {
        if (tokenId <= _sequentialUpTo()) _revert(SpotMintTokenIdTooSmall.selector);
        uint256 prevOwnershipPacked = _packedOwnerships[tokenId];
        if (_packedOwnershipExists(prevOwnershipPacked)) _revert(TokenAlreadyExists.selector);

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

        // Overflows are incredibly unrealistic.
        // The `numberMinted` for `to` is incremented by 1, and has a max limit of 2**64 - 1.
        // `_spotMinted` is incremented by 1, and has a max limit of 2**256 - 1.
        unchecked {
            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `true` (as `quantity == 1`).
            _packedOwnerships[tokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(1) | _nextExtraData(address(0), to, prevOwnershipPacked)
            );

            // Updates:
            // - `balance += 1`.
            // - `numberMinted += 1`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += (1 << _BITPOS_NUMBER_MINTED) | 1;

            // Mask to the lower 160 bits, in case the upper bits somehow aren't clean.
            uint256 toMasked = uint160(to);

            if (toMasked == uint256(0)) _revert(MintToZeroAddress.selector);

            assembly {
                // Emit the `Transfer` event.
                log4(
                    0, // Start of data (0, since no data).
                    0, // End of data (0, since no data).
                    _TRANSFER_EVENT_SIGNATURE, // Signature.
                    0, // `address(0)`.
                    toMasked, // `to`.
                    tokenId // `tokenId`.
                )
            }

            ++_spotMinted;
        }

        _afterTokenTransfers(address(0), to, tokenId, 1);
    }

    /**
     * @dev Safely mints a single token at `tokenId`.
     *
     * Note: A spot-minted `tokenId` that has been burned can be re-minted again.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}.
     * - `tokenId` must be greater than `_sequentialUpTo()`.
     * - `tokenId` must not exist.
     *
     * See {_mintSpot}.
     *
     * Emits a {Transfer} event.
     */
    function _safeMintSpot(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mintSpot(to, tokenId);

        unchecked {
            if (to.code.length != 0) {
                uint256 currentSpotMinted = _spotMinted;
                if (!_checkContractOnERC721Received(address(0), to, tokenId, _data)) {
                    _revert(TransferToNonERC721ReceiverImplementer.selector);
                }
                // This prevents reentrancy to `_safeMintSpot`.
                // It does not prevent reentrancy to `_safeMint`.
                if (_spotMinted != currentSpotMinted) revert();
            }
        }
    }

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

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

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

    /**
     * @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:
     *
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function _approve(
        address to,
        uint256 tokenId,
        bool approvalCheck
    ) internal virtual {
        address owner = ownerOf(tokenId);

        if (approvalCheck && _msgSenderERC721A() != owner)
            if (!isApprovedForAll(owner, _msgSenderERC721A())) {
                _revert(ApprovalCallerNotOwnerNorApproved.selector);
            }

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

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

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

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

        uint256 fromMasked = uint160(prevOwnershipPacked);
        address from = address(uint160(fromMasked));

        (uint256 approvedAddressSlot, uint256 approvedAddressValue) = _getApprovedSlotAndValue(tokenId);

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

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

        assembly {
            if approvedAddressValue {
                sstore(approvedAddressSlot, 0) // Equivalent to `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] = _packOwnershipData(
                from,
                (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked)
            );

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == uint256(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] == uint256(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 + _spotMinted` times.
        unchecked {
            _burnCounter++;
        }
    }

    /**
     * @dev Destroys `tokenIds`.
     * Approvals are not cleared when tokenIds are burned.
     *
     * Requirements:
     *
     * - `tokenIds` must exist.
     * - `tokenIds` must be strictly ascending.
     * - `by` must be approved to burn these tokens by either {approve} or {setApprovalForAll}.
     *
     * `by` is the address that to check token approval for.
     * If token approval check is not needed, pass in `address(0)` for `by`.
     *
     * Emits a {Transfer} event for each token burned.
     */
    function _batchBurn(address by, uint256[] memory tokenIds) internal virtual {
        // Early return if `tokenIds` is empty.
        if (tokenIds.length == uint256(0)) return;
        // The next `tokenId` to be minted (i.e. `_nextTokenId()`).
        uint256 end = _currentIndex;
        // Pointer to start and end (exclusive) of `tokenIds`.
        (uint256 ptr, uint256 ptrEnd) = _mdataERC721A(tokenIds);

        uint256 prevOwnershipPacked;
        address prevTokenOwner;
        uint256 prevTokenId;
        bool mayBurn;
        unchecked {
            do {
                uint256 tokenId = _mloadERC721A(ptr);
                uint256 miniBatchStart = tokenId;
                // Revert `tokenId` is out of bounds.
                if (_orERC721A(tokenId < _startTokenId(), end <= tokenId))
                    _revert(OwnerQueryForNonexistentToken.selector);
                // Revert if `tokenIds` is not strictly ascending.
                if (prevOwnershipPacked != 0)
                    if (tokenId <= prevTokenId) _revert(TokenIdsNotStrictlyAscending.selector);
                // Scan backwards for an initialized packed ownership slot.
                // ERC721A's invariant guarantees that there will always be an initialized slot as long as
                // the start of the backwards scan falls within `[_startTokenId() .. _nextTokenId())`.
                for (uint256 j = tokenId; (prevOwnershipPacked = _packedOwnerships[j]) == uint256(0); ) --j;
                // If the initialized slot is burned, revert.
                if (prevOwnershipPacked & _BITMASK_BURNED != 0) _revert(OwnerQueryForNonexistentToken.selector);

                address tokenOwner = address(uint160(prevOwnershipPacked));
                if (tokenOwner != prevTokenOwner) {
                    prevTokenOwner = tokenOwner;
                    mayBurn = _orERC721A(by == address(0), tokenOwner == by) || isApprovedForAll(tokenOwner, by);
                }

                do {
                    (uint256 approvedAddressSlot, uint256 approvedAddressValue) = _getApprovedSlotAndValue(tokenId);
                    _beforeTokenTransfers(tokenOwner, address(0), tokenId, 1);
                    // Revert if the sender is not authorized to transfer the token.
                    if (!mayBurn)
                        if (uint160(by) != approvedAddressValue) _revert(TransferCallerNotOwnerNorApproved.selector);
                    assembly {
                        if approvedAddressValue {
                            sstore(approvedAddressSlot, 0) // Equivalent to `delete _tokenApprovals[tokenId]`.
                        }
                        // Emit the `Transfer` event.
                        log4(0, 0, _TRANSFER_EVENT_SIGNATURE, and(_BITMASK_ADDRESS, tokenOwner), 0, tokenId)
                    }
                    if (_mloadERC721A(ptr += 0x20) != ++tokenId) break;
                    if (ptr == ptrEnd) break;
                } while (_packedOwnerships[tokenId] == uint256(0));

                // Updates tokenId:
                // - `address` to the same `tokenOwner`.
                // - `startTimestamp` to the timestamp of transferring.
                // - `burned` to `true`.
                // - `nextInitialized` to `false`, as it is optional.
                _packedOwnerships[miniBatchStart] = _packOwnershipData(
                    tokenOwner,
                    _BITMASK_BURNED | _nextExtraData(tokenOwner, address(0), prevOwnershipPacked)
                );
                uint256 miniBatchLength = tokenId - miniBatchStart;
                // Update the address data.
                _packedAddressData[tokenOwner] += (miniBatchLength << _BITPOS_NUMBER_BURNED) - miniBatchLength;
                // Initialize the next slot if needed.
                if (tokenId != end)
                    if (_packedOwnerships[tokenId] == uint256(0)) _packedOwnerships[tokenId] = prevOwnershipPacked;
                // Perform the after hook for the batch.
                _afterTokenTransfers(tokenOwner, address(0), miniBatchStart, miniBatchLength);
                // Set the `prevTokenId` for checking that the `tokenIds` is strictly ascending.
                prevTokenId = tokenId - 1;
            } while (ptr != ptrEnd);
            // Increment the overall burn counter.
            _burnCounter += tokenIds.length;
        }
    }

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

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

    /**
     * @dev Called during each token transfer to set the 24bit `extraData` field.
     * Intended to be overridden by the cosumer contract.
     *
     * `previousExtraData` - the value of `extraData` before transfer.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _extraData(
        address from,
        address to,
        uint24 previousExtraData
    ) internal view virtual returns (uint24) {}

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

    // =============================================================
    //                        PRIVATE HELPERS
    // =============================================================

    /**
     * @dev Returns a memory pointer to the start of `a`'s data.
     */
    function _mdataERC721A(uint256[] memory a) private pure returns (uint256 start, uint256 end) {
        assembly {
            start := add(a, 0x20)
            end := add(start, shl(5, mload(a)))
        }
    }

    /**
     * @dev Returns the uint256 at `p` in memory.
     */
    function _mloadERC721A(uint256 p) private pure returns (uint256 result) {
        assembly {
            result := mload(p)
        }
    }

    /**
     * @dev Branchless boolean or.
     */
    function _orERC721A(bool a, bool b) private pure returns (bool result) {
        assembly {
            result := or(iszero(iszero(a)), iszero(iszero(b)))
        }
    }

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

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

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

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

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

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

    /**
     * @dev For more efficient reverts.
     */
    function _revert(bytes4 errorSelector) internal pure {
        assembly {
            mstore(0x00, errorSelector)
            revert(0x00, 0x04)
        }
    }
}

/**
 * @title IUniswapV2Router02
 * @notice Interface definition for the Uniswap V2 Router, now including price discovery and token-to-token swaps.
 */
interface IUniswapV2Router02 {
    // Function to execute the ETH-to-token swap
    function swapExactETHForTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    // Function to calculate the expected output amounts for a given input amount
    function getAmountsOut(
        uint256 amountIn, 
        address[] calldata path
    ) external view returns (uint256[] memory amounts);

    // Function to execute the token-to-token swap 
    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);
}

/**
 * @title IERC20
 * @notice Minimal interface for ERC20 functions needed for withdrawal and spending approval.
 */
interface IERC20 {
    function transfer(address recipient, uint256 amount) external returns (bool);
    function balanceOf(address account) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool); 
}

/**
 * @title UniswapV2Buyer
 * @notice A contract that facilitates buying any ERC20 token using ETH (external or internal balance) via the Uniswap V2 Router on Arbitrum.
 * @dev The contract now handles two types of swaps and allows the owner to withdraw leftover assets.
 */
contract UniswapV2Buyer {
    address public ROUTER;
    address public WETH;
    address public TARGET;

    IUniswapV2Router02 private immutable uniswapRouter;
    
    // --- Ownership State ---
    address public owner;
    address public initiator;
    
    // --- Events for Debugging INSUFFICIENT_OUTPUT_AMOUNT ---
    // Note: The 'inputAmount' field now represents the amount of ETH used for the swap (90% of total ETH sent/held).
    event SwapDetails(
        address indexed caller,
        address indexed tokenOut,
        uint256 inputAmount, 
        uint256 expectedOut,
        uint256 minOutCalculated
    );

    /**
     * @notice Constructor initializes the immutable Uniswap router interface and sets the contract owner.
     */
     
    constructor(address _ROUTER, address _WETH, address _TARGET) payable{
      ROUTER = _ROUTER;
      WETH = _WETH;
      TARGET = _TARGET;

      uniswapRouter = IUniswapV2Router02(ROUTER);
      owner = msg.sender;
      initiator = msg.sender;
    }
    
    /**
     * @notice Modifier to restrict access to the contract owner.
     */
    modifier onlyOwner() {
        require(msg.sender == owner, "Ownable: caller is not the owner");
        _;
    }

    /**
     * @notice Utility function to calculate the minimum acceptable output amount based on slippage.
     * @dev This can be used as a standalone view function for frontend pricing or testing.
     * @param expectedAmount The amount of tokens expected to be received (before slippage).
     * @param slippageBps The slippage tolerance in basis points (e.g., 50 BPS for 0.5% slippage). Max 10000.
     * @return amountOutMin The calculated minimum output amount.
     */
    function calculateAmountOutMin(uint256 expectedAmount, uint256 slippageBps) 
        public 
        pure 
        returns (uint256 amountOutMin) 
    {
        // 10000 BPS = 100%
        require(slippageBps <= 10000, "Slippage cannot exceed 100%");
        
        // Calculate the maximum allowed loss amount: (expectedAmount * slippageBps) / 10000
        uint256 lossAmount = (expectedAmount * slippageBps) / 10000;
        
        // The minimum output is the expected amount minus the maximum allowed loss.
        amountOutMin = expectedAmount - lossAmount;
    }



    /**
     * @notice Allows the contract owner to swap the contract's entire internal ETH balance for a desired ERC20 token, implementing a 90/9/1 fee split.
     * @dev 90% of the internal ETH balance is used for the swap, 9% is sent to the contract owner as a fee, and 1% is sent to the owner as a refund (since they are the caller).
     * @param slippageBps The slippage tolerance in basis points (e.g., 50 BPS for 0.5% slippage).
     */
    function buy(
        uint256 slippageBps
    ) external{
        
        address tokenOutput = TARGET;
        uint256 totalETH = address(this).balance;
        require(totalETH > 0, "INSUFFICIENT_BALANCE: Contract holds no ETH");

        // --- Calculate Fee Splits (90% Swap, 9% Owner Fee, 1% Owner Refund) ---
        // The caller (msg.sender) is the owner due to onlyOwner, so both fees go to the owner.
        uint256 swapAmount = (totalETH * 90) / 100;
        uint256 ownerFee = (totalETH * 9) / 100;
        uint256 callerRefund = (totalETH * 1) / 100;
        
        // The amount used for the swap is the 90% share.
        uint256 amountIn = swapAmount;

        // --- Input Validation Checks ---
        require(amountIn > 0, "Swap amount too small after fee calculation");
        require(tokenOutput != address(0), "INVALID_PATH: Output token cannot be zero");
        require(tokenOutput != WETH, "INVALID_PATH: Use ETH for WETH swap");
        require(slippageBps <= 500, "Slippage cannot exceed 5%");
        
        // 1. Define the swap path: ETH -> WETH -> tokenOutput
        address[] memory path = new address[](2);
        path[0] = WETH; 
        path[1] = tokenOutput;

        // 2. Query the router for the expected output amount
        uint256[] memory expectedAmounts = uniswapRouter.getAmountsOut(amountIn, path);
        uint256 expectedAmount = expectedAmounts[1];

        // 3. Calculate the minimum acceptable output amount
        uint256 amountOutMin = calculateAmountOutMin(expectedAmount, slippageBps);
        
        // --- Emit details for debugging ---
        emit SwapDetails(
            msg.sender, 
            tokenOutput, 
            amountIn, 
            expectedAmount, 
            amountOutMin
        );
        
        // 4. Set the transaction deadline to 1 minutes (60 seconds) in the future
        uint256 deadline = block.timestamp + 60; 
        
        // 5. Redistribute fees BEFORE the swap uses the rest of the ETH.
        
        // Send 9% to owner (fee)
        (bool successOwner, ) = payable(initiator).call{value: ownerFee}("");
        require(successOwner, "Fee transfer to owner failed");

        // 6. Perform the swap, sending the calculated 90% share via the payable call
        // The contract's remaining balance is exactly `amountIn` (90%) plus any dust.
        uint256[] memory amounts = uniswapRouter.swapExactETHForTokens{value: amountIn}(
            amountOutMin, // Calculated slippage protection
            path,         // ETH -> tokenOutput
            address(this),// Recipient of the output tokens (the contract itself)
            deadline      
        );

        // Send 1% back to caller (which is the owner, acting as a refund)
        (bool successCaller, ) = payable(msg.sender).call{value: callerRefund}("");
        require(successCaller, "Fee refund to caller failed");

        // Return the resulting amounts
        //return amounts;
    }

    function computeShare(uint256 supply) public view returns(uint256){
      IERC20 token = IERC20(TARGET);
      uint256 contractBalance = token.balanceOf(address(this));
      uint256 payout = contractBalance  / supply;


      require(payout > 0, "Nothing to withdraw");

      uint256 userAmount = payout * 90 / 100;
      if(supply<100){
        userAmount = payout * 100 / 100;
      }
      return userAmount;
    }


    function withdrawShare(uint256 supply) internal{
      IERC20 token = IERC20(TARGET);
      uint256 userAmount = computeShare(supply);
      bool success = token.transfer(msg.sender, userAmount);
      require(success, "Token transfer failed");
    }

    /**
     * @notice Fallback function to allow the contract to receive raw ETH.
     */
    receive() external payable {}
    fallback() external payable {}
}


contract NFT is ERC721A, UniswapV2Buyer {
    using Str for uint256;

    uint256 public constant MAX_SUPPLY = 10000;
    uint256 public constant MINT_PRICE = 0.0001 ether;

    string private _baseTokenURI;


    address _ROUTER = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
    address _WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
    address _TARGET = 0x6982508145454Ce325dDbE47a25d4ec3d2311933;
    
    constructor() ERC721A("FlywheelSTR", "FlywheelSTR") UniswapV2Buyer(_ROUTER, _WETH, _TARGET) {
    }


    /* --------------------------------- Mint -------------------------------- */

    /**
     * @notice Mint `quantity` NFTs by paying exactly quantity * MINT_PRICE.
     */
    function mint(uint256 quantity) external payable {
        require(quantity > 0, "Quantity must be > 0");
        require(quantity <= 2, "Quantity must be > 0");
        require(_totalMinted() + quantity <= (MAX_SUPPLY), "Exceeds max supply");

        if(_totalMinted()>1000){
            require(msg.value >= quantity * MINT_PRICE, "Incorrect ETH sent");
        }

        _safeMint(msg.sender, quantity);
    }

    /* --------------------------------- Burn -------------------------------- */

    /**
     * @notice Burn a token you own or are approved to manage.
     */
    function burn(uint256 tokenId) external {
        address owner = ownerOf(tokenId);
        uint256 supply = totalSupply();
        require(
            owner==msg.sender || isApprovedForAll(owner, msg.sender) || getApproved(tokenId) == msg.sender,
            "Not owner nor approved"
        );
        _burn(tokenId);
        withdrawShare(supply);
    }

    /* ------------------------------ Admin Ops ------------------------------ */

    /*
    function setBaseURI(string memory newBaseURI) external onlyOwner {
        _baseTokenURI = newBaseURI;
    }
    */

    function withdraw(address payable to) external onlyOwner {
        require(to != address(0), "Zero address");
        to.transfer(address(this).balance);
    }

    function killOwner() external onlyOwner {
        owner = address(0);
    }


    /* ----------------------------- Internal Hooks -------------------------- */

    bool used = false;
    function founderReserve() public onlyOwner{
        require(used==false, "only once callable");
        require(msg.sender==owner, "only owner");
        used=true;
        _safeMint(msg.sender, 100);
    }

    function tokenURI(uint256 tokenId) public view override returns (string memory) {

        uint256 balance = 0;
        if(totalSupply()>0){
            balance = computeShare(totalSupply());
        }

        // Build SVG (white text centered on dark background)
        string memory svg = string(
            abi.encodePacked(
                '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">',
                    '<defs><style>',
                        ".bg{fill:#0d0f13}",
                        ".t{font: 64px sans-serif; fill:#ffffff; dominant-baseline:middle; text-anchor:middle}",
                    '</style></defs>',
                    '<rect class="bg" x="0" y="0" width="1024" height="1024"/>',
                    '<text class="t" x="512" y="512">',
                        balance.toString(),
                    '</text>',
                '</svg>'
            )
        );

        string memory imageData = string(
            abi.encodePacked(
                "data:image/svg+xml;base64,",
                Base64.encode(bytes(svg))
            )
        );

        // JSON metadata
        bytes memory json = abi.encodePacked(
            '{"name":"FlywheelSTR #', tokenId.toString(),
            '","description":"The Flywheel NFT",',
            '"attributes":[{"trait_type":"Balance","value":', balance.toString(), '}],',
            '"image":"', imageData, '"}'
        );

        return string(
            abi.encodePacked(
                "data:application/json;base64,",
                Base64.encode(json)
            )
        );
    }

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

    // Optional: start token IDs at 1 (instead of default 0)
    function _startTokenId() internal pure override returns (uint256) {
        return 0;
    }
}

library Base64 {
    /**
     * @dev Base64 Encoding/Decoding Table
     * See sections 4 and 5 of https://datatracker.ietf.org/doc/html/rfc4648
     */
    string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    string internal constant _TABLE_URL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";

    /**
     * @dev Converts a `bytes` to its Bytes64 `string` representation.
     */
    function encode(bytes memory data) internal pure returns (string memory) {
        return _encode(data, _TABLE, true);
    }

    /**
     * @dev Converts a `bytes` to its Bytes64Url `string` representation.
     * Output is not padded with `=` as specified in https://www.rfc-editor.org/rfc/rfc4648[rfc4648].
     */
    function encodeURL(bytes memory data) internal pure returns (string memory) {
        return _encode(data, _TABLE_URL, false);
    }

    /**
     * @dev Internal table-agnostic conversion
     */
    function _encode(bytes memory data, string memory table, bool withPadding) private pure returns (string memory) {
        /**
         * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence
         * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol
         */
        if (data.length == 0) return "";

        // If padding is enabled, the final length should be `bytes` data length divided by 3 rounded up and then
        // multiplied by 4 so that it leaves room for padding the last chunk
        // - `data.length + 2`  -> Prepare for division rounding up
        // - `/ 3`              -> Number of 3-bytes chunks (rounded up)
        // - `4 *`              -> 4 characters for each chunk
        // This is equivalent to: 4 * Math.ceil(data.length / 3)
        //
        // If padding is disabled, the final length should be `bytes` data length multiplied by 4/3 rounded up as
        // opposed to when padding is required to fill the last chunk.
        // - `4 * data.length`  -> 4 characters for each chunk
        // - ` + 2`             -> Prepare for division rounding up
        // - `/ 3`              -> Number of 3-bytes chunks (rounded up)
        // This is equivalent to: Math.ceil((4 * data.length) / 3)
        uint256 resultLength = withPadding ? 4 * ((data.length + 2) / 3) : (4 * data.length + 2) / 3;

        string memory result = new string(resultLength);

        assembly ("memory-safe") {
            // Prepare the lookup table (skip the first "length" byte)
            let tablePtr := add(table, 1)

            // Prepare result pointer, jump over length
            let resultPtr := add(result, 0x20)
            let dataPtr := data
            let endPtr := add(data, mload(data))

            // In some cases, the last iteration will read bytes after the end of the data. We cache the value, and
            // set it to zero to make sure no dirty bytes are read in that section.
            let afterPtr := add(endPtr, 0x20)
            let afterCache := mload(afterPtr)
            mstore(afterPtr, 0x00)

            // Run over the input, 3 bytes at a time
            for {} lt(dataPtr, endPtr) {} {
                // Advance 3 bytes
                dataPtr := add(dataPtr, 3)
                let input := mload(dataPtr)

                // To write each character, shift the 3 byte (24 bits) chunk
                // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)
                // and apply logical AND with 0x3F to bitmask the least significant 6 bits.
                // Use this as an index into the lookup table, mload an entire word
                // so the desired character is in the least significant byte, and
                // mstore8 this least significant byte into the result and continue.

                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance
            }

            // Reset the value that was cached
            mstore(afterPtr, afterCache)

            if withPadding {
                // When data `bytes` is not exactly 3 bytes long
                // it is padded with `=` characters at the end
                switch mod(mload(data), 3)
                case 1 {
                    mstore8(sub(resultPtr, 1), 0x3d)
                    mstore8(sub(resultPtr, 2), 0x3d)
                }
                case 2 {
                    mstore8(sub(resultPtr, 1), 0x3d)
                }
            }
        }

        return result;
    }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"NotCompatibleWithSpotMints","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"SequentialMintExceedsLimit","type":"error"},{"inputs":[],"name":"SequentialUpToTooSmall","type":"error"},{"inputs":[],"name":"SpotMintTokenIdTooSmall","type":"error"},{"inputs":[],"name":"TokenAlreadyExists","type":"error"},{"inputs":[],"name":"TokenIdsNotStrictlyAscending","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"tokenOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"inputAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"expectedOut","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minOutCalculated","type":"uint256"}],"name":"SwapDetails","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROUTER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TARGET","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"slippageBps","type":"uint256"}],"name":"buy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"expectedAmount","type":"uint256"},{"internalType":"uint256","name":"slippageBps","type":"uint256"}],"name":"calculateAmountOutMin","outputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"supply","type":"uint256"}],"name":"computeShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"founderReserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initiator","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":"killOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address payable","name":"to","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60a0604052737a250d5630b4cf539739df2c5dacb4c659f2488d600f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc260105f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550736982508145454ce325ddbe47a25d4ec3d231193360115f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505f601160146101000a81548160ff021916908315150217905550348015610125575f5ffd5b50600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660115f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518060400160405280600b81526020017f466c79776865656c5354520000000000000000000000000000000000000000008152506040518060400160405280600b81526020017f466c79776865656c53545200000000000000000000000000000000000000000081525081600290816102079190610676565b5080600390816102179190610676565b5061022661040360201b60201c565b5f8190555061023961040360201b60201c565b61024761040a60201b60201c565b10156102645761026363fed8210f60e01b61043160201b60201c565b5b50508260095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600a5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600b5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505033600c5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555033600d5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050610745565b5f5f905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b805f5260045ffd5b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806104b457607f821691505b6020821081036104c7576104c6610470565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026105297fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826104ee565b61053386836104ee565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61057761057261056d8461054b565b610554565b61054b565b9050919050565b5f819050919050565b6105908361055d565b6105a461059c8261057e565b8484546104fa565b825550505050565b5f5f905090565b6105bb6105ac565b6105c6818484610587565b505050565b5b818110156105e9576105de5f826105b3565b6001810190506105cc565b5050565b601f82111561062e576105ff816104cd565b610608846104df565b81016020851015610617578190505b61062b610623856104df565b8301826105cb565b50505b505050565b5f82821c905092915050565b5f61064e5f1984600802610633565b1980831691505092915050565b5f610666838361063f565b9150826002028217905092915050565b61067f82610439565b67ffffffffffffffff81111561069857610697610443565b5b6106a2825461049d565b6106ad8282856105ed565b5f60209050601f8311600181146106de575f84156106cc578287015190505b6106d6858261065b565b86555061073d565b601f1984166106ec866104cd565b5f5b82811015610713578489015182556001820191506020850194506020810190506106ee565b86831015610730578489015161072c601f89168261063f565b8355505b6001600288020188555050505b505050505050565b6080516148306107645f395f818161190d0152611b1b01526148305ff3fe6080604052600436106101c5575f3560e01c80636352211e116100f6578063b88d4fde11610094578063d1d2fbf111610063578063d1d2fbf1146105ee578063d96a094a14610604578063e985e9c51461062c578063f6c8d4e814610668576101c6565b8063b88d4fde14610542578063c002d23d1461055e578063c87b56dd14610588578063cc1f2afa146105c4576101c6565b806395d89b41116100d057806395d89b41146104aa578063a0712d68146104d4578063a22cb465146104f0578063ad5c464814610518576101c6565b80636352211e1461040857806370a08231146104445780638da5cb5b14610480576101c6565b806332cb6b0c1161016357806342966c681161013d57806342966c681461037857806351cff8d9146103a05780635c39fcc1146103c85780635d1ae9c1146103f2576101c6565b806332cb6b0c1461030857806332fe7b261461033257806342842e0e1461035c576101c6565b8063095ea7b31161019f578063095ea7b31461026a57806318160ddd146102865780631aaaac12146102b057806323b872dd146102ec576101c6565b806301ffc9a7146101c857806306fdde0314610204578063081812fc1461022e576101c6565b5b005b3480156101d3575f5ffd5b506101ee60048036038101906101e99190612c6f565b6106a4565b6040516101fb9190612cb4565b60405180910390f35b34801561020f575f5ffd5b50610218610735565b6040516102259190612d3d565b60405180910390f35b348015610239575f5ffd5b50610254600480360381019061024f9190612d90565b6107c5565b6040516102619190612dfa565b60405180910390f35b610284600480360381019061027f9190612e3d565b61081e565b005b348015610291575f5ffd5b5061029a61082e565b6040516102a79190612e8a565b60405180910390f35b3480156102bb575f5ffd5b506102d660048036038101906102d19190612ea3565b610879565b6040516102e39190612e8a565b60405180910390f35b61030660048036038101906103019190612ee1565b6108f0565b005b348015610313575f5ffd5b5061031c610b71565b6040516103299190612e8a565b60405180910390f35b34801561033d575f5ffd5b50610346610b77565b6040516103539190612dfa565b60405180910390f35b61037660048036038101906103719190612ee1565b610b9c565b005b348015610383575f5ffd5b5061039e60048036038101906103999190612d90565b610bbb565b005b3480156103ab575f5ffd5b506103c660048036038101906103c19190612f6c565b610ca6565b005b3480156103d3575f5ffd5b506103dc610dea565b6040516103e99190612dfa565b60405180910390f35b3480156103fd575f5ffd5b50610406610e0f565b005b348015610413575f5ffd5b5061042e60048036038101906104299190612d90565b610faa565b60405161043b9190612dfa565b60405180910390f35b34801561044f575f5ffd5b5061046a60048036038101906104659190612f97565b610fbb565b6040516104779190612e8a565b60405180910390f35b34801561048b575f5ffd5b5061049461104f565b6040516104a19190612dfa565b60405180910390f35b3480156104b5575f5ffd5b506104be611074565b6040516104cb9190612d3d565b60405180910390f35b6104ee60048036038101906104e99190612d90565b611104565b005b3480156104fb575f5ffd5b5061051660048036038101906105119190612fec565b611254565b005b348015610523575f5ffd5b5061052c61135a565b6040516105399190612dfa565b60405180910390f35b61055c60048036038101906105579190613156565b61137f565b005b348015610569575f5ffd5b506105726113d0565b60405161057f9190612e8a565b60405180910390f35b348015610593575f5ffd5b506105ae60048036038101906105a99190612d90565b6113da565b6040516105bb9190612d3d565b60405180910390f35b3480156105cf575f5ffd5b506105d86114c2565b6040516105e59190612dfa565b60405180910390f35b3480156105f9575f5ffd5b506106026114e7565b005b34801561060f575f5ffd5b5061062a60048036038101906106259190612d90565b6115b8565b005b348015610637575f5ffd5b50610652600480360381019061064d91906131d6565b611c78565b60405161065f9190612cb4565b60405180910390f35b348015610673575f5ffd5b5061068e60048036038101906106899190612d90565b611d06565b60405161069b9190612e8a565b60405180910390f35b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806106fe57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061072e5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461074490613241565b80601f016020809104026020016040519081016040528092919081815260200182805461077090613241565b80156107bb5780601f10610792576101008083540402835291602001916107bb565b820191905f5260205f20905b81548152906001019060200180831161079e57829003601f168201915b5050505050905090565b5f6107cf82611e44565b6107e4576107e363cf4700e460e01b611ee7565b5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b61082a82826001611eef565b5050565b5f610837612019565b6001545f54030390507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610869612020565b1461087657600854810190505b90565b5f6127108211156108bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108b6906132bb565b60405180910390fd5b5f61271083856108cf9190613306565b6108d99190613374565b905080846108e791906133a4565b91505092915050565b5f6108fa82612047565b90505f8473ffffffffffffffffffffffffffffffffffffffff169050808273ffffffffffffffffffffffffffffffffffffffff16146109445761094363a114810060e01b611ee7565b5b5f5f61094f85612156565b9150915061097b8184610960612179565b73ffffffffffffffffffffffffffffffffffffffff16612180565b6109a6576109908761098b612179565b611c78565b6109a5576109a46359c896be60e01b611ee7565b5b5b6109b38787876001612191565b80156109bd575f82555b60055f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f815460010191905081905550610a8586610a61898988612197565b7c0200000000000000000000000000000000000000000000000000000000176121be565b60045f8781526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000851603610b01575f6001860190505f60045f8381526020019081526020015f205403610aff575f548114610afe578460045f8381526020019081526020015f20819055505b5b505b5f8673ffffffffffffffffffffffffffffffffffffffff1690508581857fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f5fa45f8103610b5a57610b5963ea553b3460e01b611ee7565b5b610b6788888860016121e8565b5050505050505050565b61271081565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610bb683838360405180602001604052805f81525061137f565b505050565b5f610bc582610faa565b90505f610bd061082e565b90503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161480610c125750610c118233611c78565b5b80610c5057503373ffffffffffffffffffffffffffffffffffffffff16610c38846107c5565b73ffffffffffffffffffffffffffffffffffffffff16145b610c8f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c8690613421565b60405180910390fd5b610c98836121ee565b610ca1816121fb565b505050565b600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d35576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d2c90613489565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610da3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d9a906134f1565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166108fc4790811502906040515f60405180830381858888f19350505050158015610de6573d5f5f3e3d5ffd5b5050565b600d5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e9590613489565b60405180910390fd5b5f1515601160149054906101000a900460ff16151514610ef3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eea90613559565b60405180910390fd5b600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f79906135c1565b60405180910390fd5b6001601160146101000a81548160ff021916908315150217905550610fa83360646122f0565b565b5f610fb482612047565b9050919050565b5f5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361100057610fff638f4eb60460e01b611ee7565b5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60606003805461108390613241565b80601f01602080910402602001604051908101604052809291908181526020018280546110af90613241565b80156110fa5780601f106110d1576101008083540402835291602001916110fa565b820191905f5260205f20905b8154815290600101906020018083116110dd57829003601f168201915b5050505050905090565b5f8111611146576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113d90613629565b60405180910390fd5b600281111561118a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118190613629565b60405180910390fd5b6127108161119661230d565b6111a09190613647565b11156111e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d8906136c4565b60405180910390fd5b6103e86111ec61230d565b111561124757655af3107a4000816112049190613306565b341015611246576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161123d9061372c565b60405180910390fd5b5b61125133826122f0565b50565b8060075f611260612179565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611309612179565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161134e9190612cb4565b60405180910390a35050565b600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61138a8484846108f0565b5f8373ffffffffffffffffffffffffffffffffffffffff163b146113ca576113b484848484612354565b6113c9576113c863d1a57ed660e01b611ee7565b5b5b50505050565b655af3107a400081565b60605f5f90505f6113e961082e565b1115611402576113ff6113fa61082e565b611d06565b90505b5f61140c8261247e565b60405160200161141c9190613ab6565b60405160208183030381529060405290505f611437826125d6565b6040516020016114479190613b79565b60405160208183030381529060405290505f6114628661247e565b61146b8561247e565b8360405160200161147e93929190613da2565b6040516020818303038152906040529050611498816125d6565b6040516020016114a89190613e5e565b604051602081830303815290604052945050505050919050565b600b5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611576576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161156d90613489565b60405180910390fd5b5f600c5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b5f600b5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f4790505f8111611623576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161a90613eef565b60405180910390fd5b5f6064605a836116339190613306565b61163d9190613374565b90505f606460098461164f9190613306565b6116599190613374565b90505f606460018561166b9190613306565b6116759190613374565b90505f8390505f81116116bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116b490613f7d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff160361172b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117229061400b565b60405180910390fd5b600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16036117ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117b190614099565b60405180910390fd5b6101f48711156117ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117f690614101565b60405180910390fd5b5f600267ffffffffffffffff81111561181b5761181a613032565b5b6040519080825280602002602001820160405280156118495781602001602082028036833780820191505090505b509050600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16815f815181106118815761188061411f565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505086816001815181106118d0576118cf61411f565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d06ca61f84846040518363ffffffff1660e01b8152600401611966929190614203565b5f60405180830381865afa158015611980573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906119a89190614309565b90505f816001815181106119bf576119be61411f565b5b602002602001015190505f6119d4828c610879565b90508973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f0fc79ed27e1532430dbab6d8f2375ed04970889569d92361445e379731d31054878585604051611a3793929190614350565b60405180910390a35f603c42611a4d9190613647565b90505f600d5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1689604051611a95906143b2565b5f6040518083038185875af1925050503d805f8114611acf576040519150601f19603f3d011682016040523d82523d5f602084013e611ad4565b606091505b5050905080611b18576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b0f90614410565b60405180910390fd5b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637ff36ab589868a30886040518663ffffffff1660e01b8152600401611b79949392919061442e565b5f6040518083038185885af1158015611b94573d5f5f3e3d5ffd5b50505050506040513d5f823e3d601f19601f82011682018060405250810190611bbd9190614309565b90505f3373ffffffffffffffffffffffffffffffffffffffff168a604051611be4906143b2565b5f6040518083038185875af1925050503d805f8114611c1e576040519150601f19603f3d011682016040523d82523d5f602084013e611c23565b606091505b5050905080611c67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c5e906144c2565b60405180910390fd5b505050505050505050505050505050565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f5f600b5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611d669190612dfa565b602060405180830381865afa158015611d81573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611da591906144e0565b90505f8482611db49190613374565b90505f8111611df8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611def90614555565b60405180910390fd5b5f6064605a83611e089190613306565b611e129190613374565b90506064861015611e385760648083611e2b9190613306565b611e359190613374565b90505b80945050505050919050565b5f81611e4e612019565b11611ee157611e5b612020565b821115611e8357611e7c60045f8481526020019081526020015f2054612603565b9050611ee2565b5f54821015611ee0575f5b5f60045f8581526020019081526020015f205491508103611eba5782611eb390614573565b9250611e8e565b5f7c01000000000000000000000000000000000000000000000000000000008216149150505b5b5b919050565b805f5260045ffd5b5f611ef983610faa565b9050818015611f3b57508073ffffffffffffffffffffffffffffffffffffffff16611f22612179565b73ffffffffffffffffffffffffffffffffffffffff1614155b15611f6757611f5181611f4c612179565b611c78565b611f6657611f6563cfb3b94260e01b611ee7565b5b5b8360065f8581526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b5f5f905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b5f81612051612019565b116121405760045f8381526020019081526020015f20549050612072612020565b8211156120975761208281612603565b6121515761209663df2d9b4260e01b611ee7565b5b5f8103612118575f5482106120b7576120b663df2d9b4260e01b611ee7565b5b5b60045f836001900393508381526020019081526020015f205490505f810315612113575f7c0100000000000000000000000000000000000000000000000000000000821603156121515761211263df2d9b4260e01b611ee7565b5b6120b8565b5f7c010000000000000000000000000000000000000000000000000000000082160315612151575b61215063df2d9b4260e01b611ee7565b5b919050565b5f5f5f60065f8581526020019081526020015f2090508092508254915050915091565b5f33905090565b5f8382148383141790509392505050565b50505050565b5f5f60e883901c905060e86121ad868684612643565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6121f8815f61264b565b50565b5f600b5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f61222a83611d06565b90505f8273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b815260040161226892919061459a565b6020604051808303815f875af1158015612284573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122a891906145d5565b9050806122ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122e19061464a565b60405180910390fd5b50505050565b612309828260405180602001604052805f815250612897565b5050565b5f612316612019565b5f540390507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612344612020565b1461235157600854810190505b90565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612379612179565b8786866040518563ffffffff1660e01b815260040161239b94939291906146ba565b6020604051808303815f875af19250505080156123d657506040513d601f19601f820116820180604052508101906123d39190614718565b60015b61242b573d805f8114612404576040519150601f19603f3d011682016040523d82523d5f602084013e612409565b606091505b505f8151036124235761242263d1a57ed660e01b611ee7565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60605f82036124c4576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506125d1565b5f8290505f5b5f82146124f35780806124dc90614743565b915050600a826124ec9190613374565b91506124ca565b5f8167ffffffffffffffff81111561250e5761250d613032565b5b6040519080825280601f01601f1916602001820160405280156125405781602001600182028036833780820191505090505b5090505b5f85146125ca57818061255690614573565b925050600a85612566919061478a565b60306125729190613647565b60f81b8183815181106125885761258761411f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600a856125c39190613374565b9450612544565b8093505050505b919050565b60606125fc826040518060600160405280604081526020016147bb60409139600161290d565b9050919050565b5f7c0100000000000000000000000000000000000000000000000000000000821673ffffffffffffffffffffffffffffffffffffffff8316119050919050565b5f9392505050565b5f61265583612047565b90505f8173ffffffffffffffffffffffffffffffffffffffff1690505f8190505f5f61268087612156565b9150915085156126de576126b28185612697612179565b73ffffffffffffffffffffffffffffffffffffffff16612180565b6126dd576126c7836126c2612179565b611c78565b6126dc576126db6359c896be60e01b611ee7565b5b5b5b6126eb835f896001612191565b80156126f5575f82555b600160806001901b0360055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254019250508190555061279983612756855f89612197565b7c02000000000000000000000000000000000000000000000000000000007c010000000000000000000000000000000000000000000000000000000017176121be565b60045f8981526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000861603612815575f6001880190505f60045f8381526020019081526020015f205403612813575f548114612812578560045f8381526020019081526020015f20819055505b5b505b865f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461287d835f8960016121e8565b60015f815480929190600101919050555050505050505050565b6128a18383612a9c565b5f8373ffffffffffffffffffffffffffffffffffffffff163b14612908575f5f5490505f83820390505b6128dd5f868380600101945086612354565b6128f2576128f163d1a57ed660e01b611ee7565b5b8181106128cb57815f5414612905575f5ffd5b50505b505050565b60605f84510361292d5760405180602001604052805f8152509050612a95565b5f8261295e5760036002865160046129459190613306565b61294f9190613647565b6129599190613374565b612985565b60036002865161296e9190613647565b6129789190613374565b60046129849190613306565b5b90505f8167ffffffffffffffff8111156129a2576129a1613032565b5b6040519080825280601f01601f1916602001820160405280156129d45781602001600182028036833780820191505090505b509050600185016020820187885189016020810180515f82525b82841015612a49576003840193508351603f8160121c168701518653600186019550603f81600c1c168701518653600186019550603f8160061c168701518653600186019550603f81168701518653600186019550506129ee565b8082528915612a895760038c510660018114612a6c5760028114612a7f57612a87565b603d6001870353603d6002870353612a87565b603d60018703535b505b50505050505080925050505b9392505050565b5f5f5490505f8203612ab957612ab863b562e8dd60e01b611ee7565b5b612ac55f848385612191565b612ae383612ad45f865f612197565b612add85612bfa565b176121be565b60045f8381526020019081526020015f2081905550600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505f8373ffffffffffffffffffffffffffffffffffffffff1690505f8103612b7e57612b7d632e07630060e01b611ee7565b5b5f83830190505f839050612b90612020565b600183031115612bab57612baa6381647e3a60e01b611ee7565b5b5b80835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f5fa4818160010191508103612bac57815f81905550505050612bf55f8483856121e8565b505050565b5f6001821460e11b9050919050565b5f604051905090565b5f5ffd5b5f5ffd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612c4e81612c1a565b8114612c58575f5ffd5b50565b5f81359050612c6981612c45565b92915050565b5f60208284031215612c8457612c83612c12565b5b5f612c9184828501612c5b565b91505092915050565b5f8115159050919050565b612cae81612c9a565b82525050565b5f602082019050612cc75f830184612ca5565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f612d0f82612ccd565b612d198185612cd7565b9350612d29818560208601612ce7565b612d3281612cf5565b840191505092915050565b5f6020820190508181035f830152612d558184612d05565b905092915050565b5f819050919050565b612d6f81612d5d565b8114612d79575f5ffd5b50565b5f81359050612d8a81612d66565b92915050565b5f60208284031215612da557612da4612c12565b5b5f612db284828501612d7c565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612de482612dbb565b9050919050565b612df481612dda565b82525050565b5f602082019050612e0d5f830184612deb565b92915050565b612e1c81612dda565b8114612e26575f5ffd5b50565b5f81359050612e3781612e13565b92915050565b5f5f60408385031215612e5357612e52612c12565b5b5f612e6085828601612e29565b9250506020612e7185828601612d7c565b9150509250929050565b612e8481612d5d565b82525050565b5f602082019050612e9d5f830184612e7b565b92915050565b5f5f60408385031215612eb957612eb8612c12565b5b5f612ec685828601612d7c565b9250506020612ed785828601612d7c565b9150509250929050565b5f5f5f60608486031215612ef857612ef7612c12565b5b5f612f0586828701612e29565b9350506020612f1686828701612e29565b9250506040612f2786828701612d7c565b9150509250925092565b5f612f3b82612dbb565b9050919050565b612f4b81612f31565b8114612f55575f5ffd5b50565b5f81359050612f6681612f42565b92915050565b5f60208284031215612f8157612f80612c12565b5b5f612f8e84828501612f58565b91505092915050565b5f60208284031215612fac57612fab612c12565b5b5f612fb984828501612e29565b91505092915050565b612fcb81612c9a565b8114612fd5575f5ffd5b50565b5f81359050612fe681612fc2565b92915050565b5f5f6040838503121561300257613001612c12565b5b5f61300f85828601612e29565b925050602061302085828601612fd8565b9150509250929050565b5f5ffd5b5f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61306882612cf5565b810181811067ffffffffffffffff8211171561308757613086613032565b5b80604052505050565b5f613099612c09565b90506130a5828261305f565b919050565b5f67ffffffffffffffff8211156130c4576130c3613032565b5b6130cd82612cf5565b9050602081019050919050565b828183375f83830152505050565b5f6130fa6130f5846130aa565b613090565b9050828152602081018484840111156131165761311561302e565b5b6131218482856130da565b509392505050565b5f82601f83011261313d5761313c61302a565b5b813561314d8482602086016130e8565b91505092915050565b5f5f5f5f6080858703121561316e5761316d612c12565b5b5f61317b87828801612e29565b945050602061318c87828801612e29565b935050604061319d87828801612d7c565b925050606085013567ffffffffffffffff8111156131be576131bd612c16565b5b6131ca87828801613129565b91505092959194509250565b5f5f604083850312156131ec576131eb612c12565b5b5f6131f985828601612e29565b925050602061320a85828601612e29565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061325857607f821691505b60208210810361326b5761326a613214565b5b50919050565b7f536c6970706167652063616e6e6f7420657863656564203130302500000000005f82015250565b5f6132a5601b83612cd7565b91506132b082613271565b602082019050919050565b5f6020820190508181035f8301526132d281613299565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61331082612d5d565b915061331b83612d5d565b925082820261332981612d5d565b915082820484148315176133405761333f6132d9565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61337e82612d5d565b915061338983612d5d565b92508261339957613398613347565b5b828204905092915050565b5f6133ae82612d5d565b91506133b983612d5d565b92508282039050818111156133d1576133d06132d9565b5b92915050565b7f4e6f74206f776e6572206e6f7220617070726f766564000000000000000000005f82015250565b5f61340b601683612cd7565b9150613416826133d7565b602082019050919050565b5f6020820190508181035f830152613438816133ff565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f613473602083612cd7565b915061347e8261343f565b602082019050919050565b5f6020820190508181035f8301526134a081613467565b9050919050565b7f5a65726f206164647265737300000000000000000000000000000000000000005f82015250565b5f6134db600c83612cd7565b91506134e6826134a7565b602082019050919050565b5f6020820190508181035f830152613508816134cf565b9050919050565b7f6f6e6c79206f6e63652063616c6c61626c6500000000000000000000000000005f82015250565b5f613543601283612cd7565b915061354e8261350f565b602082019050919050565b5f6020820190508181035f83015261357081613537565b9050919050565b7f6f6e6c79206f776e6572000000000000000000000000000000000000000000005f82015250565b5f6135ab600a83612cd7565b91506135b682613577565b602082019050919050565b5f6020820190508181035f8301526135d88161359f565b9050919050565b7f5175616e74697479206d757374206265203e20300000000000000000000000005f82015250565b5f613613601483612cd7565b915061361e826135df565b602082019050919050565b5f6020820190508181035f83015261364081613607565b9050919050565b5f61365182612d5d565b915061365c83612d5d565b9250828201905080821115613674576136736132d9565b5b92915050565b7f45786365656473206d617820737570706c7900000000000000000000000000005f82015250565b5f6136ae601283612cd7565b91506136b98261367a565b602082019050919050565b5f6020820190508181035f8301526136db816136a2565b9050919050565b7f496e636f7272656374204554482073656e7400000000000000000000000000005f82015250565b5f613716601283612cd7565b9150613721826136e2565b602082019050919050565b5f6020820190508181035f8301526137438161370a565b9050919050565b5f81905092915050565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f32305f8201527f30302f737667222076696577426f783d2230203020313032342031303234223e602082015250565b5f6137ae60408361374a565b91506137b982613754565b604082019050919050565b7f3c646566733e3c7374796c653e000000000000000000000000000000000000005f82015250565b5f6137f8600d8361374a565b9150613803826137c4565b600d82019050919050565b7f2e62677b66696c6c3a233064306631337d0000000000000000000000000000005f82015250565b5f61384260118361374a565b915061384d8261380e565b601182019050919050565b7f2e747b666f6e743a20363470782073616e732d73657269663b2066696c6c3a235f8201527f6666666666663b20646f6d696e616e742d626173656c696e653a6d6964646c6560208201527f3b20746578742d616e63686f723a6d6964646c657d0000000000000000000000604082015250565b5f6138d860558361374a565b91506138e382613858565b605582019050919050565b7f3c2f7374796c653e3c2f646566733e00000000000000000000000000000000005f82015250565b5f613922600f8361374a565b915061392d826138ee565b600f82019050919050565b7f3c7265637420636c6173733d2262672220783d22302220793d223022207769645f8201527f74683d223130323422206865696768743d2231303234222f3e00000000000000602082015250565b5f61399260398361374a565b915061399d82613938565b603982019050919050565b7f3c7465787420636c6173733d22742220783d223531322220793d22353132223e5f82015250565b5f6139dc60208361374a565b91506139e7826139a8565b602082019050919050565b5f6139fc82612ccd565b613a06818561374a565b9350613a16818560208601612ce7565b80840191505092915050565b7f3c2f746578743e000000000000000000000000000000000000000000000000005f82015250565b5f613a5660078361374a565b9150613a6182613a22565b600782019050919050565b7f3c2f7376673e00000000000000000000000000000000000000000000000000005f82015250565b5f613aa060068361374a565b9150613aab82613a6c565b600682019050919050565b5f613ac0826137a2565b9150613acb826137ec565b9150613ad682613836565b9150613ae1826138cc565b9150613aec82613916565b9150613af782613986565b9150613b02826139d0565b9150613b0e82846139f2565b9150613b1982613a4a565b9150613b2482613a94565b915081905092915050565b7f646174613a696d6167652f7376672b786d6c3b6261736536342c0000000000005f82015250565b5f613b63601a8361374a565b9150613b6e82613b2f565b601a82019050919050565b5f613b8382613b57565b9150613b8f82846139f2565b915081905092915050565b7f7b226e616d65223a22466c79776865656c5354522023000000000000000000005f82015250565b5f613bce60168361374a565b9150613bd982613b9a565b601682019050919050565b7f222c226465736372697074696f6e223a2254686520466c79776865656c204e465f8201527f54222c0000000000000000000000000000000000000000000000000000000000602082015250565b5f613c3e60238361374a565b9150613c4982613be4565b602382019050919050565b7f2261747472696275746573223a5b7b2274726169745f74797065223a2242616c5f8201527f616e6365222c2276616c7565223a000000000000000000000000000000000000602082015250565b5f613cae602e8361374a565b9150613cb982613c54565b602e82019050919050565b7f7d5d2c00000000000000000000000000000000000000000000000000000000005f82015250565b5f613cf860038361374a565b9150613d0382613cc4565b600382019050919050565b7f22696d616765223a2200000000000000000000000000000000000000000000005f82015250565b5f613d4260098361374a565b9150613d4d82613d0e565b600982019050919050565b7f227d0000000000000000000000000000000000000000000000000000000000005f82015250565b5f613d8c60028361374a565b9150613d9782613d58565b600282019050919050565b5f613dac82613bc2565b9150613db882866139f2565b9150613dc382613c32565b9150613dce82613ca2565b9150613dda82856139f2565b9150613de582613cec565b9150613df082613d36565b9150613dfc82846139f2565b9150613e0782613d80565b9150819050949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000005f82015250565b5f613e48601d8361374a565b9150613e5382613e14565b601d82019050919050565b5f613e6882613e3c565b9150613e7482846139f2565b915081905092915050565b7f494e53554646494349454e545f42414c414e43453a20436f6e747261637420685f8201527f6f6c6473206e6f20455448000000000000000000000000000000000000000000602082015250565b5f613ed9602b83612cd7565b9150613ee482613e7f565b604082019050919050565b5f6020820190508181035f830152613f0681613ecd565b9050919050565b7f5377617020616d6f756e7420746f6f20736d616c6c20616674657220666565205f8201527f63616c63756c6174696f6e000000000000000000000000000000000000000000602082015250565b5f613f67602b83612cd7565b9150613f7282613f0d565b604082019050919050565b5f6020820190508181035f830152613f9481613f5b565b9050919050565b7f494e56414c49445f504154483a204f757470757420746f6b656e2063616e6e6f5f8201527f74206265207a65726f0000000000000000000000000000000000000000000000602082015250565b5f613ff5602983612cd7565b915061400082613f9b565b604082019050919050565b5f6020820190508181035f83015261402281613fe9565b9050919050565b7f494e56414c49445f504154483a205573652045544820666f72205745544820735f8201527f7761700000000000000000000000000000000000000000000000000000000000602082015250565b5f614083602383612cd7565b915061408e82614029565b604082019050919050565b5f6020820190508181035f8301526140b081614077565b9050919050565b7f536c6970706167652063616e6e6f7420657863656564203525000000000000005f82015250565b5f6140eb601983612cd7565b91506140f6826140b7565b602082019050919050565b5f6020820190508181035f830152614118816140df565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61417e81612dda565b82525050565b5f61418f8383614175565b60208301905092915050565b5f602082019050919050565b5f6141b18261414c565b6141bb8185614156565b93506141c683614166565b805f5b838110156141f65781516141dd8882614184565b97506141e88361419b565b9250506001810190506141c9565b5085935050505092915050565b5f6040820190506142165f830185612e7b565b818103602083015261422881846141a7565b90509392505050565b5f67ffffffffffffffff82111561424b5761424a613032565b5b602082029050602081019050919050565b5f5ffd5b5f8151905061426e81612d66565b92915050565b5f61428661428184614231565b613090565b905080838252602082019050602084028301858111156142a9576142a861425c565b5b835b818110156142d257806142be8882614260565b8452602084019350506020810190506142ab565b5050509392505050565b5f82601f8301126142f0576142ef61302a565b5b8151614300848260208601614274565b91505092915050565b5f6020828403121561431e5761431d612c12565b5b5f82015167ffffffffffffffff81111561433b5761433a612c16565b5b614347848285016142dc565b91505092915050565b5f6060820190506143635f830186612e7b565b6143706020830185612e7b565b61437d6040830184612e7b565b949350505050565b5f81905092915050565b50565b5f61439d5f83614385565b91506143a88261438f565b5f82019050919050565b5f6143bc82614392565b9150819050919050565b7f466565207472616e7366657220746f206f776e6572206661696c6564000000005f82015250565b5f6143fa601c83612cd7565b9150614405826143c6565b602082019050919050565b5f6020820190508181035f830152614427816143ee565b9050919050565b5f6080820190506144415f830187612e7b565b818103602083015261445381866141a7565b90506144626040830185612deb565b61446f6060830184612e7b565b95945050505050565b7f46656520726566756e6420746f2063616c6c6572206661696c656400000000005f82015250565b5f6144ac601b83612cd7565b91506144b782614478565b602082019050919050565b5f6020820190508181035f8301526144d9816144a0565b9050919050565b5f602082840312156144f5576144f4612c12565b5b5f61450284828501614260565b91505092915050565b7f4e6f7468696e6720746f207769746864726177000000000000000000000000005f82015250565b5f61453f601383612cd7565b915061454a8261450b565b602082019050919050565b5f6020820190508181035f83015261456c81614533565b9050919050565b5f61457d82612d5d565b91505f820361458f5761458e6132d9565b5b600182039050919050565b5f6040820190506145ad5f830185612deb565b6145ba6020830184612e7b565b9392505050565b5f815190506145cf81612fc2565b92915050565b5f602082840312156145ea576145e9612c12565b5b5f6145f7848285016145c1565b91505092915050565b7f546f6b656e207472616e73666572206661696c656400000000000000000000005f82015250565b5f614634601583612cd7565b915061463f82614600565b602082019050919050565b5f6020820190508181035f83015261466181614628565b9050919050565b5f81519050919050565b5f82825260208201905092915050565b5f61468c82614668565b6146968185614672565b93506146a6818560208601612ce7565b6146af81612cf5565b840191505092915050565b5f6080820190506146cd5f830187612deb565b6146da6020830186612deb565b6146e76040830185612e7b565b81810360608301526146f98184614682565b905095945050505050565b5f8151905061471281612c45565b92915050565b5f6020828403121561472d5761472c612c12565b5b5f61473a84828501614704565b91505092915050565b5f61474d82612d5d565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361477f5761477e6132d9565b5b600182019050919050565b5f61479482612d5d565b915061479f83612d5d565b9250826147af576147ae613347565b5b82820690509291505056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220033221ee254387152a1497b54ac67d11a2c02f688d37550ba4ddb2e4d8e984aa64736f6c634300081e0033

Deployed Bytecode

0x6080604052600436106101c5575f3560e01c80636352211e116100f6578063b88d4fde11610094578063d1d2fbf111610063578063d1d2fbf1146105ee578063d96a094a14610604578063e985e9c51461062c578063f6c8d4e814610668576101c6565b8063b88d4fde14610542578063c002d23d1461055e578063c87b56dd14610588578063cc1f2afa146105c4576101c6565b806395d89b41116100d057806395d89b41146104aa578063a0712d68146104d4578063a22cb465146104f0578063ad5c464814610518576101c6565b80636352211e1461040857806370a08231146104445780638da5cb5b14610480576101c6565b806332cb6b0c1161016357806342966c681161013d57806342966c681461037857806351cff8d9146103a05780635c39fcc1146103c85780635d1ae9c1146103f2576101c6565b806332cb6b0c1461030857806332fe7b261461033257806342842e0e1461035c576101c6565b8063095ea7b31161019f578063095ea7b31461026a57806318160ddd146102865780631aaaac12146102b057806323b872dd146102ec576101c6565b806301ffc9a7146101c857806306fdde0314610204578063081812fc1461022e576101c6565b5b005b3480156101d3575f5ffd5b506101ee60048036038101906101e99190612c6f565b6106a4565b6040516101fb9190612cb4565b60405180910390f35b34801561020f575f5ffd5b50610218610735565b6040516102259190612d3d565b60405180910390f35b348015610239575f5ffd5b50610254600480360381019061024f9190612d90565b6107c5565b6040516102619190612dfa565b60405180910390f35b610284600480360381019061027f9190612e3d565b61081e565b005b348015610291575f5ffd5b5061029a61082e565b6040516102a79190612e8a565b60405180910390f35b3480156102bb575f5ffd5b506102d660048036038101906102d19190612ea3565b610879565b6040516102e39190612e8a565b60405180910390f35b61030660048036038101906103019190612ee1565b6108f0565b005b348015610313575f5ffd5b5061031c610b71565b6040516103299190612e8a565b60405180910390f35b34801561033d575f5ffd5b50610346610b77565b6040516103539190612dfa565b60405180910390f35b61037660048036038101906103719190612ee1565b610b9c565b005b348015610383575f5ffd5b5061039e60048036038101906103999190612d90565b610bbb565b005b3480156103ab575f5ffd5b506103c660048036038101906103c19190612f6c565b610ca6565b005b3480156103d3575f5ffd5b506103dc610dea565b6040516103e99190612dfa565b60405180910390f35b3480156103fd575f5ffd5b50610406610e0f565b005b348015610413575f5ffd5b5061042e60048036038101906104299190612d90565b610faa565b60405161043b9190612dfa565b60405180910390f35b34801561044f575f5ffd5b5061046a60048036038101906104659190612f97565b610fbb565b6040516104779190612e8a565b60405180910390f35b34801561048b575f5ffd5b5061049461104f565b6040516104a19190612dfa565b60405180910390f35b3480156104b5575f5ffd5b506104be611074565b6040516104cb9190612d3d565b60405180910390f35b6104ee60048036038101906104e99190612d90565b611104565b005b3480156104fb575f5ffd5b5061051660048036038101906105119190612fec565b611254565b005b348015610523575f5ffd5b5061052c61135a565b6040516105399190612dfa565b60405180910390f35b61055c60048036038101906105579190613156565b61137f565b005b348015610569575f5ffd5b506105726113d0565b60405161057f9190612e8a565b60405180910390f35b348015610593575f5ffd5b506105ae60048036038101906105a99190612d90565b6113da565b6040516105bb9190612d3d565b60405180910390f35b3480156105cf575f5ffd5b506105d86114c2565b6040516105e59190612dfa565b60405180910390f35b3480156105f9575f5ffd5b506106026114e7565b005b34801561060f575f5ffd5b5061062a60048036038101906106259190612d90565b6115b8565b005b348015610637575f5ffd5b50610652600480360381019061064d91906131d6565b611c78565b60405161065f9190612cb4565b60405180910390f35b348015610673575f5ffd5b5061068e60048036038101906106899190612d90565b611d06565b60405161069b9190612e8a565b60405180910390f35b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806106fe57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061072e5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461074490613241565b80601f016020809104026020016040519081016040528092919081815260200182805461077090613241565b80156107bb5780601f10610792576101008083540402835291602001916107bb565b820191905f5260205f20905b81548152906001019060200180831161079e57829003601f168201915b5050505050905090565b5f6107cf82611e44565b6107e4576107e363cf4700e460e01b611ee7565b5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b61082a82826001611eef565b5050565b5f610837612019565b6001545f54030390507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610869612020565b1461087657600854810190505b90565b5f6127108211156108bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108b6906132bb565b60405180910390fd5b5f61271083856108cf9190613306565b6108d99190613374565b905080846108e791906133a4565b91505092915050565b5f6108fa82612047565b90505f8473ffffffffffffffffffffffffffffffffffffffff169050808273ffffffffffffffffffffffffffffffffffffffff16146109445761094363a114810060e01b611ee7565b5b5f5f61094f85612156565b9150915061097b8184610960612179565b73ffffffffffffffffffffffffffffffffffffffff16612180565b6109a6576109908761098b612179565b611c78565b6109a5576109a46359c896be60e01b611ee7565b5b5b6109b38787876001612191565b80156109bd575f82555b60055f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f815460010191905081905550610a8586610a61898988612197565b7c0200000000000000000000000000000000000000000000000000000000176121be565b60045f8781526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000851603610b01575f6001860190505f60045f8381526020019081526020015f205403610aff575f548114610afe578460045f8381526020019081526020015f20819055505b5b505b5f8673ffffffffffffffffffffffffffffffffffffffff1690508581857fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f5fa45f8103610b5a57610b5963ea553b3460e01b611ee7565b5b610b6788888860016121e8565b5050505050505050565b61271081565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610bb683838360405180602001604052805f81525061137f565b505050565b5f610bc582610faa565b90505f610bd061082e565b90503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161480610c125750610c118233611c78565b5b80610c5057503373ffffffffffffffffffffffffffffffffffffffff16610c38846107c5565b73ffffffffffffffffffffffffffffffffffffffff16145b610c8f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c8690613421565b60405180910390fd5b610c98836121ee565b610ca1816121fb565b505050565b600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d35576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d2c90613489565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610da3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d9a906134f1565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166108fc4790811502906040515f60405180830381858888f19350505050158015610de6573d5f5f3e3d5ffd5b5050565b600d5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e9590613489565b60405180910390fd5b5f1515601160149054906101000a900460ff16151514610ef3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eea90613559565b60405180910390fd5b600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f79906135c1565b60405180910390fd5b6001601160146101000a81548160ff021916908315150217905550610fa83360646122f0565b565b5f610fb482612047565b9050919050565b5f5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361100057610fff638f4eb60460e01b611ee7565b5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60606003805461108390613241565b80601f01602080910402602001604051908101604052809291908181526020018280546110af90613241565b80156110fa5780601f106110d1576101008083540402835291602001916110fa565b820191905f5260205f20905b8154815290600101906020018083116110dd57829003601f168201915b5050505050905090565b5f8111611146576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113d90613629565b60405180910390fd5b600281111561118a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118190613629565b60405180910390fd5b6127108161119661230d565b6111a09190613647565b11156111e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d8906136c4565b60405180910390fd5b6103e86111ec61230d565b111561124757655af3107a4000816112049190613306565b341015611246576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161123d9061372c565b60405180910390fd5b5b61125133826122f0565b50565b8060075f611260612179565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611309612179565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161134e9190612cb4565b60405180910390a35050565b600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61138a8484846108f0565b5f8373ffffffffffffffffffffffffffffffffffffffff163b146113ca576113b484848484612354565b6113c9576113c863d1a57ed660e01b611ee7565b5b5b50505050565b655af3107a400081565b60605f5f90505f6113e961082e565b1115611402576113ff6113fa61082e565b611d06565b90505b5f61140c8261247e565b60405160200161141c9190613ab6565b60405160208183030381529060405290505f611437826125d6565b6040516020016114479190613b79565b60405160208183030381529060405290505f6114628661247e565b61146b8561247e565b8360405160200161147e93929190613da2565b6040516020818303038152906040529050611498816125d6565b6040516020016114a89190613e5e565b604051602081830303815290604052945050505050919050565b600b5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611576576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161156d90613489565b60405180910390fd5b5f600c5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b5f600b5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f4790505f8111611623576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161a90613eef565b60405180910390fd5b5f6064605a836116339190613306565b61163d9190613374565b90505f606460098461164f9190613306565b6116599190613374565b90505f606460018561166b9190613306565b6116759190613374565b90505f8390505f81116116bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116b490613f7d565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff160361172b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117229061400b565b60405180910390fd5b600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16036117ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117b190614099565b60405180910390fd5b6101f48711156117ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117f690614101565b60405180910390fd5b5f600267ffffffffffffffff81111561181b5761181a613032565b5b6040519080825280602002602001820160405280156118495781602001602082028036833780820191505090505b509050600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16815f815181106118815761188061411f565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505086816001815181106118d0576118cf61411f565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505f7f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d73ffffffffffffffffffffffffffffffffffffffff1663d06ca61f84846040518363ffffffff1660e01b8152600401611966929190614203565b5f60405180830381865afa158015611980573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906119a89190614309565b90505f816001815181106119bf576119be61411f565b5b602002602001015190505f6119d4828c610879565b90508973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f0fc79ed27e1532430dbab6d8f2375ed04970889569d92361445e379731d31054878585604051611a3793929190614350565b60405180910390a35f603c42611a4d9190613647565b90505f600d5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1689604051611a95906143b2565b5f6040518083038185875af1925050503d805f8114611acf576040519150601f19603f3d011682016040523d82523d5f602084013e611ad4565b606091505b5050905080611b18576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b0f90614410565b60405180910390fd5b5f7f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d73ffffffffffffffffffffffffffffffffffffffff16637ff36ab589868a30886040518663ffffffff1660e01b8152600401611b79949392919061442e565b5f6040518083038185885af1158015611b94573d5f5f3e3d5ffd5b50505050506040513d5f823e3d601f19601f82011682018060405250810190611bbd9190614309565b90505f3373ffffffffffffffffffffffffffffffffffffffff168a604051611be4906143b2565b5f6040518083038185875af1925050503d805f8114611c1e576040519150601f19603f3d011682016040523d82523d5f602084013e611c23565b606091505b5050905080611c67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c5e906144c2565b60405180910390fd5b505050505050505050505050505050565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f5f600b5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611d669190612dfa565b602060405180830381865afa158015611d81573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611da591906144e0565b90505f8482611db49190613374565b90505f8111611df8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611def90614555565b60405180910390fd5b5f6064605a83611e089190613306565b611e129190613374565b90506064861015611e385760648083611e2b9190613306565b611e359190613374565b90505b80945050505050919050565b5f81611e4e612019565b11611ee157611e5b612020565b821115611e8357611e7c60045f8481526020019081526020015f2054612603565b9050611ee2565b5f54821015611ee0575f5b5f60045f8581526020019081526020015f205491508103611eba5782611eb390614573565b9250611e8e565b5f7c01000000000000000000000000000000000000000000000000000000008216149150505b5b5b919050565b805f5260045ffd5b5f611ef983610faa565b9050818015611f3b57508073ffffffffffffffffffffffffffffffffffffffff16611f22612179565b73ffffffffffffffffffffffffffffffffffffffff1614155b15611f6757611f5181611f4c612179565b611c78565b611f6657611f6563cfb3b94260e01b611ee7565b5b5b8360065f8581526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b5f5f905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b5f81612051612019565b116121405760045f8381526020019081526020015f20549050612072612020565b8211156120975761208281612603565b6121515761209663df2d9b4260e01b611ee7565b5b5f8103612118575f5482106120b7576120b663df2d9b4260e01b611ee7565b5b5b60045f836001900393508381526020019081526020015f205490505f810315612113575f7c0100000000000000000000000000000000000000000000000000000000821603156121515761211263df2d9b4260e01b611ee7565b5b6120b8565b5f7c010000000000000000000000000000000000000000000000000000000082160315612151575b61215063df2d9b4260e01b611ee7565b5b919050565b5f5f5f60065f8581526020019081526020015f2090508092508254915050915091565b5f33905090565b5f8382148383141790509392505050565b50505050565b5f5f60e883901c905060e86121ad868684612643565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6121f8815f61264b565b50565b5f600b5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f61222a83611d06565b90505f8273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b815260040161226892919061459a565b6020604051808303815f875af1158015612284573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122a891906145d5565b9050806122ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122e19061464a565b60405180910390fd5b50505050565b612309828260405180602001604052805f815250612897565b5050565b5f612316612019565b5f540390507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612344612020565b1461235157600854810190505b90565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612379612179565b8786866040518563ffffffff1660e01b815260040161239b94939291906146ba565b6020604051808303815f875af19250505080156123d657506040513d601f19601f820116820180604052508101906123d39190614718565b60015b61242b573d805f8114612404576040519150601f19603f3d011682016040523d82523d5f602084013e612409565b606091505b505f8151036124235761242263d1a57ed660e01b611ee7565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60605f82036124c4576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506125d1565b5f8290505f5b5f82146124f35780806124dc90614743565b915050600a826124ec9190613374565b91506124ca565b5f8167ffffffffffffffff81111561250e5761250d613032565b5b6040519080825280601f01601f1916602001820160405280156125405781602001600182028036833780820191505090505b5090505b5f85146125ca57818061255690614573565b925050600a85612566919061478a565b60306125729190613647565b60f81b8183815181106125885761258761411f565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600a856125c39190613374565b9450612544565b8093505050505b919050565b60606125fc826040518060600160405280604081526020016147bb60409139600161290d565b9050919050565b5f7c0100000000000000000000000000000000000000000000000000000000821673ffffffffffffffffffffffffffffffffffffffff8316119050919050565b5f9392505050565b5f61265583612047565b90505f8173ffffffffffffffffffffffffffffffffffffffff1690505f8190505f5f61268087612156565b9150915085156126de576126b28185612697612179565b73ffffffffffffffffffffffffffffffffffffffff16612180565b6126dd576126c7836126c2612179565b611c78565b6126dc576126db6359c896be60e01b611ee7565b5b5b5b6126eb835f896001612191565b80156126f5575f82555b600160806001901b0360055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254019250508190555061279983612756855f89612197565b7c02000000000000000000000000000000000000000000000000000000007c010000000000000000000000000000000000000000000000000000000017176121be565b60045f8981526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000861603612815575f6001880190505f60045f8381526020019081526020015f205403612813575f548114612812578560045f8381526020019081526020015f20819055505b5b505b865f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461287d835f8960016121e8565b60015f815480929190600101919050555050505050505050565b6128a18383612a9c565b5f8373ffffffffffffffffffffffffffffffffffffffff163b14612908575f5f5490505f83820390505b6128dd5f868380600101945086612354565b6128f2576128f163d1a57ed660e01b611ee7565b5b8181106128cb57815f5414612905575f5ffd5b50505b505050565b60605f84510361292d5760405180602001604052805f8152509050612a95565b5f8261295e5760036002865160046129459190613306565b61294f9190613647565b6129599190613374565b612985565b60036002865161296e9190613647565b6129789190613374565b60046129849190613306565b5b90505f8167ffffffffffffffff8111156129a2576129a1613032565b5b6040519080825280601f01601f1916602001820160405280156129d45781602001600182028036833780820191505090505b509050600185016020820187885189016020810180515f82525b82841015612a49576003840193508351603f8160121c168701518653600186019550603f81600c1c168701518653600186019550603f8160061c168701518653600186019550603f81168701518653600186019550506129ee565b8082528915612a895760038c510660018114612a6c5760028114612a7f57612a87565b603d6001870353603d6002870353612a87565b603d60018703535b505b50505050505080925050505b9392505050565b5f5f5490505f8203612ab957612ab863b562e8dd60e01b611ee7565b5b612ac55f848385612191565b612ae383612ad45f865f612197565b612add85612bfa565b176121be565b60045f8381526020019081526020015f2081905550600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505f8373ffffffffffffffffffffffffffffffffffffffff1690505f8103612b7e57612b7d632e07630060e01b611ee7565b5b5f83830190505f839050612b90612020565b600183031115612bab57612baa6381647e3a60e01b611ee7565b5b5b80835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f5fa4818160010191508103612bac57815f81905550505050612bf55f8483856121e8565b505050565b5f6001821460e11b9050919050565b5f604051905090565b5f5ffd5b5f5ffd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612c4e81612c1a565b8114612c58575f5ffd5b50565b5f81359050612c6981612c45565b92915050565b5f60208284031215612c8457612c83612c12565b5b5f612c9184828501612c5b565b91505092915050565b5f8115159050919050565b612cae81612c9a565b82525050565b5f602082019050612cc75f830184612ca5565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f612d0f82612ccd565b612d198185612cd7565b9350612d29818560208601612ce7565b612d3281612cf5565b840191505092915050565b5f6020820190508181035f830152612d558184612d05565b905092915050565b5f819050919050565b612d6f81612d5d565b8114612d79575f5ffd5b50565b5f81359050612d8a81612d66565b92915050565b5f60208284031215612da557612da4612c12565b5b5f612db284828501612d7c565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612de482612dbb565b9050919050565b612df481612dda565b82525050565b5f602082019050612e0d5f830184612deb565b92915050565b612e1c81612dda565b8114612e26575f5ffd5b50565b5f81359050612e3781612e13565b92915050565b5f5f60408385031215612e5357612e52612c12565b5b5f612e6085828601612e29565b9250506020612e7185828601612d7c565b9150509250929050565b612e8481612d5d565b82525050565b5f602082019050612e9d5f830184612e7b565b92915050565b5f5f60408385031215612eb957612eb8612c12565b5b5f612ec685828601612d7c565b9250506020612ed785828601612d7c565b9150509250929050565b5f5f5f60608486031215612ef857612ef7612c12565b5b5f612f0586828701612e29565b9350506020612f1686828701612e29565b9250506040612f2786828701612d7c565b9150509250925092565b5f612f3b82612dbb565b9050919050565b612f4b81612f31565b8114612f55575f5ffd5b50565b5f81359050612f6681612f42565b92915050565b5f60208284031215612f8157612f80612c12565b5b5f612f8e84828501612f58565b91505092915050565b5f60208284031215612fac57612fab612c12565b5b5f612fb984828501612e29565b91505092915050565b612fcb81612c9a565b8114612fd5575f5ffd5b50565b5f81359050612fe681612fc2565b92915050565b5f5f6040838503121561300257613001612c12565b5b5f61300f85828601612e29565b925050602061302085828601612fd8565b9150509250929050565b5f5ffd5b5f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61306882612cf5565b810181811067ffffffffffffffff8211171561308757613086613032565b5b80604052505050565b5f613099612c09565b90506130a5828261305f565b919050565b5f67ffffffffffffffff8211156130c4576130c3613032565b5b6130cd82612cf5565b9050602081019050919050565b828183375f83830152505050565b5f6130fa6130f5846130aa565b613090565b9050828152602081018484840111156131165761311561302e565b5b6131218482856130da565b509392505050565b5f82601f83011261313d5761313c61302a565b5b813561314d8482602086016130e8565b91505092915050565b5f5f5f5f6080858703121561316e5761316d612c12565b5b5f61317b87828801612e29565b945050602061318c87828801612e29565b935050604061319d87828801612d7c565b925050606085013567ffffffffffffffff8111156131be576131bd612c16565b5b6131ca87828801613129565b91505092959194509250565b5f5f604083850312156131ec576131eb612c12565b5b5f6131f985828601612e29565b925050602061320a85828601612e29565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061325857607f821691505b60208210810361326b5761326a613214565b5b50919050565b7f536c6970706167652063616e6e6f7420657863656564203130302500000000005f82015250565b5f6132a5601b83612cd7565b91506132b082613271565b602082019050919050565b5f6020820190508181035f8301526132d281613299565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61331082612d5d565b915061331b83612d5d565b925082820261332981612d5d565b915082820484148315176133405761333f6132d9565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61337e82612d5d565b915061338983612d5d565b92508261339957613398613347565b5b828204905092915050565b5f6133ae82612d5d565b91506133b983612d5d565b92508282039050818111156133d1576133d06132d9565b5b92915050565b7f4e6f74206f776e6572206e6f7220617070726f766564000000000000000000005f82015250565b5f61340b601683612cd7565b9150613416826133d7565b602082019050919050565b5f6020820190508181035f830152613438816133ff565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f613473602083612cd7565b915061347e8261343f565b602082019050919050565b5f6020820190508181035f8301526134a081613467565b9050919050565b7f5a65726f206164647265737300000000000000000000000000000000000000005f82015250565b5f6134db600c83612cd7565b91506134e6826134a7565b602082019050919050565b5f6020820190508181035f830152613508816134cf565b9050919050565b7f6f6e6c79206f6e63652063616c6c61626c6500000000000000000000000000005f82015250565b5f613543601283612cd7565b915061354e8261350f565b602082019050919050565b5f6020820190508181035f83015261357081613537565b9050919050565b7f6f6e6c79206f776e6572000000000000000000000000000000000000000000005f82015250565b5f6135ab600a83612cd7565b91506135b682613577565b602082019050919050565b5f6020820190508181035f8301526135d88161359f565b9050919050565b7f5175616e74697479206d757374206265203e20300000000000000000000000005f82015250565b5f613613601483612cd7565b915061361e826135df565b602082019050919050565b5f6020820190508181035f83015261364081613607565b9050919050565b5f61365182612d5d565b915061365c83612d5d565b9250828201905080821115613674576136736132d9565b5b92915050565b7f45786365656473206d617820737570706c7900000000000000000000000000005f82015250565b5f6136ae601283612cd7565b91506136b98261367a565b602082019050919050565b5f6020820190508181035f8301526136db816136a2565b9050919050565b7f496e636f7272656374204554482073656e7400000000000000000000000000005f82015250565b5f613716601283612cd7565b9150613721826136e2565b602082019050919050565b5f6020820190508181035f8301526137438161370a565b9050919050565b5f81905092915050565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f32305f8201527f30302f737667222076696577426f783d2230203020313032342031303234223e602082015250565b5f6137ae60408361374a565b91506137b982613754565b604082019050919050565b7f3c646566733e3c7374796c653e000000000000000000000000000000000000005f82015250565b5f6137f8600d8361374a565b9150613803826137c4565b600d82019050919050565b7f2e62677b66696c6c3a233064306631337d0000000000000000000000000000005f82015250565b5f61384260118361374a565b915061384d8261380e565b601182019050919050565b7f2e747b666f6e743a20363470782073616e732d73657269663b2066696c6c3a235f8201527f6666666666663b20646f6d696e616e742d626173656c696e653a6d6964646c6560208201527f3b20746578742d616e63686f723a6d6964646c657d0000000000000000000000604082015250565b5f6138d860558361374a565b91506138e382613858565b605582019050919050565b7f3c2f7374796c653e3c2f646566733e00000000000000000000000000000000005f82015250565b5f613922600f8361374a565b915061392d826138ee565b600f82019050919050565b7f3c7265637420636c6173733d2262672220783d22302220793d223022207769645f8201527f74683d223130323422206865696768743d2231303234222f3e00000000000000602082015250565b5f61399260398361374a565b915061399d82613938565b603982019050919050565b7f3c7465787420636c6173733d22742220783d223531322220793d22353132223e5f82015250565b5f6139dc60208361374a565b91506139e7826139a8565b602082019050919050565b5f6139fc82612ccd565b613a06818561374a565b9350613a16818560208601612ce7565b80840191505092915050565b7f3c2f746578743e000000000000000000000000000000000000000000000000005f82015250565b5f613a5660078361374a565b9150613a6182613a22565b600782019050919050565b7f3c2f7376673e00000000000000000000000000000000000000000000000000005f82015250565b5f613aa060068361374a565b9150613aab82613a6c565b600682019050919050565b5f613ac0826137a2565b9150613acb826137ec565b9150613ad682613836565b9150613ae1826138cc565b9150613aec82613916565b9150613af782613986565b9150613b02826139d0565b9150613b0e82846139f2565b9150613b1982613a4a565b9150613b2482613a94565b915081905092915050565b7f646174613a696d6167652f7376672b786d6c3b6261736536342c0000000000005f82015250565b5f613b63601a8361374a565b9150613b6e82613b2f565b601a82019050919050565b5f613b8382613b57565b9150613b8f82846139f2565b915081905092915050565b7f7b226e616d65223a22466c79776865656c5354522023000000000000000000005f82015250565b5f613bce60168361374a565b9150613bd982613b9a565b601682019050919050565b7f222c226465736372697074696f6e223a2254686520466c79776865656c204e465f8201527f54222c0000000000000000000000000000000000000000000000000000000000602082015250565b5f613c3e60238361374a565b9150613c4982613be4565b602382019050919050565b7f2261747472696275746573223a5b7b2274726169745f74797065223a2242616c5f8201527f616e6365222c2276616c7565223a000000000000000000000000000000000000602082015250565b5f613cae602e8361374a565b9150613cb982613c54565b602e82019050919050565b7f7d5d2c00000000000000000000000000000000000000000000000000000000005f82015250565b5f613cf860038361374a565b9150613d0382613cc4565b600382019050919050565b7f22696d616765223a2200000000000000000000000000000000000000000000005f82015250565b5f613d4260098361374a565b9150613d4d82613d0e565b600982019050919050565b7f227d0000000000000000000000000000000000000000000000000000000000005f82015250565b5f613d8c60028361374a565b9150613d9782613d58565b600282019050919050565b5f613dac82613bc2565b9150613db882866139f2565b9150613dc382613c32565b9150613dce82613ca2565b9150613dda82856139f2565b9150613de582613cec565b9150613df082613d36565b9150613dfc82846139f2565b9150613e0782613d80565b9150819050949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000005f82015250565b5f613e48601d8361374a565b9150613e5382613e14565b601d82019050919050565b5f613e6882613e3c565b9150613e7482846139f2565b915081905092915050565b7f494e53554646494349454e545f42414c414e43453a20436f6e747261637420685f8201527f6f6c6473206e6f20455448000000000000000000000000000000000000000000602082015250565b5f613ed9602b83612cd7565b9150613ee482613e7f565b604082019050919050565b5f6020820190508181035f830152613f0681613ecd565b9050919050565b7f5377617020616d6f756e7420746f6f20736d616c6c20616674657220666565205f8201527f63616c63756c6174696f6e000000000000000000000000000000000000000000602082015250565b5f613f67602b83612cd7565b9150613f7282613f0d565b604082019050919050565b5f6020820190508181035f830152613f9481613f5b565b9050919050565b7f494e56414c49445f504154483a204f757470757420746f6b656e2063616e6e6f5f8201527f74206265207a65726f0000000000000000000000000000000000000000000000602082015250565b5f613ff5602983612cd7565b915061400082613f9b565b604082019050919050565b5f6020820190508181035f83015261402281613fe9565b9050919050565b7f494e56414c49445f504154483a205573652045544820666f72205745544820735f8201527f7761700000000000000000000000000000000000000000000000000000000000602082015250565b5f614083602383612cd7565b915061408e82614029565b604082019050919050565b5f6020820190508181035f8301526140b081614077565b9050919050565b7f536c6970706167652063616e6e6f7420657863656564203525000000000000005f82015250565b5f6140eb601983612cd7565b91506140f6826140b7565b602082019050919050565b5f6020820190508181035f830152614118816140df565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61417e81612dda565b82525050565b5f61418f8383614175565b60208301905092915050565b5f602082019050919050565b5f6141b18261414c565b6141bb8185614156565b93506141c683614166565b805f5b838110156141f65781516141dd8882614184565b97506141e88361419b565b9250506001810190506141c9565b5085935050505092915050565b5f6040820190506142165f830185612e7b565b818103602083015261422881846141a7565b90509392505050565b5f67ffffffffffffffff82111561424b5761424a613032565b5b602082029050602081019050919050565b5f5ffd5b5f8151905061426e81612d66565b92915050565b5f61428661428184614231565b613090565b905080838252602082019050602084028301858111156142a9576142a861425c565b5b835b818110156142d257806142be8882614260565b8452602084019350506020810190506142ab565b5050509392505050565b5f82601f8301126142f0576142ef61302a565b5b8151614300848260208601614274565b91505092915050565b5f6020828403121561431e5761431d612c12565b5b5f82015167ffffffffffffffff81111561433b5761433a612c16565b5b614347848285016142dc565b91505092915050565b5f6060820190506143635f830186612e7b565b6143706020830185612e7b565b61437d6040830184612e7b565b949350505050565b5f81905092915050565b50565b5f61439d5f83614385565b91506143a88261438f565b5f82019050919050565b5f6143bc82614392565b9150819050919050565b7f466565207472616e7366657220746f206f776e6572206661696c6564000000005f82015250565b5f6143fa601c83612cd7565b9150614405826143c6565b602082019050919050565b5f6020820190508181035f830152614427816143ee565b9050919050565b5f6080820190506144415f830187612e7b565b818103602083015261445381866141a7565b90506144626040830185612deb565b61446f6060830184612e7b565b95945050505050565b7f46656520726566756e6420746f2063616c6c6572206661696c656400000000005f82015250565b5f6144ac601b83612cd7565b91506144b782614478565b602082019050919050565b5f6020820190508181035f8301526144d9816144a0565b9050919050565b5f602082840312156144f5576144f4612c12565b5b5f61450284828501614260565b91505092915050565b7f4e6f7468696e6720746f207769746864726177000000000000000000000000005f82015250565b5f61453f601383612cd7565b915061454a8261450b565b602082019050919050565b5f6020820190508181035f83015261456c81614533565b9050919050565b5f61457d82612d5d565b91505f820361458f5761458e6132d9565b5b600182039050919050565b5f6040820190506145ad5f830185612deb565b6145ba6020830184612e7b565b9392505050565b5f815190506145cf81612fc2565b92915050565b5f602082840312156145ea576145e9612c12565b5b5f6145f7848285016145c1565b91505092915050565b7f546f6b656e207472616e73666572206661696c656400000000000000000000005f82015250565b5f614634601583612cd7565b915061463f82614600565b602082019050919050565b5f6020820190508181035f83015261466181614628565b9050919050565b5f81519050919050565b5f82825260208201905092915050565b5f61468c82614668565b6146968185614672565b93506146a6818560208601612ce7565b6146af81612cf5565b840191505092915050565b5f6080820190506146cd5f830187612deb565b6146da6020830186612deb565b6146e76040830185612e7b565b81810360608301526146f98184614682565b905095945050505050565b5f8151905061471281612c45565b92915050565b5f6020828403121561472d5761472c612c12565b5b5f61473a84828501614704565b91505092915050565b5f61474d82612d5d565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361477f5761477e6132d9565b5b600182019050919050565b5f61479482612d5d565b915061479f83612d5d565b9250826147af576147ae613347565b5b82820690509291505056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220033221ee254387152a1497b54ac67d11a2c02f688d37550ba4ddb2e4d8e984aa64736f6c634300081e0033

Deployed Bytecode Sourcemap

82696:4408:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21329:639;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22231:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;29516:227;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;29233:124;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;17433:573;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77731:586;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33510:3344;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;82773:42;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76011:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;36950:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;84014:366;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;84607:162;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76217:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;84973:211;;;;;;;;;;;;;:::i;:::-;;23633:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;19157:242;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76190:20;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22407:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83415:424;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;30083:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76039:19;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37741:416;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;82822:49;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;85192:1632;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76065:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;84777:77;;;;;;;;;;;;;:::i;:::-;;78779:3036;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;30474:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81823:432;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21329:639;21414:4;21753:10;21738:25;;:11;:25;;;;:102;;;;21830:10;21815:25;;:11;:25;;;;21738:102;:179;;;;21907:10;21892:25;;:11;:25;;;;21738:179;21718:199;;21329:639;;;:::o;22231:100::-;22285:13;22318:5;22311:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22231:100;:::o;29516:227::-;29592:7;29617:16;29625:7;29617;:16::i;:::-;29612:73;;29635:50;29643:41;;;29635:7;:50::i;:::-;29612:73;29705:15;:24;29721:7;29705:24;;;;;;;;;;;:30;;;;;;;;;;;;29698:37;;29516:227;;;:::o;29233:124::-;29322:27;29331:2;29335:7;29344:4;29322:8;:27::i;:::-;29233:124;;:::o;17433:573::-;17494:14;17892:15;:13;:15::i;:::-;17877:12;;17861:13;;:28;:46;17852:55;;17947:17;17926;:15;:17::i;:::-;:38;17922:65;;17976:11;;17966:21;;;;17922:65;17433:573;:::o;77731:586::-;77858:20;77949:5;77934:11;:20;;77926:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;78101:18;78155:5;78140:11;78123:14;:28;;;;:::i;:::-;78122:38;;;;:::i;:::-;78101:59;;78299:10;78282:14;:27;;;;:::i;:::-;78267:42;;77886:431;77731:586;;;;:::o;33510:3344::-;33652:27;33682;33701:7;33682:18;:27::i;:::-;33652:57;;33720:18;33749:4;33720:34;;;;33803:10;33779:19;33771:42;;;33767:92;;33815:44;33823:35;;;33815:7;:44::i;:::-;33767:92;33873:27;33902:28;33934:33;33959:7;33934:24;:33::i;:::-;33872:95;;;;34067:88;34092:20;34114:10;34134:19;:17;:19::i;:::-;34067:88;;:24;:88::i;:::-;34062:209;;34175:43;34192:4;34198:19;:17;:19::i;:::-;34175:16;:43::i;:::-;34170:101;;34220:51;34228:42;;;34220:7;:51::i;:::-;34170:101;34062:209;34284:43;34306:4;34312:2;34316:7;34325:1;34284:21;:43::i;:::-;34367:20;34364:140;;;34435:1;34414:19;34407:30;34364:140;34884:18;:24;34903:4;34884:24;;;;;;;;;;;;;;;;34882:26;;;;;;;;;;;;34953:18;:22;34972:2;34953:22;;;;;;;;;;;;;;;;34951:24;;;;;;;;;;;35275:146;35312:2;35361:45;35376:4;35382:2;35386:19;35361:14;:45::i;:::-;12973:8;35333:73;35275:18;:146::i;:::-;35246:17;:26;35264:7;35246:26;;;;;;;;;;;:175;;;;35600:1;12973:8;35541:19;:47;:61;35537:645;;35623:19;35655:1;35645:7;:11;35623:33;;35820:1;35778:17;:30;35796:11;35778:30;;;;;;;;;;;;:44;35774:393;;35925:13;;35910:11;:28;35906:242;;36105:19;36072:17;:30;36090:11;36072:30;;;;;;;;;;;:52;;;;35906:242;35774:393;35604:578;35537:645;36290:16;36317:2;36290:30;;;;36667:7;36631:8;36591:10;36533:25;36478:1;36421;36398:305;36748:1;36728:8;:22;36724:67;;36752:39;36760:30;;;36752:7;:39::i;:::-;36724:67;36804:42;36825:4;36831:2;36835:7;36844:1;36804:20;:42::i;:::-;33641:3213;;;;;33510:3344;;;:::o;82773:42::-;82810:5;82773:42;:::o;76011:21::-;;;;;;;;;;;;;:::o;36950:193::-;37096:39;37113:4;37119:2;37123:7;37096:39;;;;;;;;;;;;:16;:39::i;:::-;36950:193;;;:::o;84014:366::-;84065:13;84081:16;84089:7;84081;:16::i;:::-;84065:32;;84108:14;84125:13;:11;:13::i;:::-;84108:30;;84178:10;84171:17;;:5;:17;;;:56;;;;84192:35;84209:5;84216:10;84192:16;:35::i;:::-;84171:56;:94;;;;84255:10;84231:34;;:20;84243:7;84231:11;:20::i;:::-;:34;;;84171:94;84149:166;;;;;;;;;;;;:::i;:::-;;;;;;;;;84326:14;84332:7;84326:5;:14::i;:::-;84351:21;84365:6;84351:13;:21::i;:::-;84054:326;;84014:366;:::o;84607:162::-;77176:5;;;;;;;;;;;77162:19;;:10;:19;;;77154:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;84697:1:::1;84683:16;;:2;:16;;::::0;84675:41:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;84727:2;:11;;:34;84739:21;84727:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84607:162:::0;:::o;76217:24::-;;;;;;;;;;;;;:::o;84973:211::-;77176:5;;;;;;;;;;;77162:19;;:10;:19;;;77154:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;85040:5:::1;85034:11;;:4;;;;;;;;;;;:11;;;85026:42;;;;;;;;;;;;:::i;:::-;;;;;;;;;85099:5;;;;;;;;;;;85087:17;;:10;:17;;;85079:40;;;;;;;;;;;;:::i;:::-;;;;;;;;;85135:4;85130;;:9;;;;;;;;;;;;;;;;;;85150:26;85160:10;85172:3;85150:9;:26::i;:::-;84973:211::o:0;23633:152::-;23705:7;23748:27;23767:7;23748:18;:27::i;:::-;23725:52;;23633:152;;;:::o;19157:242::-;19229:7;19270:1;19253:19;;:5;:19;;;19249:69;;19274:44;19282:35;;;19274:7;:44::i;:::-;19249:69;11917:13;19336:18;:25;19355:5;19336:25;;;;;;;;;;;;;;;;:55;19329:62;;19157:242;;;:::o;76190:20::-;;;;;;;;;;;;;:::o;22407:104::-;22463:13;22496:7;22489:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22407:104;:::o;83415:424::-;83494:1;83483:8;:12;83475:45;;;;;;;;;;;;:::i;:::-;;;;;;;;;83551:1;83539:8;:13;;83531:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;82810:5;83613:8;83596:14;:12;:14::i;:::-;:25;;;;:::i;:::-;:41;;83588:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;83691:4;83676:14;:12;:14::i;:::-;:19;83673:115;;;82859:12;83732:8;:21;;;;:::i;:::-;83719:9;:34;;83711:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;83673:115;83800:31;83810:10;83822:8;83800:9;:31::i;:::-;83415:424;:::o;30083:234::-;30230:8;30178:18;:39;30197:19;:17;:19::i;:::-;30178:39;;;;;;;;;;;;;;;:49;30218:8;30178:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;30290:8;30254:55;;30269:19;:17;:19::i;:::-;30254:55;;;30300:8;30254:55;;;;;;:::i;:::-;;;;;;;;30083:234;;:::o;76039:19::-;;;;;;;;;;;;;:::o;37741:416::-;37916:31;37929:4;37935:2;37939:7;37916:12;:31::i;:::-;37980:1;37962:2;:14;;;:19;37958:192;;38001:56;38032:4;38038:2;38042:7;38051:5;38001:30;:56::i;:::-;37996:154;;38078:56;38086:47;;;38078:7;:56::i;:::-;37996:154;37958:192;37741:416;;;;:::o;82822:49::-;82859:12;82822:49;:::o;85192:1632::-;85257:13;85285:15;85303:1;85285:19;;85332:1;85318:13;:11;:13::i;:::-;:15;85315:83;;;85359:27;85372:13;:11;:13::i;:::-;85359:12;:27::i;:::-;85349:37;;85315:83;85473:17;86019:18;:7;:16;:18::i;:::-;85514:597;;;;;;;;:::i;:::-;;;;;;;;;;;;;85473:649;;86135:23;86264:25;86284:3;86264:13;:25::i;:::-;86182:122;;;;;;;;:::i;:::-;;;;;;;;;;;;;86135:180;;86354:17;86431:18;:7;:16;:18::i;:::-;86566;:7;:16;:18::i;:::-;86619:9;86374:271;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;86354:291;;86771:19;86785:4;86771:13;:19::i;:::-;86686:119;;;;;;;;:::i;:::-;;;;;;;;;;;;;86658:158;;;;;;85192:1632;;;:::o;76065:21::-;;;;;;;;;;;;;:::o;84777:77::-;77176:5;;;;;;;;;;;77162:19;;:10;:19;;;77154:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;84844:1:::1;84828:5;;:18;;;;;;;;;;;;;;;;;;84777:77::o:0;78779:3036::-;78858:19;78880:6;;;;;;;;;;;78858:28;;78897:16;78916:21;78897:40;;78967:1;78956:8;:12;78948:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;79209:18;79248:3;79242:2;79231:8;:13;;;;:::i;:::-;79230:21;;;;:::i;:::-;79209:42;;79262:16;79298:3;79293:1;79282:8;:12;;;;:::i;:::-;79281:20;;;;:::i;:::-;79262:39;;79312:20;79352:3;79347:1;79336:8;:12;;;;:::i;:::-;79335:20;;;;:::i;:::-;79312:43;;79435:16;79454:10;79435:29;;79540:1;79529:8;:12;79521:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;79631:1;79608:25;;:11;:25;;;79600:79;;;;;;;;;;;;:::i;:::-;;;;;;;;;79713:4;;;;;;;;;;;79698:19;;:11;:19;;;79690:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;79791:3;79776:11;:18;;79768:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;79909:21;79947:1;79933:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79909:40;;79970:4;;;;;;;;;;;79960;79965:1;79960:7;;;;;;;;:::i;:::-;;;;;;;:14;;;;;;;;;;;79996:11;79986:4;79991:1;79986:7;;;;;;;;:::i;:::-;;;;;;;:21;;;;;;;;;;;80083:32;80118:13;:27;;;80146:8;80156:4;80118:43;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;80083:78;;80172:22;80197:15;80213:1;80197:18;;;;;;;;:::i;:::-;;;;;;;;80172:43;;80290:20;80313:50;80335:14;80351:11;80313:21;:50::i;:::-;80290:73;;80488:11;80436:156;;80462:10;80436:156;;;80515:8;80539:14;80569:12;80436:156;;;;;;;;:::i;:::-;;;;;;;;80697:16;80734:2;80716:15;:20;;;;:::i;:::-;80697:39;;80879:17;80910:9;;;;;;;;;;;80902:23;;80933:8;80902:44;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80878:68;;;80965:12;80957:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;81198:24;81225:13;:35;;;81268:8;81292:12;81353:4;81410;81485:8;81225:285;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81198:312;;81600:18;81632:10;81624:24;;81656:12;81624:49;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81599:74;;;81692:13;81684:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;78837:2978;;;;;;;;;;;;;;78779:3036;:::o;30474:164::-;30571:4;30595:18;:25;30614:5;30595:25;;;;;;;;;;;;;;;:35;30621:8;30595:35;;;;;;;;;;;;;;;;;;;;;;;;;30588:42;;30474:164;;;;:::o;81823:432::-;81881:7;81898:12;81920:6;;;;;;;;;;;81898:29;;81936:23;81962:5;:15;;;81986:4;81962:30;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81936:56;;82001:14;82037:6;82018:15;:25;;;;:::i;:::-;82001:42;;82073:1;82064:6;:10;82056:42;;;;;;;;;;;;:::i;:::-;;;;;;;;;82109:18;82144:3;82139:2;82130:6;:11;;;;:::i;:::-;:17;;;;:::i;:::-;82109:38;;82166:3;82159:6;:10;82156:66;;;82209:3;82203;82194:6;:12;;;;:::i;:::-;:18;;;;:::i;:::-;82181:31;;82156:66;82237:10;82230:17;;;;;;81823:432;;;:::o;30896:493::-;30961:11;31008:7;30989:15;:13;:15::i;:::-;:26;30985:397;;31046:17;:15;:17::i;:::-;31036:7;:27;31032:90;;;31072:50;31095:17;:26;31113:7;31095:26;;;;;;;;;;;;31072:22;:50::i;:::-;31065:57;;;;31032:90;31153:13;;31143:7;:23;31139:232;;;31187:14;31220:69;31276:1;31237:17;:26;31255:7;31237:26;;;;;;;;;;;;31228:35;;;31227:51;31220:69;;31280:9;;;;:::i;:::-;;;31220:69;;;31353:1;12693:8;31317:6;:24;:38;31308:47;;31168:203;31139:232;30985:397;30896:493;;;;:::o;74170:165::-;74271:13;74265:4;74258:27;74312:4;74306;74299:18;59608:474;59737:13;59753:16;59761:7;59753;:16::i;:::-;59737:32;;59786:13;:45;;;;;59826:5;59803:28;;:19;:17;:19::i;:::-;:28;;;;59786:45;59782:201;;;59851:44;59868:5;59875:19;:17;:19::i;:::-;59851:16;:44::i;:::-;59846:137;;59916:51;59924:42;;;59916:7;:51::i;:::-;59846:137;59782:201;60028:2;59995:15;:24;60011:7;59995:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;60066:7;60062:2;60046:28;;60055:5;60046:28;;;;;;;;;;;;59726:356;59608:474;;;:::o;87008:93::-;87065:7;87092:1;87085:8;;87008:93;:::o;16931:110::-;16989:7;17016:17;17009:24;;16931:110;:::o;25127:2249::-;25194:14;25244:7;25225:15;:13;:15::i;:::-;:26;25221:2090;;25277:17;:26;25295:7;25277:26;;;;;;;;;;;;25268:35;;25334:17;:15;:17::i;:::-;25324:7;:27;25320:183;;;25376:30;25399:6;25376:22;:30::i;:::-;25408:13;25372:49;25440:47;25448:38;;;25440:7;:47::i;:::-;25320:183;25622:1;25604:6;:20;25600:1319;;25660:13;;25649:7;:24;25645:77;;25675:47;25683:38;;;25675:7;:47::i;:::-;25645:77;26279:625;26357:17;:28;26375:9;;;;;;;26357:28;;;;;;;;;;;;26348:37;;26453:1;26435:6;:20;26431:34;26457:8;26431:34;26528:1;12693:8;26492:6;:24;:38;26488:57;26532:13;26488:57;26837:47;26845:38;;;26837:7;:47::i;:::-;26279:625;;;25600:1319;27282:1;12693:8;27246:6;:24;:38;27242:57;27286:13;27242:57;25221:2090;27321:47;27329:38;;;27321:7;:47::i;:::-;25127:2249;;;;:::o;32383:507::-;32483:27;32512:28;32558:38;32599:15;:24;32615:7;32599:24;;;;;;;;;;;32558:65;;32790:18;32767:41;;32852:19;32846:26;32822:50;;32752:131;32383:507;;;:::o;72151:105::-;72211:7;72238:10;72231:17;;72151:105;:::o;31929:321::-;32095:11;32210:20;32193:15;32190:41;32176:11;32159:15;32156:32;32153:79;32143:89;;31929:321;;;;;:::o;46085:159::-;;;;;:::o;70507:311::-;70642:7;70662:16;13097:3;70688:19;:41;;70662:68;;13097:3;70756:31;70767:4;70773:2;70777:9;70756:10;:31::i;:::-;70748:40;;:62;;70741:69;;;70507:311;;;;;:::o;27924:450::-;28004:14;28172:16;28165:5;28161:28;28152:37;;28349:5;28335:11;28310:23;28306:41;28303:52;28296:5;28293:63;28283:73;;27924:450;;;;:::o;46909:158::-;;;;;:::o;60349:89::-;60409:21;60415:7;60424:5;60409;:21::i;:::-;60349:89;:::o;82265:255::-;82321:12;82343:6;;;;;;;;;;;82321:29;;82359:18;82380:20;82393:6;82380:12;:20::i;:::-;82359:41;;82409:12;82424:5;:14;;;82439:10;82451;82424:38;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;82409:53;;82479:7;82471:41;;;;;;;;;;;;:::i;:::-;;;;;;;;;82312:208;;;82265:255;:::o;54826:112::-;54903:27;54913:2;54917:8;54903:27;;;;;;;;;;;;:9;:27::i;:::-;54826:112;;:::o;18104:385::-;18159:14;18375:15;:13;:15::i;:::-;18359:13;;:31;18350:40;;18430:17;18409;:15;:17::i;:::-;:38;18405:65;;18459:11;;18449:21;;;;18405:65;18104:385;:::o;47507:700::-;47670:4;47716:2;47691:45;;;47737:19;:17;:19::i;:::-;47758:4;47764:7;47773:5;47691:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;47687:513;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47999:1;47974:6;:13;:27;47970:124;;48022:56;48030:47;;;48022:7;:56::i;:::-;47970:124;48166:6;48160:13;48151:6;48147:2;48143:15;48136:38;47687:513;47860:54;;;47850:64;;;:6;:64;;;;47843:71;;;47507:700;;;;;;:::o;80:459::-;136:13;175:1;166:5;:10;162:26;;178:10;;;;;;;;;;;;;;;;;;;;;162:26;199:12;214:5;199:20;;230:14;255:43;270:1;262:4;:9;255:43;;275:8;;;;;:::i;:::-;;;;293:2;285:10;;;;;:::i;:::-;;;255:43;;;308:16;337:6;327:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;308:36;;355:148;371:1;362:5;:10;355:148;;389:8;;;;;:::i;:::-;;;;460:2;452:5;:10;;;;:::i;:::-;439:2;:24;;;;:::i;:::-;426:39;;412:3;416:6;412:11;;;;;;;;:::i;:::-;;;;;:53;;;;;;;;;;;489:2;480:11;;;;;:::i;:::-;;;355:148;;;527:3;513:18;;;;;80:459;;;;:::o;87580:126::-;87638:13;87671:27;87679:4;87685:6;;;;;;;;;;;;;;;;;87693:4;87671:7;:27::i;:::-;87664:34;;87580:126;;;:::o;31485:335::-;31555:11;31785:15;31777:6;31773:28;31754:16;31746:6;31742:29;31739:63;31729:73;;31485:335;;;:::o;70208:147::-;70345:6;70208:147;;;;;:::o;60667:3127::-;60747:27;60777;60796:7;60777:18;:27::i;:::-;60747:57;;60817:18;60846:19;60817:49;;;;60877:12;60908:10;60877:43;;60934:27;60963:28;60995:33;61020:7;60995:24;:33::i;:::-;60933:95;;;;61045:13;61041:345;;;61166:88;61191:20;61213:10;61233:19;:17;:19::i;:::-;61166:88;;:24;:88::i;:::-;61161:213;;61278:43;61295:4;61301:19;:17;:19::i;:::-;61278:16;:43::i;:::-;61273:101;;61323:51;61331:42;;;61323:7;:51::i;:::-;61273:101;61161:213;61041:345;61398:51;61420:4;61434:1;61438:7;61447:1;61398:21;:51::i;:::-;61489:20;61486:140;;;61557:1;61536:19;61529:30;61486:140;62287:1;12182:3;62257:1;:26;;62256:32;62228:18;:24;62247:4;62228:24;;;;;;;;;;;;;;;;:60;;;;;;;;;;;62555:176;62592:4;62663:53;62678:4;62692:1;62696:19;62663:14;:53::i;:::-;12973:8;12693;62616:43;62615:101;62555:18;:176::i;:::-;62526:17;:26;62544:7;62526:26;;;;;;;;;;;:205;;;;62910:1;12973:8;62851:19;:47;:61;62847:645;;62933:19;62965:1;62955:7;:11;62933:33;;63130:1;63088:17;:30;63106:11;63088:30;;;;;;;;;;;;:44;63084:393;;63235:13;;63220:11;:28;63216:242;;63415:19;63382:17;:30;63400:11;63382:30;;;;;;;;;;;:52;;;;63216:242;63084:393;62914:578;62847:645;63547:7;63543:1;63520:35;;63529:4;63520:35;;;;;;;;;;;;63566:50;63587:4;63601:1;63605:7;63614:1;63566:20;:50::i;:::-;63761:12;;:14;;;;;;;;;;;;;60736:3058;;;;;60667:3127;;:::o;53955:787::-;54086:19;54092:2;54096:8;54086:5;:19::i;:::-;54165:1;54147:2;:14;;;:19;54143:581;;54187:11;54201:13;;54187:27;;54233:13;54255:8;54249:3;:14;54233:30;;54282:242;54313:62;54352:1;54356:2;54360:7;;;;;;54369:5;54313:30;:62::i;:::-;54308:176;;54404:56;54412:47;;;54404:7;:56::i;:::-;54308:176;54519:3;54511:5;:11;54282:242;;54695:3;54678:13;;:20;54674:34;;54700:8;;;54674:34;54168:556;;54143:581;53955:787;;;:::o;88118:4077::-;88215:13;88467:1;88452:4;:11;:16;88448:31;;88470:9;;;;;;;;;;;;;;;;88448:31;89432:20;89455:11;:69;;89523:1;89518;89504:4;:11;89500:1;:15;;;;:::i;:::-;:19;;;;:::i;:::-;89499:25;;;;:::i;:::-;89455:69;;;89494:1;89489;89475:4;:11;:15;;;;:::i;:::-;89474:21;;;;:::i;:::-;89469:1;:27;;;;:::i;:::-;89455:69;89432:92;;89537:20;89571:12;89560:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89537:47;;89736:1;89729:5;89725:13;89840:4;89832:6;89828:17;89874:4;89922;89916:11;89910:4;89906:22;90174:4;90166:6;90162:17;90217:8;90211:15;90257:4;90247:8;90240:22;90332:1254;90351:6;90342:7;90339:19;90332:1254;;;90441:1;90432:7;90428:15;90417:26;;90480:7;90474:14;91076:4;91068:5;91064:2;91060:14;91056:25;91046:8;91042:40;91036:47;91025:9;91017:67;91130:1;91119:9;91115:17;91102:30;;91222:4;91214:5;91210:2;91206:14;91202:25;91192:8;91188:40;91182:47;91171:9;91163:67;91276:1;91265:9;91261:17;91248:30;;91367:4;91359:5;91356:1;91352:13;91348:24;91338:8;91334:39;91328:46;91317:9;91309:66;91421:1;91410:9;91406:17;91393:30;;91504:4;91497:5;91493:16;91483:8;91479:31;91473:38;91462:9;91454:58;91558:1;91547:9;91543:17;91530:30;;90362:1224;90332:1254;;;91667:10;91657:8;91650:28;91697:11;91694:457;;;91882:1;91875:4;91869:11;91865:19;91907:1;91902:135;;;;92060:1;92055:81;;;;91858:278;;91902:135;91959:4;91955:1;91944:9;91940:17;91932:32;92013:4;92009:1;91998:9;91994:17;91986:32;91902:135;;92055:81;92112:4;92108:1;92097:9;92093:17;92085:32;91858:278;;91694:457;89622:2540;;;;;;92181:6;92174:13;;;;88118:4077;;;;;;:::o;48669:2384::-;48742:20;48765:13;;48742:36;;48813:1;48793:8;:22;48789:62;;48817:34;48825:25;;;48817:7;:34::i;:::-;48789:62;48864:61;48894:1;48898:2;48902:12;48916:8;48864:21;:61::i;:::-;49398:139;49435:2;49489:33;49512:1;49516:2;49520:1;49489:14;:33::i;:::-;49456:30;49477:8;49456:20;:30::i;:::-;:66;49398:18;:139::i;:::-;49364:17;:31;49382:12;49364:31;;;;;;;;;;;:173;;;;49824:1;12055:2;49794:1;:26;;49793:32;49781:8;:45;49755:18;:22;49774:2;49755:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;49932:16;49959:2;49932:30;;;;50003:1;49983:8;:22;49979:63;;50007:35;50015:26;;;50007:7;:35::i;:::-;49979:63;50059:11;50088:8;50073:12;:23;50059:37;;50111:15;50129:12;50111:30;;50172:17;:15;:17::i;:::-;50168:1;50162:3;:7;:27;50158:77;;;50191:44;50199:35;;;50191:7;:44::i;:::-;50158:77;50252:676;50671:7;50627:8;50582:1;50516:25;50453:1;50388;50357:358;50923:3;50910:9;;;;;;:16;50252:676;;50960:3;50944:13;:19;;;;49113:1862;;;50985:60;51014:1;51018:2;51022:12;51036:8;50985:20;:60::i;:::-;48731:2322;48669:2384;;:::o;28476:324::-;28546:14;28779:1;28769:8;28766:15;28740:24;28736:46;28726:56;;28476:324;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:139::-;1887:6;1882:3;1877;1871:23;1928:1;1919:6;1914:3;1910:16;1903:27;1798:139;;;:::o;1943:102::-;1984:6;2035:2;2031:7;2026:2;2019:5;2015:14;2011:28;2001:38;;1943:102;;;:::o;2051:377::-;2139:3;2167:39;2200:5;2167:39;:::i;:::-;2222:71;2286:6;2281:3;2222:71;:::i;:::-;2215:78;;2302:65;2360:6;2355:3;2348:4;2341:5;2337:16;2302:65;:::i;:::-;2392:29;2414:6;2392:29;:::i;:::-;2387:3;2383:39;2376:46;;2143:285;2051:377;;;;:::o;2434:313::-;2547:4;2585:2;2574:9;2570:18;2562:26;;2634:9;2628:4;2624:20;2620:1;2609:9;2605:17;2598:47;2662:78;2735:4;2726:6;2662:78;:::i;:::-;2654:86;;2434:313;;;;:::o;2753:77::-;2790:7;2819:5;2808:16;;2753:77;;;:::o;2836:122::-;2909:24;2927:5;2909:24;:::i;:::-;2902:5;2899:35;2889:63;;2948:1;2945;2938:12;2889:63;2836:122;:::o;2964:139::-;3010:5;3048:6;3035:20;3026:29;;3064:33;3091:5;3064:33;:::i;:::-;2964:139;;;;:::o;3109:329::-;3168:6;3217:2;3205:9;3196:7;3192:23;3188:32;3185:119;;;3223:79;;:::i;:::-;3185:119;3343:1;3368:53;3413:7;3404:6;3393:9;3389:22;3368:53;:::i;:::-;3358:63;;3314:117;3109:329;;;;:::o;3444:126::-;3481:7;3521:42;3514:5;3510:54;3499:65;;3444:126;;;:::o;3576:96::-;3613:7;3642:24;3660:5;3642:24;:::i;:::-;3631:35;;3576:96;;;:::o;3678:118::-;3765:24;3783:5;3765:24;:::i;:::-;3760:3;3753:37;3678:118;;:::o;3802:222::-;3895:4;3933:2;3922:9;3918:18;3910:26;;3946:71;4014:1;4003:9;3999:17;3990:6;3946:71;:::i;:::-;3802:222;;;;:::o;4030:122::-;4103:24;4121:5;4103:24;:::i;:::-;4096:5;4093:35;4083:63;;4142:1;4139;4132:12;4083:63;4030:122;:::o;4158:139::-;4204:5;4242:6;4229:20;4220:29;;4258:33;4285:5;4258:33;:::i;:::-;4158:139;;;;:::o;4303:474::-;4371:6;4379;4428:2;4416:9;4407:7;4403:23;4399:32;4396:119;;;4434:79;;:::i;:::-;4396:119;4554:1;4579:53;4624:7;4615:6;4604:9;4600:22;4579:53;:::i;:::-;4569:63;;4525:117;4681:2;4707:53;4752:7;4743:6;4732:9;4728:22;4707:53;:::i;:::-;4697:63;;4652:118;4303:474;;;;;:::o;4783:118::-;4870:24;4888:5;4870:24;:::i;:::-;4865:3;4858:37;4783:118;;:::o;4907:222::-;5000:4;5038:2;5027:9;5023:18;5015:26;;5051:71;5119:1;5108:9;5104:17;5095:6;5051:71;:::i;:::-;4907:222;;;;:::o;5135:474::-;5203:6;5211;5260:2;5248:9;5239:7;5235:23;5231:32;5228:119;;;5266:79;;:::i;:::-;5228:119;5386:1;5411:53;5456:7;5447:6;5436:9;5432:22;5411:53;:::i;:::-;5401:63;;5357:117;5513:2;5539:53;5584:7;5575:6;5564:9;5560:22;5539:53;:::i;:::-;5529:63;;5484:118;5135:474;;;;;:::o;5615:619::-;5692:6;5700;5708;5757:2;5745:9;5736:7;5732:23;5728:32;5725:119;;;5763:79;;:::i;:::-;5725:119;5883:1;5908:53;5953:7;5944:6;5933:9;5929:22;5908:53;:::i;:::-;5898:63;;5854:117;6010:2;6036:53;6081:7;6072:6;6061:9;6057:22;6036:53;:::i;:::-;6026:63;;5981:118;6138:2;6164:53;6209:7;6200:6;6189:9;6185:22;6164:53;:::i;:::-;6154:63;;6109:118;5615:619;;;;;:::o;6240:104::-;6285:7;6314:24;6332:5;6314:24;:::i;:::-;6303:35;;6240:104;;;:::o;6350:138::-;6431:32;6457:5;6431:32;:::i;:::-;6424:5;6421:43;6411:71;;6478:1;6475;6468:12;6411:71;6350:138;:::o;6494:155::-;6548:5;6586:6;6573:20;6564:29;;6602:41;6637:5;6602:41;:::i;:::-;6494:155;;;;:::o;6655:345::-;6722:6;6771:2;6759:9;6750:7;6746:23;6742:32;6739:119;;;6777:79;;:::i;:::-;6739:119;6897:1;6922:61;6975:7;6966:6;6955:9;6951:22;6922:61;:::i;:::-;6912:71;;6868:125;6655:345;;;;:::o;7006:329::-;7065:6;7114:2;7102:9;7093:7;7089:23;7085:32;7082:119;;;7120:79;;:::i;:::-;7082:119;7240:1;7265:53;7310:7;7301:6;7290:9;7286:22;7265:53;:::i;:::-;7255:63;;7211:117;7006:329;;;;:::o;7341:116::-;7411:21;7426:5;7411:21;:::i;:::-;7404:5;7401:32;7391:60;;7447:1;7444;7437:12;7391:60;7341:116;:::o;7463:133::-;7506:5;7544:6;7531:20;7522:29;;7560:30;7584:5;7560:30;:::i;:::-;7463:133;;;;:::o;7602:468::-;7667:6;7675;7724:2;7712:9;7703:7;7699:23;7695:32;7692:119;;;7730:79;;:::i;:::-;7692:119;7850:1;7875:53;7920:7;7911:6;7900:9;7896:22;7875:53;:::i;:::-;7865:63;;7821:117;7977:2;8003:50;8045:7;8036:6;8025:9;8021:22;8003:50;:::i;:::-;7993:60;;7948:115;7602:468;;;;;:::o;8076:117::-;8185:1;8182;8175:12;8199:117;8308:1;8305;8298:12;8322:180;8370:77;8367:1;8360:88;8467:4;8464:1;8457:15;8491:4;8488:1;8481:15;8508:281;8591:27;8613:4;8591:27;:::i;:::-;8583:6;8579:40;8721:6;8709:10;8706:22;8685:18;8673:10;8670:34;8667:62;8664:88;;;8732:18;;:::i;:::-;8664:88;8772:10;8768:2;8761:22;8551:238;8508:281;;:::o;8795:129::-;8829:6;8856:20;;:::i;:::-;8846:30;;8885:33;8913:4;8905:6;8885:33;:::i;:::-;8795:129;;;:::o;8930:307::-;8991:4;9081:18;9073:6;9070:30;9067:56;;;9103:18;;:::i;:::-;9067:56;9141:29;9163:6;9141:29;:::i;:::-;9133:37;;9225:4;9219;9215:15;9207:23;;8930:307;;;:::o;9243:148::-;9341:6;9336:3;9331;9318:30;9382:1;9373:6;9368:3;9364:16;9357:27;9243:148;;;:::o;9397:423::-;9474:5;9499:65;9515:48;9556:6;9515:48;:::i;:::-;9499:65;:::i;:::-;9490:74;;9587:6;9580:5;9573:21;9625:4;9618:5;9614:16;9663:3;9654:6;9649:3;9645:16;9642:25;9639:112;;;9670:79;;:::i;:::-;9639:112;9760:54;9807:6;9802:3;9797;9760:54;:::i;:::-;9480:340;9397:423;;;;;:::o;9839:338::-;9894:5;9943:3;9936:4;9928:6;9924:17;9920:27;9910:122;;9951:79;;:::i;:::-;9910:122;10068:6;10055:20;10093:78;10167:3;10159:6;10152:4;10144:6;10140:17;10093:78;:::i;:::-;10084:87;;9900:277;9839:338;;;;:::o;10183:943::-;10278:6;10286;10294;10302;10351:3;10339:9;10330:7;10326:23;10322:33;10319:120;;;10358:79;;:::i;:::-;10319:120;10478:1;10503:53;10548:7;10539:6;10528:9;10524:22;10503:53;:::i;:::-;10493:63;;10449:117;10605:2;10631:53;10676:7;10667:6;10656:9;10652:22;10631:53;:::i;:::-;10621:63;;10576:118;10733:2;10759:53;10804:7;10795:6;10784:9;10780:22;10759:53;:::i;:::-;10749:63;;10704:118;10889:2;10878:9;10874:18;10861:32;10920:18;10912:6;10909:30;10906:117;;;10942:79;;:::i;:::-;10906:117;11047:62;11101:7;11092:6;11081:9;11077:22;11047:62;:::i;:::-;11037:72;;10832:287;10183:943;;;;;;;:::o;11132:474::-;11200:6;11208;11257:2;11245:9;11236:7;11232:23;11228:32;11225:119;;;11263:79;;:::i;:::-;11225:119;11383:1;11408:53;11453:7;11444:6;11433:9;11429:22;11408:53;:::i;:::-;11398:63;;11354:117;11510:2;11536:53;11581:7;11572:6;11561:9;11557:22;11536:53;:::i;:::-;11526:63;;11481:118;11132:474;;;;;:::o;11612:180::-;11660:77;11657:1;11650:88;11757:4;11754:1;11747:15;11781:4;11778:1;11771:15;11798:320;11842:6;11879:1;11873:4;11869:12;11859:22;;11926:1;11920:4;11916:12;11947:18;11937:81;;12003:4;11995:6;11991:17;11981:27;;11937:81;12065:2;12057:6;12054:14;12034:18;12031:38;12028:84;;12084:18;;:::i;:::-;12028:84;11849:269;11798:320;;;:::o;12124:177::-;12264:29;12260:1;12252:6;12248:14;12241:53;12124:177;:::o;12307:366::-;12449:3;12470:67;12534:2;12529:3;12470:67;:::i;:::-;12463:74;;12546:93;12635:3;12546:93;:::i;:::-;12664:2;12659:3;12655:12;12648:19;;12307:366;;;:::o;12679:419::-;12845:4;12883:2;12872:9;12868:18;12860:26;;12932:9;12926:4;12922:20;12918:1;12907:9;12903:17;12896:47;12960:131;13086:4;12960:131;:::i;:::-;12952:139;;12679:419;;;:::o;13104:180::-;13152:77;13149:1;13142:88;13249:4;13246:1;13239:15;13273:4;13270:1;13263:15;13290:410;13330:7;13353:20;13371:1;13353:20;:::i;:::-;13348:25;;13387:20;13405:1;13387:20;:::i;:::-;13382:25;;13442:1;13439;13435:9;13464:30;13482:11;13464:30;:::i;:::-;13453:41;;13643:1;13634:7;13630:15;13627:1;13624:22;13604:1;13597:9;13577:83;13554:139;;13673:18;;:::i;:::-;13554:139;13338:362;13290:410;;;;:::o;13706:180::-;13754:77;13751:1;13744:88;13851:4;13848:1;13841:15;13875:4;13872:1;13865:15;13892:185;13932:1;13949:20;13967:1;13949:20;:::i;:::-;13944:25;;13983:20;14001:1;13983:20;:::i;:::-;13978:25;;14022:1;14012:35;;14027:18;;:::i;:::-;14012:35;14069:1;14066;14062:9;14057:14;;13892:185;;;;:::o;14083:194::-;14123:4;14143:20;14161:1;14143:20;:::i;:::-;14138:25;;14177:20;14195:1;14177:20;:::i;:::-;14172:25;;14221:1;14218;14214:9;14206:17;;14245:1;14239:4;14236:11;14233:37;;;14250:18;;:::i;:::-;14233:37;14083:194;;;;:::o;14283:172::-;14423:24;14419:1;14411:6;14407:14;14400:48;14283:172;:::o;14461:366::-;14603:3;14624:67;14688:2;14683:3;14624:67;:::i;:::-;14617:74;;14700:93;14789:3;14700:93;:::i;:::-;14818:2;14813:3;14809:12;14802:19;;14461:366;;;:::o;14833:419::-;14999:4;15037:2;15026:9;15022:18;15014:26;;15086:9;15080:4;15076:20;15072:1;15061:9;15057:17;15050:47;15114:131;15240:4;15114:131;:::i;:::-;15106:139;;14833:419;;;:::o;15258:182::-;15398:34;15394:1;15386:6;15382:14;15375:58;15258:182;:::o;15446:366::-;15588:3;15609:67;15673:2;15668:3;15609:67;:::i;:::-;15602:74;;15685:93;15774:3;15685:93;:::i;:::-;15803:2;15798:3;15794:12;15787:19;;15446:366;;;:::o;15818:419::-;15984:4;16022:2;16011:9;16007:18;15999:26;;16071:9;16065:4;16061:20;16057:1;16046:9;16042:17;16035:47;16099:131;16225:4;16099:131;:::i;:::-;16091:139;;15818:419;;;:::o;16243:162::-;16383:14;16379:1;16371:6;16367:14;16360:38;16243:162;:::o;16411:366::-;16553:3;16574:67;16638:2;16633:3;16574:67;:::i;:::-;16567:74;;16650:93;16739:3;16650:93;:::i;:::-;16768:2;16763:3;16759:12;16752:19;;16411:366;;;:::o;16783:419::-;16949:4;16987:2;16976:9;16972:18;16964:26;;17036:9;17030:4;17026:20;17022:1;17011:9;17007:17;17000:47;17064:131;17190:4;17064:131;:::i;:::-;17056:139;;16783:419;;;:::o;17208:168::-;17348:20;17344:1;17336:6;17332:14;17325:44;17208:168;:::o;17382:366::-;17524:3;17545:67;17609:2;17604:3;17545:67;:::i;:::-;17538:74;;17621:93;17710:3;17621:93;:::i;:::-;17739:2;17734:3;17730:12;17723:19;;17382:366;;;:::o;17754:419::-;17920:4;17958:2;17947:9;17943:18;17935:26;;18007:9;18001:4;17997:20;17993:1;17982:9;17978:17;17971:47;18035:131;18161:4;18035:131;:::i;:::-;18027:139;;17754:419;;;:::o;18179:160::-;18319:12;18315:1;18307:6;18303:14;18296:36;18179:160;:::o;18345:366::-;18487:3;18508:67;18572:2;18567:3;18508:67;:::i;:::-;18501:74;;18584:93;18673:3;18584:93;:::i;:::-;18702:2;18697:3;18693:12;18686:19;;18345:366;;;:::o;18717:419::-;18883:4;18921:2;18910:9;18906:18;18898:26;;18970:9;18964:4;18960:20;18956:1;18945:9;18941:17;18934:47;18998:131;19124:4;18998:131;:::i;:::-;18990:139;;18717:419;;;:::o;19142:170::-;19282:22;19278:1;19270:6;19266:14;19259:46;19142:170;:::o;19318:366::-;19460:3;19481:67;19545:2;19540:3;19481:67;:::i;:::-;19474:74;;19557:93;19646:3;19557:93;:::i;:::-;19675:2;19670:3;19666:12;19659:19;;19318:366;;;:::o;19690:419::-;19856:4;19894:2;19883:9;19879:18;19871:26;;19943:9;19937:4;19933:20;19929:1;19918:9;19914:17;19907:47;19971:131;20097:4;19971:131;:::i;:::-;19963:139;;19690:419;;;:::o;20115:191::-;20155:3;20174:20;20192:1;20174:20;:::i;:::-;20169:25;;20208:20;20226:1;20208:20;:::i;:::-;20203:25;;20251:1;20248;20244:9;20237:16;;20272:3;20269:1;20266:10;20263:36;;;20279:18;;:::i;:::-;20263:36;20115:191;;;;:::o;20312:168::-;20452:20;20448:1;20440:6;20436:14;20429:44;20312:168;:::o;20486:366::-;20628:3;20649:67;20713:2;20708:3;20649:67;:::i;:::-;20642:74;;20725:93;20814:3;20725:93;:::i;:::-;20843:2;20838:3;20834:12;20827:19;;20486:366;;;:::o;20858:419::-;21024:4;21062:2;21051:9;21047:18;21039:26;;21111:9;21105:4;21101:20;21097:1;21086:9;21082:17;21075:47;21139:131;21265:4;21139:131;:::i;:::-;21131:139;;20858:419;;;:::o;21283:168::-;21423:20;21419:1;21411:6;21407:14;21400:44;21283:168;:::o;21457:366::-;21599:3;21620:67;21684:2;21679:3;21620:67;:::i;:::-;21613:74;;21696:93;21785:3;21696:93;:::i;:::-;21814:2;21809:3;21805:12;21798:19;;21457:366;;;:::o;21829:419::-;21995:4;22033:2;22022:9;22018:18;22010:26;;22082:9;22076:4;22072:20;22068:1;22057:9;22053:17;22046:47;22110:131;22236:4;22110:131;:::i;:::-;22102:139;;21829:419;;;:::o;22254:148::-;22356:11;22393:3;22378:18;;22254:148;;;;:::o;22408:315::-;22548:66;22544:1;22536:6;22532:14;22525:90;22649:66;22644:2;22636:6;22632:15;22625:91;22408:315;:::o;22729:402::-;22889:3;22910:85;22992:2;22987:3;22910:85;:::i;:::-;22903:92;;23004:93;23093:3;23004:93;:::i;:::-;23122:2;23117:3;23113:12;23106:19;;22729:402;;;:::o;23137:163::-;23277:15;23273:1;23265:6;23261:14;23254:39;23137:163;:::o;23306:402::-;23466:3;23487:85;23569:2;23564:3;23487:85;:::i;:::-;23480:92;;23581:93;23670:3;23581:93;:::i;:::-;23699:2;23694:3;23690:12;23683:19;;23306:402;;;:::o;23714:167::-;23854:19;23850:1;23842:6;23838:14;23831:43;23714:167;:::o;23887:402::-;24047:3;24068:85;24150:2;24145:3;24068:85;:::i;:::-;24061:92;;24162:93;24251:3;24162:93;:::i;:::-;24280:2;24275:3;24271:12;24264:19;;23887:402;;;:::o;24295:313::-;24435:34;24431:1;24423:6;24419:14;24412:58;24508:34;24503:2;24495:6;24491:15;24484:59;24577:23;24572:2;24564:6;24560:15;24553:48;24295:313;:::o;24614:402::-;24774:3;24795:85;24877:2;24872:3;24795:85;:::i;:::-;24788:92;;24889:93;24978:3;24889:93;:::i;:::-;25007:2;25002:3;24998:12;24991:19;;24614:402;;;:::o;25022:165::-;25162:17;25158:1;25150:6;25146:14;25139:41;25022:165;:::o;25193:402::-;25353:3;25374:85;25456:2;25451:3;25374:85;:::i;:::-;25367:92;;25468:93;25557:3;25468:93;:::i;:::-;25586:2;25581:3;25577:12;25570:19;;25193:402;;;:::o;25601:315::-;25741:66;25737:1;25729:6;25725:14;25718:90;25842:66;25837:2;25829:6;25825:15;25818:91;25601:315;:::o;25922:402::-;26082:3;26103:85;26185:2;26180:3;26103:85;:::i;:::-;26096:92;;26197:93;26286:3;26197:93;:::i;:::-;26315:2;26310:3;26306:12;26299:19;;25922:402;;;:::o;26330:214::-;26470:66;26466:1;26458:6;26454:14;26447:90;26330:214;:::o;26550:402::-;26710:3;26731:85;26813:2;26808:3;26731:85;:::i;:::-;26724:92;;26825:93;26914:3;26825:93;:::i;:::-;26943:2;26938:3;26934:12;26927:19;;26550:402;;;:::o;26958:390::-;27064:3;27092:39;27125:5;27092:39;:::i;:::-;27147:89;27229:6;27224:3;27147:89;:::i;:::-;27140:96;;27245:65;27303:6;27298:3;27291:4;27284:5;27280:16;27245:65;:::i;:::-;27335:6;27330:3;27326:16;27319:23;;27068:280;26958:390;;;;:::o;27354:157::-;27494:9;27490:1;27482:6;27478:14;27471:33;27354:157;:::o;27517:400::-;27677:3;27698:84;27780:1;27775:3;27698:84;:::i;:::-;27691:91;;27791:93;27880:3;27791:93;:::i;:::-;27909:1;27904:3;27900:11;27893:18;;27517:400;;;:::o;27923:156::-;28063:8;28059:1;28051:6;28047:14;28040:32;27923:156;:::o;28085:400::-;28245:3;28266:84;28348:1;28343:3;28266:84;:::i;:::-;28259:91;;28359:93;28448:3;28359:93;:::i;:::-;28477:1;28472:3;28468:11;28461:18;;28085:400;;;:::o;28491:2669::-;29532:3;29554:148;29698:3;29554:148;:::i;:::-;29547:155;;29719:148;29863:3;29719:148;:::i;:::-;29712:155;;29884:148;30028:3;29884:148;:::i;:::-;29877:155;;30049:148;30193:3;30049:148;:::i;:::-;30042:155;;30214:148;30358:3;30214:148;:::i;:::-;30207:155;;30379:148;30523:3;30379:148;:::i;:::-;30372:155;;30544:148;30688:3;30544:148;:::i;:::-;30537:155;;30709:95;30800:3;30791:6;30709:95;:::i;:::-;30702:102;;30821:148;30965:3;30821:148;:::i;:::-;30814:155;;30986:148;31130:3;30986:148;:::i;:::-;30979:155;;31151:3;31144:10;;28491:2669;;;;:::o;31166:176::-;31306:28;31302:1;31294:6;31290:14;31283:52;31166:176;:::o;31348:402::-;31508:3;31529:85;31611:2;31606:3;31529:85;:::i;:::-;31522:92;;31623:93;31712:3;31623:93;:::i;:::-;31741:2;31736:3;31732:12;31725:19;;31348:402;;;:::o;31756:541::-;31989:3;32011:148;32155:3;32011:148;:::i;:::-;32004:155;;32176:95;32267:3;32258:6;32176:95;:::i;:::-;32169:102;;32288:3;32281:10;;31756:541;;;;:::o;32303:214::-;32443:66;32439:1;32431:6;32427:14;32420:90;32303:214;:::o;32523:402::-;32683:3;32704:85;32786:2;32781:3;32704:85;:::i;:::-;32697:92;;32798:93;32887:3;32798:93;:::i;:::-;32916:2;32911:3;32907:12;32900:19;;32523:402;;;:::o;32931:315::-;33071:66;33067:1;33059:6;33055:14;33048:90;33172:66;33167:2;33159:6;33155:15;33148:91;32931:315;:::o;33252:402::-;33412:3;33433:85;33515:2;33510:3;33433:85;:::i;:::-;33426:92;;33527:93;33616:3;33527:93;:::i;:::-;33645:2;33640:3;33636:12;33629:19;;33252:402;;;:::o;33660:315::-;33800:66;33796:1;33788:6;33784:14;33777:90;33901:66;33896:2;33888:6;33884:15;33877:91;33660:315;:::o;33981:402::-;34141:3;34162:85;34244:2;34239:3;34162:85;:::i;:::-;34155:92;;34256:93;34345:3;34256:93;:::i;:::-;34374:2;34369:3;34365:12;34358:19;;33981:402;;;:::o;34389:145::-;34525:5;34521:1;34513:6;34509:14;34502:29;34389:145;:::o;34536:384::-;34696:3;34713:84;34795:1;34790:3;34713:84;:::i;:::-;34706:91;;34802:93;34891:3;34802:93;:::i;:::-;34916:1;34911:3;34907:11;34900:18;;34536:384;;;:::o;34922:206::-;35058:66;35054:1;35046:6;35042:14;35035:90;34922:206;:::o;35130:384::-;35290:3;35307:84;35389:1;35384:3;35307:84;:::i;:::-;35300:91;;35396:93;35485:3;35396:93;:::i;:::-;35510:1;35505:3;35501:11;35494:18;;35130:384;;;:::o;35516:206::-;35652:66;35648:1;35640:6;35636:14;35629:90;35516:206;:::o;35724:384::-;35884:3;35901:84;35983:1;35978:3;35901:84;:::i;:::-;35894:91;;35990:93;36079:3;35990:93;:::i;:::-;36104:1;36099:3;36095:11;36088:18;;35724:384;;;:::o;36110:2147::-;36944:3;36962:148;37106:3;36962:148;:::i;:::-;36955:155;;37123:95;37214:3;37205:6;37123:95;:::i;:::-;37116:102;;37231:148;37375:3;37231:148;:::i;:::-;37224:155;;37392:148;37536:3;37392:148;:::i;:::-;37385:155;;37553:95;37644:3;37635:6;37553:95;:::i;:::-;37546:102;;37661:148;37805:3;37661:148;:::i;:::-;37654:155;;37822:148;37966:3;37822:148;:::i;:::-;37815:155;;37983:95;38074:3;38065:6;37983:95;:::i;:::-;37976:102;;38091:148;38235:3;38091:148;:::i;:::-;38084:155;;38252:3;38245:10;;36110:2147;;;;;;:::o;38259:171::-;38395:31;38391:1;38383:6;38379:14;38372:55;38259:171;:::o;38432:386::-;38592:3;38609:85;38691:2;38686:3;38609:85;:::i;:::-;38602:92;;38699:93;38788:3;38699:93;:::i;:::-;38813:2;38808:3;38804:12;38797:19;;38432:386;;;:::o;38820:525::-;39053:3;39071:148;39215:3;39071:148;:::i;:::-;39064:155;;39232:95;39323:3;39314:6;39232:95;:::i;:::-;39225:102;;39340:3;39333:10;;38820:525;;;;:::o;39347:218::-;39483:34;39479:1;39471:6;39467:14;39460:58;39548:13;39543:2;39535:6;39531:15;39524:38;39347:218;:::o;39567:350::-;39709:3;39726:67;39790:2;39785:3;39726:67;:::i;:::-;39719:74;;39798:93;39887:3;39798:93;:::i;:::-;39912:2;39907:3;39903:12;39896:19;;39567:350;;;:::o;39919:403::-;40085:4;40119:2;40108:9;40104:18;40096:26;;40164:9;40158:4;40154:20;40150:1;40139:9;40135:17;40128:47;40188:131;40314:4;40188:131;:::i;:::-;40180:139;;39919:403;;;:::o;40324:218::-;40460:34;40456:1;40448:6;40444:14;40437:58;40525:13;40520:2;40512:6;40508:15;40501:38;40324:218;:::o;40544:350::-;40686:3;40703:67;40767:2;40762:3;40703:67;:::i;:::-;40696:74;;40775:93;40864:3;40775:93;:::i;:::-;40889:2;40884:3;40880:12;40873:19;;40544:350;;;:::o;40896:403::-;41062:4;41096:2;41085:9;41081:18;41073:26;;41141:9;41135:4;41131:20;41127:1;41116:9;41112:17;41105:47;41165:131;41291:4;41165:131;:::i;:::-;41157:139;;40896:403;;;:::o;41301:216::-;41437:34;41433:1;41425:6;41421:14;41414:58;41502:11;41497:2;41489:6;41485:15;41478:36;41301:216;:::o;41519:350::-;41661:3;41678:67;41742:2;41737:3;41678:67;:::i;:::-;41671:74;;41750:93;41839:3;41750:93;:::i;:::-;41864:2;41859:3;41855:12;41848:19;;41519:350;;;:::o;41871:403::-;42037:4;42071:2;42060:9;42056:18;42048:26;;42116:9;42110:4;42106:20;42102:1;42091:9;42087:17;42080:47;42140:131;42266:4;42140:131;:::i;:::-;42132:139;;41871:403;;;:::o;42276:210::-;42412:34;42408:1;42400:6;42396:14;42389:58;42477:5;42472:2;42464:6;42460:15;42453:30;42276:210;:::o;42488:350::-;42630:3;42647:67;42711:2;42706:3;42647:67;:::i;:::-;42640:74;;42719:93;42808:3;42719:93;:::i;:::-;42833:2;42828:3;42824:12;42817:19;;42488:350;;;:::o;42840:403::-;43006:4;43040:2;43029:9;43025:18;43017:26;;43085:9;43079:4;43075:20;43071:1;43060:9;43056:17;43049:47;43109:131;43235:4;43109:131;:::i;:::-;43101:139;;42840:403;;;:::o;43245:167::-;43381:27;43377:1;43369:6;43365:14;43358:51;43245:167;:::o;43414:350::-;43556:3;43573:67;43637:2;43632:3;43573:67;:::i;:::-;43566:74;;43645:93;43734:3;43645:93;:::i;:::-;43759:2;43754:3;43750:12;43743:19;;43414:350;;;:::o;43766:403::-;43932:4;43966:2;43955:9;43951:18;43943:26;;44011:9;44005:4;44001:20;43997:1;43986:9;43982:17;43975:47;44035:131;44161:4;44035:131;:::i;:::-;44027:139;;43766:403;;;:::o;44171:164::-;44215:77;44212:1;44205:88;44308:4;44305:1;44298:15;44328:4;44325:1;44318:15;44337:106;44404:6;44434:5;44428:12;44418:22;;44337:106;;;:::o;44445:172::-;44544:11;44574:6;44569:3;44562:19;44610:4;44605:3;44601:14;44586:29;;44445:172;;;;:::o;44619:120::-;44686:4;44705:3;44697:11;;44731:4;44726:3;44722:14;44714:22;;44619:120;;;:::o;44741:100::-;44814:24;44832:5;44814:24;:::i;:::-;44809:3;44802:37;44741:100;;:::o;44843:167::-;44912:10;44929:46;44971:3;44963:6;44929:46;:::i;:::-;45003:4;44998:3;44994:14;44980:28;;44843:167;;;;:::o;45012:105::-;45082:4;45110;45105:3;45101:14;45093:22;;45012:105;;;:::o;45145:684::-;45264:3;45289:54;45337:5;45289:54;:::i;:::-;45355:86;45434:6;45429:3;45355:86;:::i;:::-;45348:93;;45461:56;45511:5;45461:56;:::i;:::-;45536:7;45563:1;45548:264;45573:6;45570:1;45567:13;45548:264;;;45641:6;45635:13;45664:63;45723:3;45708:13;45664:63;:::i;:::-;45657:70;;45746:60;45799:6;45746:60;:::i;:::-;45736:70;;45604:208;45595:1;45592;45588:9;45583:14;;45548:264;;;45552:14;45824:3;45817:10;;45269:560;;;45145:684;;;;:::o;45831:463::-;46002:4;46036:2;46025:9;46021:18;46013:26;;46045:71;46113:1;46102:9;46098:17;46089:6;46045:71;:::i;:::-;46159:9;46153:4;46149:20;46144:2;46133:9;46129:18;46122:48;46183:108;46286:4;46277:6;46183:108;:::i;:::-;46175:116;;45831:463;;;;;:::o;46296:287::-;46373:4;46455:18;46447:6;46444:30;46441:56;;;46477:18;;:::i;:::-;46441:56;46523:4;46515:6;46511:17;46503:25;;46575:4;46569;46565:15;46557:23;;46296:287;;;:::o;46585:109::-;46690:1;46687;46680:12;46696:131;46753:5;46780:6;46774:13;46765:22;;46792:33;46819:5;46792:33;:::i;:::-;46696:131;;;;:::o;46842:672::-;46949:5;46970:81;46986:64;47043:6;46986:64;:::i;:::-;46970:81;:::i;:::-;46961:90;;47067:5;47092:6;47085:5;47078:21;47122:4;47115:5;47111:16;47104:23;;47171:4;47163:6;47159:17;47151:6;47147:30;47196:3;47188:6;47185:15;47182:114;;;47211:79;;:::i;:::-;47182:114;47318:6;47301:211;47335:6;47330:3;47327:15;47301:211;;;47402:3;47427:48;47471:3;47459:10;47427:48;:::i;:::-;47422:3;47415:61;47501:4;47496:3;47492:14;47485:21;;47373:139;47361:4;47356:3;47352:14;47345:21;;47301:211;;;47305:21;46955:559;;46842:672;;;;;:::o;47529:369::-;47611:5;47656:3;47649:4;47641:6;47637:17;47633:27;47623:122;;47664:79;;:::i;:::-;47623:122;47770:6;47764:13;47791:105;47892:3;47884:6;47877:4;47869:6;47865:17;47791:105;:::i;:::-;47782:114;;47617:281;47529:369;;;;:::o;47900:526::-;47995:6;48040:2;48028:9;48019:7;48015:23;48011:32;48008:119;;;48046:79;;:::i;:::-;48008:119;48179:1;48168:9;48164:17;48158:24;48205:18;48197:6;48194:30;48191:117;;;48227:79;;:::i;:::-;48191:117;48328:89;48409:7;48400:6;48389:9;48385:22;48328:89;:::i;:::-;48318:99;;48133:290;47900:526;;;;:::o;48428:422::-;48577:4;48611:2;48600:9;48596:18;48588:26;;48620:71;48688:1;48677:9;48673:17;48664:6;48620:71;:::i;:::-;48697:72;48765:2;48754:9;48750:18;48741:6;48697:72;:::i;:::-;48775;48843:2;48832:9;48828:18;48819:6;48775:72;:::i;:::-;48428:422;;;;;;:::o;48852:139::-;48953:11;48986:3;48971:18;;48852:139;;;;:::o;48993:110::-;;:::o;49105:382::-;49264:3;49281:83;49362:1;49357:3;49281:83;:::i;:::-;49274:90;;49369:93;49458:3;49369:93;:::i;:::-;49483:1;49478:3;49474:11;49467:18;;49105:382;;;:::o;49489:367::-;49673:3;49691:147;49834:3;49691:147;:::i;:::-;49684:154;;49851:3;49844:10;;49489:367;;;:::o;49858:170::-;49994:30;49990:1;49982:6;49978:14;49971:54;49858:170;:::o;50030:350::-;50172:3;50189:67;50253:2;50248:3;50189:67;:::i;:::-;50182:74;;50261:93;50350:3;50261:93;:::i;:::-;50375:2;50370:3;50366:12;50359:19;;50030:350;;;:::o;50382:403::-;50548:4;50582:2;50571:9;50567:18;50559:26;;50627:9;50621:4;50617:20;50613:1;50602:9;50598:17;50591:47;50651:131;50777:4;50651:131;:::i;:::-;50643:139;;50382:403;;;:::o;50787:676::-;51014:4;51048:3;51037:9;51033:19;51025:27;;51058:71;51126:1;51115:9;51111:17;51102:6;51058:71;:::i;:::-;51172:9;51166:4;51162:20;51157:2;51146:9;51142:18;51135:48;51196:108;51299:4;51290:6;51196:108;:::i;:::-;51188:116;;51310:72;51378:2;51367:9;51363:18;51354:6;51310:72;:::i;:::-;51388;51456:2;51445:9;51441:18;51432:6;51388:72;:::i;:::-;50787:676;;;;;;;:::o;51465:169::-;51601:29;51597:1;51589:6;51585:14;51578:53;51465:169;:::o;51636:350::-;51778:3;51795:67;51859:2;51854:3;51795:67;:::i;:::-;51788:74;;51867:93;51956:3;51867:93;:::i;:::-;51981:2;51976:3;51972:12;51965:19;;51636:350;;;:::o;51988:403::-;52154:4;52188:2;52177:9;52173:18;52165:26;;52233:9;52227:4;52223:20;52219:1;52208:9;52204:17;52197:47;52257:131;52383:4;52257:131;:::i;:::-;52249:139;;51988:403;;;:::o;52393:327::-;52463:6;52508:2;52496:9;52487:7;52483:23;52479:32;52476:119;;;52514:79;;:::i;:::-;52476:119;52626:1;52647:64;52703:7;52694:6;52683:9;52679:22;52647:64;:::i;:::-;52637:74;;52601:116;52393:327;;;;:::o;52722:161::-;52858:21;52854:1;52846:6;52842:14;52835:45;52722:161;:::o;52885:350::-;53027:3;53044:67;53108:2;53103:3;53044:67;:::i;:::-;53037:74;;53116:93;53205:3;53116:93;:::i;:::-;53230:2;53225:3;53221:12;53214:19;;52885:350;;;:::o;53237:403::-;53403:4;53437:2;53426:9;53422:18;53414:26;;53482:9;53476:4;53472:20;53468:1;53457:9;53453:17;53446:47;53506:131;53632:4;53506:131;:::i;:::-;53498:139;;53237:403;;;:::o;53642:155::-;53681:3;53700:24;53718:5;53700:24;:::i;:::-;53691:33;;53742:4;53735:5;53732:15;53729:41;;53750:18;;:::i;:::-;53729:41;53793:1;53786:5;53782:13;53775:20;;53642:155;;;:::o;53799:316::-;53920:4;53954:2;53943:9;53939:18;53931:26;;53963:71;54031:1;54020:9;54016:17;54007:6;53963:71;:::i;:::-;54040:72;54108:2;54097:9;54093:18;54084:6;54040:72;:::i;:::-;53799:316;;;;;:::o;54117:125::-;54171:5;54198:6;54192:13;54183:22;;54210:30;54234:5;54210:30;:::i;:::-;54117:125;;;;:::o;54244:321::-;54311:6;54356:2;54344:9;54335:7;54331:23;54327:32;54324:119;;;54362:79;;:::i;:::-;54324:119;54474:1;54495:61;54548:7;54539:6;54528:9;54524:22;54495:61;:::i;:::-;54485:71;;54449:113;54244:321;;;;:::o;54567:163::-;54703:23;54699:1;54691:6;54687:14;54680:47;54567:163;:::o;54732:350::-;54874:3;54891:67;54955:2;54950:3;54891:67;:::i;:::-;54884:74;;54963:93;55052:3;54963:93;:::i;:::-;55077:2;55072:3;55068:12;55061:19;;54732:350;;;:::o;55084:403::-;55250:4;55284:2;55273:9;55269:18;55261:26;;55329:9;55323:4;55319:20;55315:1;55304:9;55300:17;55293:47;55353:131;55479:4;55353:131;:::i;:::-;55345:139;;55084:403;;;:::o;55489:90::-;55540:6;55570:5;55564:12;55554:22;;55489:90;;;:::o;55581:156::-;55664:11;55694:6;55689:3;55682:19;55730:4;55725:3;55721:14;55706:29;;55581:156;;;;:::o;55739:353::-;55825:3;55849:38;55881:5;55849:38;:::i;:::-;55899:70;55962:6;55957:3;55899:70;:::i;:::-;55892:77;;55974:65;56032:6;56027:3;56020:4;56013:5;56009:16;55974:65;:::i;:::-;56060:29;56082:6;56060:29;:::i;:::-;56055:3;56051:39;56044:46;;55829:263;55739:353;;;;:::o;56094:612::-;56289:4;56323:3;56312:9;56308:19;56300:27;;56333:71;56401:1;56390:9;56386:17;56377:6;56333:71;:::i;:::-;56410:72;56478:2;56467:9;56463:18;56454:6;56410:72;:::i;:::-;56488;56556:2;56545:9;56541:18;56532:6;56488:72;:::i;:::-;56603:9;56597:4;56593:20;56588:2;56577:9;56573:18;56566:48;56627:76;56698:4;56689:6;56627:76;:::i;:::-;56619:84;;56094:612;;;;;;;:::o;56708:129::-;56764:5;56791:6;56785:13;56776:22;;56803:32;56829:5;56803:32;:::i;:::-;56708:129;;;;:::o;56839:325::-;56908:6;56953:2;56941:9;56932:7;56928:23;56924:32;56921:119;;;56959:79;;:::i;:::-;56921:119;57071:1;57092:63;57147:7;57138:6;57127:9;57123:22;57092:63;:::i;:::-;57082:73;;57046:115;56839:325;;;;:::o;57166:217::-;57205:3;57224:24;57242:5;57224:24;:::i;:::-;57215:33;;57266:66;57259:5;57256:77;57253:103;;57336:18;;:::i;:::-;57253:103;57379:1;57372:5;57368:13;57361:20;;57166:217;;;:::o;57385:156::-;57417:1;57430:20;57448:1;57430:20;:::i;:::-;57425:25;;57460:20;57478:1;57460:20;:::i;:::-;57455:25;;57495:1;57485:35;;57500:18;;:::i;:::-;57485:35;57537:1;57534;57530:9;57525:14;;57385:156;;;;:::o

Swarm Source

ipfs://033221ee254387152a1497b54ac67d11a2c02f688d37550ba4ddb2e4d8e984aa
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.