ETH Price: $3,443.57 (-1.07%)
Gas: 9 Gwei

Token

Bored Grapes - Vines (BG)
 

Overview

Max Total Supply

246 BG

Holders

91

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
dbarlow.eth
Balance
4 BG
0x956367db79b29463f42e56c1d5bd186f5c390566
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:
BoredGrapes_Vines

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

// Sources flattened with hardhat v2.12.2 https://hardhat.org

// File contracts/IERC721A.sol

// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


// File contracts/ERC721A.sol


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

pragma solidity ^0.8.4;

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

/**
 * @title ERC721A
 *
 * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721)
 * Non-Fungible Token Standard, including the Metadata extension.
 * Optimized for lower gas during batch mints.
 *
 * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...)
 * starting from `_startTokenId()`.
 *
 * Assumptions:
 *
 * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // Reference type for token approval.
    struct TokenApprovalRef {
        address value;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        unchecked {
            if (_startTokenId() <= curr)
                if (curr < _currentIndex) {
                    uint256 packed = _packedOwnerships[curr];
                    // If not burned.
                    if (packed & _BITMASK_BURNED == 0) {
                        // Invariant:
                        // There will always be an initialized ownership slot
                        // (i.e. `ownership.addr != address(0) && ownership.burned == false`)
                        // before an unintialized ownership slot
                        // (i.e. `ownership.addr == address(0) && ownership.burned == false`)
                        // Hence, `curr` will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed will be zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                }
        }
        revert OwnerQueryForNonexistentToken();
    }

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

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

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

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

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

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

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

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

        return _tokenApprovals[tokenId].value;
    }

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

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

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

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

    /**
     * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`.
     */
    function _isSenderApprovedOrOwner(
        address approvedAddress,
        address owner,
        address msgSender
    ) private pure returns (bool result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, _BITMASK_ADDRESS)
            // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean.
            msgSender := and(msgSender, _BITMASK_ADDRESS)
            // `msgSender == owner || msgSender == approvedAddress`.
            result := or(eq(msgSender, owner), eq(msgSender, approvedAddress))
        }
    }

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

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

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

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

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);

        // The nested ifs save around 20+ gas over a compound boolean condition.
        if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
            if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();

        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

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

            // Updates:
            // - `address` to the next owner.
            // - `startTimestamp` to the timestamp of transfering.
            // - `burned` to `false`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                to,
                _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked)
            );

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

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

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public 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 virtual override {
        transferFrom(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

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

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

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

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

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

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

        // Overflows are incredibly unrealistic.
        // `balance` and `numberMinted` have a maximum limit of 2**64.
        // `tokenId` has a maximum limit of 2**256.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

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

            uint256 toMasked;
            uint256 end = startTokenId + quantity;

            // Use assembly to loop and emit the `Transfer` event for gas savings.
            assembly {
                // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
                toMasked := and(to, _BITMASK_ADDRESS)
                // Emit the `Transfer` event.
                log4(
                    0, // Start of data (0, since no data).
                    0, // End of data (0, since no data).
                    _TRANSFER_EVENT_SIGNATURE, // Signature.
                    0, // `address(0)`.
                    toMasked, // `to`.
                    startTokenId // `tokenId`.
                )

                for {
                    let tokenId := add(startTokenId, 1)
                } iszero(eq(tokenId, end)) {
                    tokenId := add(tokenId, 1)
                } {
                    // Emit the `Transfer` event. Similar to above.
                    log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId)
                }
            }
            if (toMasked == 0) revert MintToZeroAddress();

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

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

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

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

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

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

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

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

        unchecked {
            if (to.code.length != 0) {
                uint256 end = _currentIndex;
                uint256 index = end - quantity;
                do {
                    if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (index < end);
                // Reentrancy protection.
                if (_currentIndex != end) revert();
            }
        }
    }

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

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

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

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

        address from = address(uint160(prevOwnershipPacked));

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);

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

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

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

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

            // Updates:
            // - `address` to the last owner.
            // - `startTimestamp` to the timestamp of burning.
            // - `burned` to `true`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                from,
                (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked)
            );

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

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

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

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

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

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

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

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

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

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

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

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

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


// File @openzeppelin/contracts/utils/math/[email protected]


// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10**64) {
                value /= 10**64;
                result += 64;
            }
            if (value >= 10**32) {
                value /= 10**32;
                result += 32;
            }
            if (value >= 10**16) {
                value /= 10**16;
                result += 16;
            }
            if (value >= 10**8) {
                value /= 10**8;
                result += 8;
            }
            if (value >= 10**4) {
                value /= 10**4;
                result += 4;
            }
            if (value >= 10**2) {
                value /= 10**2;
                result += 2;
            }
            if (value >= 10**1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
        }
    }
}


// File @openzeppelin/contracts/utils/[email protected]


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

pragma solidity ^0.8.0;

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

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

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

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


// File @openzeppelin/contracts/utils/[email protected]


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

pragma solidity ^0.8.0;

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

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


// File @openzeppelin/contracts/access/[email protected]


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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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


// File @openzeppelin/contracts/utils/cryptography/[email protected]


// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV // Deprecated in v4.8
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}


// File contracts/GrapeVines.sol


pragma solidity ^0.8.17;




/*

// ______                    _    _____                           
// | ___ \                  | |  |  __ \                          
// | |_/ / ___  _ __ ___  __| |  | |  \/_ __ __ _ _ __   ___  ___ 
// | ___ \/ _ \| '__/ _ \/ _` |  | | __| '__/ _` | '_ \ / _ \/ __|
// | |_/ / (_) | | |  __/ (_| |  | |_\ \ | | (_| | |_) |  __/\__ \
// \____/ \___/|_|  \___|\__,_|   \____/_|  \__,_| .__/ \___||___/
//                                               | |              
//                                               |_|                                                         
//  _____                    _____ _             
// |   __|___ ___ ___ ___   |  |  |_|___ ___ ___ 
// |  |  |  _| .'| . | -_|  |  |  | |   | -_|_ -|
// |_____|_| |__,|  _|___|   \___/|_|_|_|___|___|
//               |_|                             

*/

//  Bored Grapes 2023


contract BoredGrapes_Vines is ERC721A, Ownable {
    using Strings for uint;

    event PricesChanged(uint newPresalePrice, uint newPublicPrice);
    event BaseURIChanged(string newUriPrefix, string newUriSuffix);
    event BottlesUsed(uint tokenId, uint[] bottleIds);
    event AdminChanged(address[] wallets, bool[] values);

    uint public publicPrice =  0.1 * 1000000000000000000;
    uint public presalePrice = 0.08 * 1000000000000000000;
    uint public constant MAX_SUPPLY = 5555;
    uint public walletLimit = 2;
    bool public publicSaleEnabled;
    bool public presaleEnabled;
    mapping(address => uint) public walletMints;
    mapping(uint => bool) public bottleUsed;
    uint public tokensReserved;

    string private _baseURIPrefix = "";
    string private _baseURISuffix = "";
    address private dev = 0xDB4AAC095f709a62Ec24479404fAE45D24ade34b;
    address private signerAddress = 0x77bFCca6F45B07047a34A31885Af86F11033665B;    
    ERC721A public bottleContract = ERC721A(0x0f7CcE027E0afe16fbf0dCc8e76932845B4e21d1);

    mapping(address => bool) public isAdmin; // mapping of Admin wallets for Bored Grapes Raffles
   
    constructor() ERC721A('Bored Grapes - Vines', 'BG') {
    }

    // ========================== Minting ==============================

    function _mintTokens(address to, uint quantity, uint price) internal {
        require(totalSupply()+quantity <= MAX_SUPPLY, "Max supply exceeded");
        require(price*quantity == msg.value, "invalid eth value");

        payable(owner()).transfer(msg.value);

        _mint(to, quantity);
        walletMints[to]+=quantity;
    }

    function bottlePresaleMint(uint[] calldata bottleIds) external payable {
        require(presaleEnabled, "Presale minting disabled");
        for(uint i=0; i<bottleIds.length; i++){
            require(bottleContract.ownerOf(bottleIds[i])==msg.sender, 'Address to is not owner of bottleId');
            require(!bottleUsed[bottleIds[i]],'BottleId has already been used');
            bottleUsed[bottleIds[i]]=true;
        }
        _mintTokens(msg.sender, bottleIds.length, presalePrice);
        emit BottlesUsed(_totalMinted(), bottleIds);
    }

    function _hashMessage(address sender) internal pure returns(bytes32) {
        return keccak256(abi.encodePacked( "\x19Ethereum Signed Message:\n32", keccak256(abi.encodePacked('BoredGrapesVines',sender))));         
    }

    function presaleMint(uint quantity, bytes memory signature) external payable {
        require(presaleEnabled, "Presale minting disabled");
        require(signerAddress == ECDSA.recover( _hashMessage( msg.sender), signature), "invalid hash or signature");
        require( walletMints[msg.sender]+quantity <= walletLimit, "Cannot mint more than walletLimit");        
        _mintTokens(msg.sender, quantity, publicPrice);
    }

    function mint(address to, uint quantity) external payable {
        require(publicSaleEnabled, "Public minting disabled");         
        _mintTokens(to, quantity, publicPrice);
    }

    // BoredGrapes can reserve 150 tokens for giveaways
    function reserveTokens(address to, uint quantity) external onlyOwner {
        require(tokensReserved + quantity <= 150, 'cannot reserve more');
        tokensReserved += quantity;
        _mint(to, quantity);
    }
  
    // ========================== Other functions ==============================

    modifier devOrOwner() {
        _devOrOwner();
        _;
    }

    function _devOrOwner() internal view {
        require( (owner()==msg.sender)||(dev==msg.sender), "Signer is not dev nor owner");
    }    

    function tokenURI(uint tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
        return bytes(_baseURIPrefix).length > 0 ? string(abi.encodePacked(_baseURIPrefix, tokenId.toString(), _baseURISuffix)) : "";
    }

    function setBaseURI(string memory newUriPrefix, string memory newUriSuffix) external devOrOwner{
        _baseURIPrefix = newUriPrefix;
        _baseURISuffix = newUriSuffix;
        emit BaseURIChanged(newUriPrefix, newUriSuffix);
    }

    function setPrices(uint newPresalePrice, uint newPublicPrice) external devOrOwner{
        presalePrice = newPresalePrice;
        publicPrice = newPublicPrice;
        emit PricesChanged(newPresalePrice, newPublicPrice);
    } 

    function setSigner(address _signerAddress) external devOrOwner{
        signerAddress = _signerAddress;
    }

    function setWalletLimit(uint _walletLimit) external devOrOwner{
        walletLimit = _walletLimit;
    }    

    function setBottleContract(ERC721A _bottleContract) public devOrOwner{
        bottleContract = _bottleContract;
    }

    function setDev(address newDev) external onlyOwner{
        dev = newDev;
    }           

    function toggleMinting(bool _presaleEnabled, bool _publicSaleEnabled) external devOrOwner{
        presaleEnabled = _presaleEnabled;
        publicSaleEnabled = _publicSaleEnabled;        
    }

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

    function setAdmins(address[] calldata wallets, bool[] calldata values) external onlyOwner{
        require(wallets.length==values.length, 'Array are of different size');
        require(wallets.length > 0, 'Arrays are empty');
        for(uint i=0; i<wallets.length; i++){
            isAdmin[wallets[i]]=values[i];
        }
        emit AdminChanged(wallets, values);
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"wallets","type":"address[]"},{"indexed":false,"internalType":"bool[]","name":"values","type":"bool[]"}],"name":"AdminChanged","type":"event"},{"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":false,"internalType":"string","name":"newUriPrefix","type":"string"},{"indexed":false,"internalType":"string","name":"newUriSuffix","type":"string"}],"name":"BaseURIChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"bottleIds","type":"uint256[]"}],"name":"BottlesUsed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newPresalePrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newPublicPrice","type":"uint256"}],"name":"PricesChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bottleContract","outputs":[{"internalType":"contract ERC721A","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"bottleIds","type":"uint256[]"}],"name":"bottlePresaleMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"bottleUsed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"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":[],"name":"presaleEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"presaleMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"presalePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicSaleEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"reserveTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"wallets","type":"address[]"},{"internalType":"bool[]","name":"values","type":"bool[]"}],"name":"setAdmins","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newUriPrefix","type":"string"},{"internalType":"string","name":"newUriSuffix","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ERC721A","name":"_bottleContract","type":"address"}],"name":"setBottleContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newDev","type":"address"}],"name":"setDev","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPresalePrice","type":"uint256"},{"internalType":"uint256","name":"newPublicPrice","type":"uint256"}],"name":"setPrices","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signerAddress","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_walletLimit","type":"uint256"}],"name":"setWalletLimit","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":"bool","name":"_presaleEnabled","type":"bool"},{"internalType":"bool","name":"_publicSaleEnabled","type":"bool"}],"name":"toggleMinting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokensReserved","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"walletLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"walletMints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

608060405267016345785d8a000060095567011c37937e080000600a556002600b5560405180602001604052806000815250601090816200004191906200058f565b5060405180602001604052806000815250601190816200006291906200058f565b5073db4aac095f709a62ec24479404fae45d24ade34b601260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507377bfcca6f45b07047a34a31885af86f11033665b601360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550730f7cce027e0afe16fbf0dcc8e76932845b4e21d1601460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503480156200016f57600080fd5b506040518060400160405280601481526020017f426f72656420477261706573202d2056696e65730000000000000000000000008152506040518060400160405280600281526020017f42470000000000000000000000000000000000000000000000000000000000008152508160029081620001ed91906200058f565b508060039081620001ff91906200058f565b50620002106200023e60201b60201c565b6000819055505050620002386200022c6200024760201b60201c565b6200024f60201b60201c565b62000676565b60006001905090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200039757607f821691505b602082108103620003ad57620003ac6200034f565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620004177fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620003d8565b620004238683620003d8565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620004706200046a62000464846200043b565b62000445565b6200043b565b9050919050565b6000819050919050565b6200048c836200044f565b620004a46200049b8262000477565b848454620003e5565b825550505050565b600090565b620004bb620004ac565b620004c881848462000481565b505050565b5b81811015620004f057620004e4600082620004b1565b600181019050620004ce565b5050565b601f8211156200053f576200050981620003b3565b6200051484620003c8565b8101602085101562000524578190505b6200053c6200053385620003c8565b830182620004cd565b50505b505050565b600082821c905092915050565b6000620005646000198460080262000544565b1980831691505092915050565b60006200057f838362000551565b9150826002028217905092915050565b6200059a8262000315565b67ffffffffffffffff811115620005b657620005b562000320565b5b620005c282546200037e565b620005cf828285620004f4565b600060209050601f831160018114620006075760008415620005f2578287015190505b620005fe858262000571565b8655506200066e565b601f1984166200061786620003b3565b60005b8281101562000641578489015182556001820191506020850194506020810190506200061a565b868310156200066157848901516200065d601f89168262000551565b8355505b6001600288020188555050505b505050505050565b614a2d80620006866000396000f3fe60806040526004361061023a5760003560e01c80636790a9de1161012e578063a945bf80116100ab578063f0293fd31161006f578063f0293fd314610866578063f1d5f517146108a3578063f2fde38b146108cc578063f997cbec146108f5578063fd24a8541461091e5761023a565b8063a945bf801461076f578063b88d4fde1461079a578063c87b56dd146107c3578063d477f05f14610800578063e985e9c5146108295761023a565b80638da5cb5b116100f25780638da5cb5b1461069757806391840bc7146106c257806395d89b41146106de5780639c95ad8514610709578063a22cb465146107465761023a565b80636790a9de146105c85780636c19e783146105f157806370a082311461061a578063715018a61461065757806378cf19e91461066e5761023a565b80632ab91bba116101bc57806340c10f191161018057806340c10f19146104f257806342842e0e1461050e578063433adb05146105375780634a6ba2f1146105625780636352211e1461058b5761023a565b80632ab91bba1461041d5780633085afe21461044857806332cb6b0c1461047157806333bd97241461049c5780633c8463a1146104c75761023a565b8063095ea7b311610203578063095ea7b314610338578063143b237f1461036157806318160ddd1461038c57806323b872dd146103b757806324d7806c146103e05761023a565b80620e7fa81461023f57806301ffc9a71461026a57806305fefda7146102a757806306fdde03146102d0578063081812fc146102fb575b600080fd5b34801561024b57600080fd5b5061025461093a565b6040516102619190612c27565b60405180910390f35b34801561027657600080fd5b50610291600480360381019061028c9190612cae565b610940565b60405161029e9190612cf6565b60405180910390f35b3480156102b357600080fd5b506102ce60048036038101906102c99190612d3d565b6109d2565b005b3480156102dc57600080fd5b506102e5610a25565b6040516102f29190612e0d565b60405180910390f35b34801561030757600080fd5b50610322600480360381019061031d9190612e2f565b610ab7565b60405161032f9190612e9d565b60405180910390f35b34801561034457600080fd5b5061035f600480360381019061035a9190612ee4565b610b36565b005b34801561036d57600080fd5b50610376610c7a565b6040516103839190612cf6565b60405180910390f35b34801561039857600080fd5b506103a1610c8d565b6040516103ae9190612c27565b60405180910390f35b3480156103c357600080fd5b506103de60048036038101906103d99190612f24565b610ca4565b005b3480156103ec57600080fd5b5061040760048036038101906104029190612f77565b610fc6565b6040516104149190612cf6565b60405180910390f35b34801561042957600080fd5b50610432610fe6565b60405161043f9190612cf6565b60405180910390f35b34801561045457600080fd5b5061046f600480360381019061046a9190612fe2565b610ff9565b005b34801561047d57600080fd5b50610486611045565b6040516104939190612c27565b60405180910390f35b3480156104a857600080fd5b506104b161104b565b6040516104be919061306e565b60405180910390f35b3480156104d357600080fd5b506104dc611071565b6040516104e99190612c27565b60405180910390f35b61050c60048036038101906105079190612ee4565b611077565b005b34801561051a57600080fd5b5061053560048036038101906105309190612f24565b6110d7565b005b34801561054357600080fd5b5061054c6110f7565b6040516105599190612c27565b60405180910390f35b34801561056e57600080fd5b5061058960048036038101906105849190613144565b6110fd565b005b34801561059757600080fd5b506105b260048036038101906105ad9190612e2f565b61129d565b6040516105bf9190612e9d565b60405180910390f35b3480156105d457600080fd5b506105ef60048036038101906105ea91906132f5565b6112af565b005b3480156105fd57600080fd5b5061061860048036038101906106139190612f77565b611314565b005b34801561062657600080fd5b50610641600480360381019061063c9190612f77565b611360565b60405161064e9190612c27565b60405180910390f35b34801561066357600080fd5b5061066c611418565b005b34801561067a57600080fd5b5061069560048036038101906106909190612ee4565b61142c565b005b3480156106a357600080fd5b506106ac6114ac565b6040516106b99190612e9d565b60405180910390f35b6106dc60048036038101906106d791906133c3565b6114d6565b005b3480156106ea57600080fd5b506106f361177e565b6040516107009190612e0d565b60405180910390f35b34801561071557600080fd5b50610730600480360381019061072b9190612e2f565b611810565b60405161073d9190612cf6565b60405180910390f35b34801561075257600080fd5b5061076d6004803603810190610768919061343c565b611830565b005b34801561077b57600080fd5b506107846119a7565b6040516107919190612c27565b60405180910390f35b3480156107a657600080fd5b506107c160048036038101906107bc919061351d565b6119ad565b005b3480156107cf57600080fd5b506107ea60048036038101906107e59190612e2f565b611a20565b6040516107f79190612e0d565b60405180910390f35b34801561080c57600080fd5b5061082760048036038101906108229190612f77565b611acb565b005b34801561083557600080fd5b50610850600480360381019061084b91906135a0565b611b17565b60405161085d9190612cf6565b60405180910390f35b34801561087257600080fd5b5061088d60048036038101906108889190612f77565b611bab565b60405161089a9190612c27565b60405180910390f35b3480156108af57600080fd5b506108ca60048036038101906108c59190612e2f565b611bc3565b005b3480156108d857600080fd5b506108f360048036038101906108ee9190612f77565b611bd5565b005b34801561090157600080fd5b5061091c600480360381019061091791906135e0565b611c58565b005b61093860048036038101906109339190613620565b611c98565b005b600a5481565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061099b57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806109cb5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6109da611e28565b81600a81905550806009819055507f80aade646210706e24b438e253bdb9596f344bc718597854cba4a597f4db8f938282604051610a1992919061367c565b60405180910390a15050565b606060028054610a34906136d4565b80601f0160208091040260200160405190810160405280929190818152602001828054610a60906136d4565b8015610aad5780601f10610a8257610100808354040283529160200191610aad565b820191906000526020600020905b815481529060010190602001808311610a9057829003601f168201915b5050505050905090565b6000610ac282611ef7565b610af8576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610b418261129d565b90508073ffffffffffffffffffffffffffffffffffffffff16610b62611f56565b73ffffffffffffffffffffffffffffffffffffffff1614610bc557610b8e81610b89611f56565b611b17565b610bc4576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600c60019054906101000a900460ff1681565b6000610c97611f5e565b6001546000540303905090565b6000610caf82611f67565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610d16576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610d2284612033565b91509150610d388187610d33611f56565b61205a565b610d8457610d4d86610d48611f56565b611b17565b610d83576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610dea576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610df7868686600161209e565b8015610e0257600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610ed085610eac8888876120a4565b7c0200000000000000000000000000000000000000000000000000000000176120cc565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610f565760006001850190506000600460008381526020019081526020016000205403610f54576000548114610f53578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610fbe86868660016120f7565b505050505050565b60156020528060005260406000206000915054906101000a900460ff1681565b600c60009054906101000a900460ff1681565b611001611e28565b80601460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6115b381565b601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b5481565b600c60009054906101000a900460ff166110c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110bd90613751565b60405180910390fd5b6110d382826009546120fd565b5050565b6110f2838383604051806020016040528060008152506119ad565b505050565b600f5481565b611105612254565b81819050848490501461114d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611144906137bd565b60405180910390fd5b60008484905011611193576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118a90613829565b60405180910390fd5b60005b84849050811015611259578282828181106111b4576111b3613849565b5b90506020020160208101906111c99190613878565b601560008787858181106111e0576111df613849565b5b90506020020160208101906111f59190612f77565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611251906138d4565b915050611196565b507fb752570d2b30ffb4f019c0c5ff6e2f0673ed3440d25b9752487c814789b94f9d8484848460405161128f9493929190613aa2565b60405180910390a150505050565b60006112a882611f67565b9050919050565b6112b7611e28565b81601090816112c69190613c7f565b5080601190816112d69190613c7f565b507fc41b7cb64e5be01af4afc2641afc861432136270f4206b7773f229b658b966998282604051611308929190613d51565b60405180910390a15050565b61131c611e28565b80601360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036113c7576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b611420612254565b61142a60006122d2565b565b611434612254565b609681600f546114449190613d88565b1115611485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161147c90613e08565b60405180910390fd5b80600f60008282546114979190613d88565b925050819055506114a88282612398565b5050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600c60019054906101000a900460ff16611525576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151c90613e74565b60405180910390fd5b60005b82829050811015611727573373ffffffffffffffffffffffffffffffffffffffff16601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e85858581811061159b5761159a613849565b5b905060200201356040518263ffffffff1660e01b81526004016115be9190612c27565b602060405180830381865afa1580156115db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ff9190613ea9565b73ffffffffffffffffffffffffffffffffffffffff1614611655576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164c90613f48565b60405180910390fd5b600e600084848481811061166c5761166b613849565b5b90506020020135815260200190815260200160002060009054906101000a900460ff16156116cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116c690613fb4565b60405180910390fd5b6001600e60008585858181106116e8576116e7613849565b5b90506020020135815260200190815260200160002060006101000a81548160ff021916908315150217905550808061171f906138d4565b915050611528565b506117383383839050600a546120fd565b7fb9488f4fcc28b58228f056a73c5a4eac0bc5c3aaa95d2c5af05d16a8ea3b50c4611761612553565b83836040516117729392919061404f565b60405180910390a15050565b60606003805461178d906136d4565b80601f01602080910402602001604051908101604052809291908181526020018280546117b9906136d4565b80156118065780601f106117db57610100808354040283529160200191611806565b820191906000526020600020905b8154815290600101906020018083116117e957829003601f168201915b5050505050905090565b600e6020528060005260406000206000915054906101000a900460ff1681565b611838611f56565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361189c576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600760006118a9611f56565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611956611f56565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161199b9190612cf6565b60405180910390a35050565b60095481565b6119b8848484610ca4565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611a1a576119e384848484612566565b611a19576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6060611a2b82611ef7565b611a6a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a61906140f3565b60405180910390fd5b600060108054611a79906136d4565b905011611a955760405180602001604052806000815250611ac4565b6010611aa0836126b6565b6011604051602001611ab4939291906141d2565b6040516020818303038152906040525b9050919050565b611ad3612254565b80601260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600d6020528060005260406000206000915090505481565b611bcb611e28565b80600b8190555050565b611bdd612254565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611c4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c4390614275565b60405180910390fd5b611c55816122d2565b50565b611c60611e28565b81600c60016101000a81548160ff02191690831515021790555080600c60006101000a81548160ff0219169083151502179055505050565b600c60019054906101000a900460ff16611ce7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cde90613e74565b60405180910390fd5b611cf9611cf333612784565b826127da565b73ffffffffffffffffffffffffffffffffffffffff16601360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611d88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7f906142e1565b60405180910390fd5b600b5482600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611dd69190613d88565b1115611e17576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e0e90614373565b60405180910390fd5b611e2433836009546120fd565b5050565b3373ffffffffffffffffffffffffffffffffffffffff16611e476114ac565b73ffffffffffffffffffffffffffffffffffffffff161480611eb657503373ffffffffffffffffffffffffffffffffffffffff16601260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b611ef5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eec906143df565b60405180910390fd5b565b600081611f02611f5e565b11158015611f11575060005482105b8015611f4f575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b60006001905090565b60008082905080611f76611f5e565b11611ffc57600054811015611ffb5760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603611ff9575b60008103611fef576004600083600190039350838152602001908152602001600020549050611fc5565b809250505061202e565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e86120bb868684612801565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6115b382612109610c8d565b6121139190613d88565b1115612154576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161214b9061444b565b60405180910390fd5b348282612161919061446b565b146121a1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612198906144f9565b60405180910390fd5b6121a96114ac565b73ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050501580156121ee573d6000803e3d6000fd5b506121f98383612398565b81600d60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546122489190613d88565b92505081905550505050565b61225c61280a565b73ffffffffffffffffffffffffffffffffffffffff1661227a6114ac565b73ffffffffffffffffffffffffffffffffffffffff16146122d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c790614565565b60405180910390fd5b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080549050600082036123d8576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123e5600084838561209e565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061245c8361244d60008660006120a4565b61245685612812565b176120cc565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146124fd57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a46001810190506124c2565b5060008203612538576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505061254e60008483856120f7565b505050565b600061255d611f5e565b60005403905090565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261258c611f56565b8786866040518563ffffffff1660e01b81526004016125ae94939291906145da565b6020604051808303816000875af19250505080156125ea57506040513d601f19601f820116820180604052508101906125e7919061463b565b60015b612663573d806000811461261a576040519150601f19603f3d011682016040523d82523d6000602084013e61261f565b606091505b50600081510361265b576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600060016126c584612822565b01905060008167ffffffffffffffff8111156126e4576126e36131ca565b5b6040519080825280601f01601f1916602001820160405280156127165781602001600182028036833780820191505090505b509050600082602001820190505b600115612779578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161276d5761276c614668565b5b04945060008503612724575b819350505050919050565b600081604051602001612797919061472b565b604051602081830303815290604052805190602001206040516020016127bd91906147c8565b604051602081830303815290604052805190602001209050919050565b60008060006127e98585612975565b915091506127f6816129c6565b819250505092915050565b60009392505050565b600033905090565b60006001821460e11b9050919050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612880577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161287657612875614668565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106128bd576d04ee2d6d415b85acef810000000083816128b3576128b2614668565b5b0492506020810190505b662386f26fc1000083106128ec57662386f26fc1000083816128e2576128e1614668565b5b0492506010810190505b6305f5e1008310612915576305f5e100838161290b5761290a614668565b5b0492506008810190505b612710831061293a5761271083816129305761292f614668565b5b0492506004810190505b6064831061295d576064838161295357612952614668565b5b0492506002810190505b600a831061296c576001810190505b80915050919050565b60008060418351036129b65760008060006020860151925060408601519150606086015160001a90506129aa87828585612b2c565b945094505050506129bf565b60006002915091505b9250929050565b600060048111156129da576129d96147ee565b5b8160048111156129ed576129ec6147ee565b5b0315612b295760016004811115612a0757612a066147ee565b5b816004811115612a1a57612a196147ee565b5b03612a5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a5190614869565b60405180910390fd5b60026004811115612a6e57612a6d6147ee565b5b816004811115612a8157612a806147ee565b5b03612ac1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ab8906148d5565b60405180910390fd5b60036004811115612ad557612ad46147ee565b5b816004811115612ae857612ae76147ee565b5b03612b28576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b1f90614967565b60405180910390fd5b5b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c1115612b67576000600391509150612c05565b600060018787878760405160008152602001604052604051612b8c94939291906149b2565b6020604051602081039080840390855afa158015612bae573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612bfc57600060019250925050612c05565b80600092509250505b94509492505050565b6000819050919050565b612c2181612c0e565b82525050565b6000602082019050612c3c6000830184612c18565b92915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612c8b81612c56565b8114612c9657600080fd5b50565b600081359050612ca881612c82565b92915050565b600060208284031215612cc457612cc3612c4c565b5b6000612cd284828501612c99565b91505092915050565b60008115159050919050565b612cf081612cdb565b82525050565b6000602082019050612d0b6000830184612ce7565b92915050565b612d1a81612c0e565b8114612d2557600080fd5b50565b600081359050612d3781612d11565b92915050565b60008060408385031215612d5457612d53612c4c565b5b6000612d6285828601612d28565b9250506020612d7385828601612d28565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612db7578082015181840152602081019050612d9c565b60008484015250505050565b6000601f19601f8301169050919050565b6000612ddf82612d7d565b612de98185612d88565b9350612df9818560208601612d99565b612e0281612dc3565b840191505092915050565b60006020820190508181036000830152612e278184612dd4565b905092915050565b600060208284031215612e4557612e44612c4c565b5b6000612e5384828501612d28565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612e8782612e5c565b9050919050565b612e9781612e7c565b82525050565b6000602082019050612eb26000830184612e8e565b92915050565b612ec181612e7c565b8114612ecc57600080fd5b50565b600081359050612ede81612eb8565b92915050565b60008060408385031215612efb57612efa612c4c565b5b6000612f0985828601612ecf565b9250506020612f1a85828601612d28565b9150509250929050565b600080600060608486031215612f3d57612f3c612c4c565b5b6000612f4b86828701612ecf565b9350506020612f5c86828701612ecf565b9250506040612f6d86828701612d28565b9150509250925092565b600060208284031215612f8d57612f8c612c4c565b5b6000612f9b84828501612ecf565b91505092915050565b6000612faf82612e7c565b9050919050565b612fbf81612fa4565b8114612fca57600080fd5b50565b600081359050612fdc81612fb6565b92915050565b600060208284031215612ff857612ff7612c4c565b5b600061300684828501612fcd565b91505092915050565b6000819050919050565b600061303461302f61302a84612e5c565b61300f565b612e5c565b9050919050565b600061304682613019565b9050919050565b60006130588261303b565b9050919050565b6130688161304d565b82525050565b6000602082019050613083600083018461305f565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126130ae576130ad613089565b5b8235905067ffffffffffffffff8111156130cb576130ca61308e565b5b6020830191508360208202830111156130e7576130e6613093565b5b9250929050565b60008083601f84011261310457613103613089565b5b8235905067ffffffffffffffff8111156131215761312061308e565b5b60208301915083602082028301111561313d5761313c613093565b5b9250929050565b6000806000806040858703121561315e5761315d612c4c565b5b600085013567ffffffffffffffff81111561317c5761317b612c51565b5b61318887828801613098565b9450945050602085013567ffffffffffffffff8111156131ab576131aa612c51565b5b6131b7878288016130ee565b925092505092959194509250565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61320282612dc3565b810181811067ffffffffffffffff82111715613221576132206131ca565b5b80604052505050565b6000613234612c42565b905061324082826131f9565b919050565b600067ffffffffffffffff8211156132605761325f6131ca565b5b61326982612dc3565b9050602081019050919050565b82818337600083830152505050565b600061329861329384613245565b61322a565b9050828152602081018484840111156132b4576132b36131c5565b5b6132bf848285613276565b509392505050565b600082601f8301126132dc576132db613089565b5b81356132ec848260208601613285565b91505092915050565b6000806040838503121561330c5761330b612c4c565b5b600083013567ffffffffffffffff81111561332a57613329612c51565b5b613336858286016132c7565b925050602083013567ffffffffffffffff81111561335757613356612c51565b5b613363858286016132c7565b9150509250929050565b60008083601f84011261338357613382613089565b5b8235905067ffffffffffffffff8111156133a05761339f61308e565b5b6020830191508360208202830111156133bc576133bb613093565b5b9250929050565b600080602083850312156133da576133d9612c4c565b5b600083013567ffffffffffffffff8111156133f8576133f7612c51565b5b6134048582860161336d565b92509250509250929050565b61341981612cdb565b811461342457600080fd5b50565b60008135905061343681613410565b92915050565b6000806040838503121561345357613452612c4c565b5b600061346185828601612ecf565b925050602061347285828601613427565b9150509250929050565b600067ffffffffffffffff821115613497576134966131ca565b5b6134a082612dc3565b9050602081019050919050565b60006134c06134bb8461347c565b61322a565b9050828152602081018484840111156134dc576134db6131c5565b5b6134e7848285613276565b509392505050565b600082601f83011261350457613503613089565b5b81356135148482602086016134ad565b91505092915050565b6000806000806080858703121561353757613536612c4c565b5b600061354587828801612ecf565b945050602061355687828801612ecf565b935050604061356787828801612d28565b925050606085013567ffffffffffffffff81111561358857613587612c51565b5b613594878288016134ef565b91505092959194509250565b600080604083850312156135b7576135b6612c4c565b5b60006135c585828601612ecf565b92505060206135d685828601612ecf565b9150509250929050565b600080604083850312156135f7576135f6612c4c565b5b600061360585828601613427565b925050602061361685828601613427565b9150509250929050565b6000806040838503121561363757613636612c4c565b5b600061364585828601612d28565b925050602083013567ffffffffffffffff81111561366657613665612c51565b5b613672858286016134ef565b9150509250929050565b60006040820190506136916000830185612c18565b61369e6020830184612c18565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806136ec57607f821691505b6020821081036136ff576136fe6136a5565b5b50919050565b7f5075626c6963206d696e74696e672064697361626c6564000000000000000000600082015250565b600061373b601783612d88565b915061374682613705565b602082019050919050565b6000602082019050818103600083015261376a8161372e565b9050919050565b7f417272617920617265206f6620646966666572656e742073697a650000000000600082015250565b60006137a7601b83612d88565b91506137b282613771565b602082019050919050565b600060208201905081810360008301526137d68161379a565b9050919050565b7f4172726179732061726520656d70747900000000000000000000000000000000600082015250565b6000613813601083612d88565b915061381e826137dd565b602082019050919050565b6000602082019050818103600083015261384281613806565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561388e5761388d612c4c565b5b600061389c84828501613427565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006138df82612c0e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613911576139106138a5565b5b600182019050919050565b600082825260208201905092915050565b6000819050919050565b61394081612e7c565b82525050565b60006139528383613937565b60208301905092915050565b600061396d6020840184612ecf565b905092915050565b6000602082019050919050565b600061398e838561391c565b93506139998261392d565b8060005b858110156139d2576139af828461395e565b6139b98882613946565b97506139c483613975565b92505060018101905061399d565b5085925050509392505050565b600082825260208201905092915050565b6000819050919050565b613a0381612cdb565b82525050565b6000613a1583836139fa565b60208301905092915050565b6000613a306020840184613427565b905092915050565b6000602082019050919050565b6000613a5183856139df565b9350613a5c826139f0565b8060005b85811015613a9557613a728284613a21565b613a7c8882613a09565b9750613a8783613a38565b925050600181019050613a60565b5085925050509392505050565b60006040820190508181036000830152613abd818688613982565b90508181036020830152613ad2818486613a45565b905095945050505050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302613b3f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613b02565b613b498683613b02565b95508019841693508086168417925050509392505050565b6000613b7c613b77613b7284612c0e565b61300f565b612c0e565b9050919050565b6000819050919050565b613b9683613b61565b613baa613ba282613b83565b848454613b0f565b825550505050565b600090565b613bbf613bb2565b613bca818484613b8d565b505050565b5b81811015613bee57613be3600082613bb7565b600181019050613bd0565b5050565b601f821115613c3357613c0481613add565b613c0d84613af2565b81016020851015613c1c578190505b613c30613c2885613af2565b830182613bcf565b50505b505050565b600082821c905092915050565b6000613c5660001984600802613c38565b1980831691505092915050565b6000613c6f8383613c45565b9150826002028217905092915050565b613c8882612d7d565b67ffffffffffffffff811115613ca157613ca06131ca565b5b613cab82546136d4565b613cb6828285613bf2565b600060209050601f831160018114613ce95760008415613cd7578287015190505b613ce18582613c63565b865550613d49565b601f198416613cf786613add565b60005b82811015613d1f57848901518255600182019150602085019450602081019050613cfa565b86831015613d3c5784890151613d38601f891682613c45565b8355505b6001600288020188555050505b505050505050565b60006040820190508181036000830152613d6b8185612dd4565b90508181036020830152613d7f8184612dd4565b90509392505050565b6000613d9382612c0e565b9150613d9e83612c0e565b9250828201905080821115613db657613db56138a5565b5b92915050565b7f63616e6e6f742072657365727665206d6f726500000000000000000000000000600082015250565b6000613df2601383612d88565b9150613dfd82613dbc565b602082019050919050565b60006020820190508181036000830152613e2181613de5565b9050919050565b7f50726573616c65206d696e74696e672064697361626c65640000000000000000600082015250565b6000613e5e601883612d88565b9150613e6982613e28565b602082019050919050565b60006020820190508181036000830152613e8d81613e51565b9050919050565b600081519050613ea381612eb8565b92915050565b600060208284031215613ebf57613ebe612c4c565b5b6000613ecd84828501613e94565b91505092915050565b7f4164647265737320746f206973206e6f74206f776e6572206f6620626f74746c60008201527f6549640000000000000000000000000000000000000000000000000000000000602082015250565b6000613f32602383612d88565b9150613f3d82613ed6565b604082019050919050565b60006020820190508181036000830152613f6181613f25565b9050919050565b7f426f74746c6549642068617320616c7265616479206265656e20757365640000600082015250565b6000613f9e601e83612d88565b9150613fa982613f68565b602082019050919050565b60006020820190508181036000830152613fcd81613f91565b9050919050565b600082825260208201905092915050565b600080fd5b82818337505050565b6000613fff8385613fd4565b93507f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561403257614031613fe5565b5b602083029250614043838584613fea565b82840190509392505050565b60006040820190506140646000830186612c18565b8181036020830152614077818486613ff3565b9050949350505050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b60006140dd602f83612d88565b91506140e882614081565b604082019050919050565b6000602082019050818103600083015261410c816140d0565b9050919050565b600081905092915050565b6000815461412b816136d4565b6141358186614113565b94506001821660008114614150576001811461416557614198565b60ff1983168652811515820286019350614198565b61416e85613add565b60005b8381101561419057815481890152600182019150602081019050614171565b838801955050505b50505092915050565b60006141ac82612d7d565b6141b68185614113565b93506141c6818560208601612d99565b80840191505092915050565b60006141de828661411e565b91506141ea82856141a1565b91506141f6828461411e565b9150819050949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061425f602683612d88565b915061426a82614203565b604082019050919050565b6000602082019050818103600083015261428e81614252565b9050919050565b7f696e76616c69642068617368206f72207369676e617475726500000000000000600082015250565b60006142cb601983612d88565b91506142d682614295565b602082019050919050565b600060208201905081810360008301526142fa816142be565b9050919050565b7f43616e6e6f74206d696e74206d6f7265207468616e2077616c6c65744c696d6960008201527f7400000000000000000000000000000000000000000000000000000000000000602082015250565b600061435d602183612d88565b915061436882614301565b604082019050919050565b6000602082019050818103600083015261438c81614350565b9050919050565b7f5369676e6572206973206e6f7420646576206e6f72206f776e65720000000000600082015250565b60006143c9601b83612d88565b91506143d482614393565b602082019050919050565b600060208201905081810360008301526143f8816143bc565b9050919050565b7f4d617820737570706c7920657863656564656400000000000000000000000000600082015250565b6000614435601383612d88565b9150614440826143ff565b602082019050919050565b6000602082019050818103600083015261446481614428565b9050919050565b600061447682612c0e565b915061448183612c0e565b925082820261448f81612c0e565b915082820484148315176144a6576144a56138a5565b5b5092915050565b7f696e76616c6964206574682076616c7565000000000000000000000000000000600082015250565b60006144e3601183612d88565b91506144ee826144ad565b602082019050919050565b60006020820190508181036000830152614512816144d6565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061454f602083612d88565b915061455a82614519565b602082019050919050565b6000602082019050818103600083015261457e81614542565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006145ac82614585565b6145b68185614590565b93506145c6818560208601612d99565b6145cf81612dc3565b840191505092915050565b60006080820190506145ef6000830187612e8e565b6145fc6020830186612e8e565b6146096040830185612c18565b818103606083015261461b81846145a1565b905095945050505050565b60008151905061463581612c82565b92915050565b60006020828403121561465157614650612c4c565b5b600061465f84828501614626565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f426f72656447726170657356696e657300000000000000000000000000000000600082015250565b60006146cd601083614113565b91506146d882614697565b601082019050919050565b60008160601b9050919050565b60006146fb826146e3565b9050919050565b600061470d826146f0565b9050919050565b61472561472082612e7c565b614702565b82525050565b6000614736826146c0565b91506147428284614714565b60148201915081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000614787601c83614113565b915061479282614751565b601c82019050919050565b6000819050919050565b6000819050919050565b6147c26147bd8261479d565b6147a7565b82525050565b60006147d38261477a565b91506147df82846147b1565b60208201915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b6000614853601883612d88565b915061485e8261481d565b602082019050919050565b6000602082019050818103600083015261488281614846565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b60006148bf601f83612d88565b91506148ca82614889565b602082019050919050565b600060208201905081810360008301526148ee816148b2565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000614951602283612d88565b915061495c826148f5565b604082019050919050565b6000602082019050818103600083015261498081614944565b9050919050565b6149908161479d565b82525050565b600060ff82169050919050565b6149ac81614996565b82525050565b60006080820190506149c76000830187614987565b6149d460208301866149a3565b6149e16040830185614987565b6149ee6060830184614987565b9594505050505056fea2646970667358221220b0d054cab5eeeec004d19edbdd39789cf15dc621629a38c2bd4fb2e53a9e70ad64736f6c63430008110033

Deployed Bytecode

0x60806040526004361061023a5760003560e01c80636790a9de1161012e578063a945bf80116100ab578063f0293fd31161006f578063f0293fd314610866578063f1d5f517146108a3578063f2fde38b146108cc578063f997cbec146108f5578063fd24a8541461091e5761023a565b8063a945bf801461076f578063b88d4fde1461079a578063c87b56dd146107c3578063d477f05f14610800578063e985e9c5146108295761023a565b80638da5cb5b116100f25780638da5cb5b1461069757806391840bc7146106c257806395d89b41146106de5780639c95ad8514610709578063a22cb465146107465761023a565b80636790a9de146105c85780636c19e783146105f157806370a082311461061a578063715018a61461065757806378cf19e91461066e5761023a565b80632ab91bba116101bc57806340c10f191161018057806340c10f19146104f257806342842e0e1461050e578063433adb05146105375780634a6ba2f1146105625780636352211e1461058b5761023a565b80632ab91bba1461041d5780633085afe21461044857806332cb6b0c1461047157806333bd97241461049c5780633c8463a1146104c75761023a565b8063095ea7b311610203578063095ea7b314610338578063143b237f1461036157806318160ddd1461038c57806323b872dd146103b757806324d7806c146103e05761023a565b80620e7fa81461023f57806301ffc9a71461026a57806305fefda7146102a757806306fdde03146102d0578063081812fc146102fb575b600080fd5b34801561024b57600080fd5b5061025461093a565b6040516102619190612c27565b60405180910390f35b34801561027657600080fd5b50610291600480360381019061028c9190612cae565b610940565b60405161029e9190612cf6565b60405180910390f35b3480156102b357600080fd5b506102ce60048036038101906102c99190612d3d565b6109d2565b005b3480156102dc57600080fd5b506102e5610a25565b6040516102f29190612e0d565b60405180910390f35b34801561030757600080fd5b50610322600480360381019061031d9190612e2f565b610ab7565b60405161032f9190612e9d565b60405180910390f35b34801561034457600080fd5b5061035f600480360381019061035a9190612ee4565b610b36565b005b34801561036d57600080fd5b50610376610c7a565b6040516103839190612cf6565b60405180910390f35b34801561039857600080fd5b506103a1610c8d565b6040516103ae9190612c27565b60405180910390f35b3480156103c357600080fd5b506103de60048036038101906103d99190612f24565b610ca4565b005b3480156103ec57600080fd5b5061040760048036038101906104029190612f77565b610fc6565b6040516104149190612cf6565b60405180910390f35b34801561042957600080fd5b50610432610fe6565b60405161043f9190612cf6565b60405180910390f35b34801561045457600080fd5b5061046f600480360381019061046a9190612fe2565b610ff9565b005b34801561047d57600080fd5b50610486611045565b6040516104939190612c27565b60405180910390f35b3480156104a857600080fd5b506104b161104b565b6040516104be919061306e565b60405180910390f35b3480156104d357600080fd5b506104dc611071565b6040516104e99190612c27565b60405180910390f35b61050c60048036038101906105079190612ee4565b611077565b005b34801561051a57600080fd5b5061053560048036038101906105309190612f24565b6110d7565b005b34801561054357600080fd5b5061054c6110f7565b6040516105599190612c27565b60405180910390f35b34801561056e57600080fd5b5061058960048036038101906105849190613144565b6110fd565b005b34801561059757600080fd5b506105b260048036038101906105ad9190612e2f565b61129d565b6040516105bf9190612e9d565b60405180910390f35b3480156105d457600080fd5b506105ef60048036038101906105ea91906132f5565b6112af565b005b3480156105fd57600080fd5b5061061860048036038101906106139190612f77565b611314565b005b34801561062657600080fd5b50610641600480360381019061063c9190612f77565b611360565b60405161064e9190612c27565b60405180910390f35b34801561066357600080fd5b5061066c611418565b005b34801561067a57600080fd5b5061069560048036038101906106909190612ee4565b61142c565b005b3480156106a357600080fd5b506106ac6114ac565b6040516106b99190612e9d565b60405180910390f35b6106dc60048036038101906106d791906133c3565b6114d6565b005b3480156106ea57600080fd5b506106f361177e565b6040516107009190612e0d565b60405180910390f35b34801561071557600080fd5b50610730600480360381019061072b9190612e2f565b611810565b60405161073d9190612cf6565b60405180910390f35b34801561075257600080fd5b5061076d6004803603810190610768919061343c565b611830565b005b34801561077b57600080fd5b506107846119a7565b6040516107919190612c27565b60405180910390f35b3480156107a657600080fd5b506107c160048036038101906107bc919061351d565b6119ad565b005b3480156107cf57600080fd5b506107ea60048036038101906107e59190612e2f565b611a20565b6040516107f79190612e0d565b60405180910390f35b34801561080c57600080fd5b5061082760048036038101906108229190612f77565b611acb565b005b34801561083557600080fd5b50610850600480360381019061084b91906135a0565b611b17565b60405161085d9190612cf6565b60405180910390f35b34801561087257600080fd5b5061088d60048036038101906108889190612f77565b611bab565b60405161089a9190612c27565b60405180910390f35b3480156108af57600080fd5b506108ca60048036038101906108c59190612e2f565b611bc3565b005b3480156108d857600080fd5b506108f360048036038101906108ee9190612f77565b611bd5565b005b34801561090157600080fd5b5061091c600480360381019061091791906135e0565b611c58565b005b61093860048036038101906109339190613620565b611c98565b005b600a5481565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061099b57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806109cb5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6109da611e28565b81600a81905550806009819055507f80aade646210706e24b438e253bdb9596f344bc718597854cba4a597f4db8f938282604051610a1992919061367c565b60405180910390a15050565b606060028054610a34906136d4565b80601f0160208091040260200160405190810160405280929190818152602001828054610a60906136d4565b8015610aad5780601f10610a8257610100808354040283529160200191610aad565b820191906000526020600020905b815481529060010190602001808311610a9057829003601f168201915b5050505050905090565b6000610ac282611ef7565b610af8576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610b418261129d565b90508073ffffffffffffffffffffffffffffffffffffffff16610b62611f56565b73ffffffffffffffffffffffffffffffffffffffff1614610bc557610b8e81610b89611f56565b611b17565b610bc4576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600c60019054906101000a900460ff1681565b6000610c97611f5e565b6001546000540303905090565b6000610caf82611f67565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610d16576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610d2284612033565b91509150610d388187610d33611f56565b61205a565b610d8457610d4d86610d48611f56565b611b17565b610d83576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610dea576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610df7868686600161209e565b8015610e0257600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610ed085610eac8888876120a4565b7c0200000000000000000000000000000000000000000000000000000000176120cc565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610f565760006001850190506000600460008381526020019081526020016000205403610f54576000548114610f53578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610fbe86868660016120f7565b505050505050565b60156020528060005260406000206000915054906101000a900460ff1681565b600c60009054906101000a900460ff1681565b611001611e28565b80601460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6115b381565b601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b5481565b600c60009054906101000a900460ff166110c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110bd90613751565b60405180910390fd5b6110d382826009546120fd565b5050565b6110f2838383604051806020016040528060008152506119ad565b505050565b600f5481565b611105612254565b81819050848490501461114d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611144906137bd565b60405180910390fd5b60008484905011611193576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118a90613829565b60405180910390fd5b60005b84849050811015611259578282828181106111b4576111b3613849565b5b90506020020160208101906111c99190613878565b601560008787858181106111e0576111df613849565b5b90506020020160208101906111f59190612f77565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611251906138d4565b915050611196565b507fb752570d2b30ffb4f019c0c5ff6e2f0673ed3440d25b9752487c814789b94f9d8484848460405161128f9493929190613aa2565b60405180910390a150505050565b60006112a882611f67565b9050919050565b6112b7611e28565b81601090816112c69190613c7f565b5080601190816112d69190613c7f565b507fc41b7cb64e5be01af4afc2641afc861432136270f4206b7773f229b658b966998282604051611308929190613d51565b60405180910390a15050565b61131c611e28565b80601360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036113c7576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b611420612254565b61142a60006122d2565b565b611434612254565b609681600f546114449190613d88565b1115611485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161147c90613e08565b60405180910390fd5b80600f60008282546114979190613d88565b925050819055506114a88282612398565b5050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600c60019054906101000a900460ff16611525576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151c90613e74565b60405180910390fd5b60005b82829050811015611727573373ffffffffffffffffffffffffffffffffffffffff16601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e85858581811061159b5761159a613849565b5b905060200201356040518263ffffffff1660e01b81526004016115be9190612c27565b602060405180830381865afa1580156115db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ff9190613ea9565b73ffffffffffffffffffffffffffffffffffffffff1614611655576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164c90613f48565b60405180910390fd5b600e600084848481811061166c5761166b613849565b5b90506020020135815260200190815260200160002060009054906101000a900460ff16156116cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116c690613fb4565b60405180910390fd5b6001600e60008585858181106116e8576116e7613849565b5b90506020020135815260200190815260200160002060006101000a81548160ff021916908315150217905550808061171f906138d4565b915050611528565b506117383383839050600a546120fd565b7fb9488f4fcc28b58228f056a73c5a4eac0bc5c3aaa95d2c5af05d16a8ea3b50c4611761612553565b83836040516117729392919061404f565b60405180910390a15050565b60606003805461178d906136d4565b80601f01602080910402602001604051908101604052809291908181526020018280546117b9906136d4565b80156118065780601f106117db57610100808354040283529160200191611806565b820191906000526020600020905b8154815290600101906020018083116117e957829003601f168201915b5050505050905090565b600e6020528060005260406000206000915054906101000a900460ff1681565b611838611f56565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361189c576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600760006118a9611f56565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611956611f56565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161199b9190612cf6565b60405180910390a35050565b60095481565b6119b8848484610ca4565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611a1a576119e384848484612566565b611a19576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6060611a2b82611ef7565b611a6a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a61906140f3565b60405180910390fd5b600060108054611a79906136d4565b905011611a955760405180602001604052806000815250611ac4565b6010611aa0836126b6565b6011604051602001611ab4939291906141d2565b6040516020818303038152906040525b9050919050565b611ad3612254565b80601260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600d6020528060005260406000206000915090505481565b611bcb611e28565b80600b8190555050565b611bdd612254565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611c4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c4390614275565b60405180910390fd5b611c55816122d2565b50565b611c60611e28565b81600c60016101000a81548160ff02191690831515021790555080600c60006101000a81548160ff0219169083151502179055505050565b600c60019054906101000a900460ff16611ce7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cde90613e74565b60405180910390fd5b611cf9611cf333612784565b826127da565b73ffffffffffffffffffffffffffffffffffffffff16601360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611d88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d7f906142e1565b60405180910390fd5b600b5482600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611dd69190613d88565b1115611e17576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e0e90614373565b60405180910390fd5b611e2433836009546120fd565b5050565b3373ffffffffffffffffffffffffffffffffffffffff16611e476114ac565b73ffffffffffffffffffffffffffffffffffffffff161480611eb657503373ffffffffffffffffffffffffffffffffffffffff16601260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b611ef5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eec906143df565b60405180910390fd5b565b600081611f02611f5e565b11158015611f11575060005482105b8015611f4f575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b60006001905090565b60008082905080611f76611f5e565b11611ffc57600054811015611ffb5760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603611ff9575b60008103611fef576004600083600190039350838152602001908152602001600020549050611fc5565b809250505061202e565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e86120bb868684612801565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6115b382612109610c8d565b6121139190613d88565b1115612154576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161214b9061444b565b60405180910390fd5b348282612161919061446b565b146121a1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612198906144f9565b60405180910390fd5b6121a96114ac565b73ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050501580156121ee573d6000803e3d6000fd5b506121f98383612398565b81600d60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546122489190613d88565b92505081905550505050565b61225c61280a565b73ffffffffffffffffffffffffffffffffffffffff1661227a6114ac565b73ffffffffffffffffffffffffffffffffffffffff16146122d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c790614565565b60405180910390fd5b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080549050600082036123d8576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123e5600084838561209e565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061245c8361244d60008660006120a4565b61245685612812565b176120cc565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146124fd57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a46001810190506124c2565b5060008203612538576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505061254e60008483856120f7565b505050565b600061255d611f5e565b60005403905090565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261258c611f56565b8786866040518563ffffffff1660e01b81526004016125ae94939291906145da565b6020604051808303816000875af19250505080156125ea57506040513d601f19601f820116820180604052508101906125e7919061463b565b60015b612663573d806000811461261a576040519150601f19603f3d011682016040523d82523d6000602084013e61261f565b606091505b50600081510361265b576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600060016126c584612822565b01905060008167ffffffffffffffff8111156126e4576126e36131ca565b5b6040519080825280601f01601f1916602001820160405280156127165781602001600182028036833780820191505090505b509050600082602001820190505b600115612779578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161276d5761276c614668565b5b04945060008503612724575b819350505050919050565b600081604051602001612797919061472b565b604051602081830303815290604052805190602001206040516020016127bd91906147c8565b604051602081830303815290604052805190602001209050919050565b60008060006127e98585612975565b915091506127f6816129c6565b819250505092915050565b60009392505050565b600033905090565b60006001821460e11b9050919050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612880577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161287657612875614668565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106128bd576d04ee2d6d415b85acef810000000083816128b3576128b2614668565b5b0492506020810190505b662386f26fc1000083106128ec57662386f26fc1000083816128e2576128e1614668565b5b0492506010810190505b6305f5e1008310612915576305f5e100838161290b5761290a614668565b5b0492506008810190505b612710831061293a5761271083816129305761292f614668565b5b0492506004810190505b6064831061295d576064838161295357612952614668565b5b0492506002810190505b600a831061296c576001810190505b80915050919050565b60008060418351036129b65760008060006020860151925060408601519150606086015160001a90506129aa87828585612b2c565b945094505050506129bf565b60006002915091505b9250929050565b600060048111156129da576129d96147ee565b5b8160048111156129ed576129ec6147ee565b5b0315612b295760016004811115612a0757612a066147ee565b5b816004811115612a1a57612a196147ee565b5b03612a5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a5190614869565b60405180910390fd5b60026004811115612a6e57612a6d6147ee565b5b816004811115612a8157612a806147ee565b5b03612ac1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ab8906148d5565b60405180910390fd5b60036004811115612ad557612ad46147ee565b5b816004811115612ae857612ae76147ee565b5b03612b28576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b1f90614967565b60405180910390fd5b5b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c1115612b67576000600391509150612c05565b600060018787878760405160008152602001604052604051612b8c94939291906149b2565b6020604051602081039080840390855afa158015612bae573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612bfc57600060019250925050612c05565b80600092509250505b94509492505050565b6000819050919050565b612c2181612c0e565b82525050565b6000602082019050612c3c6000830184612c18565b92915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612c8b81612c56565b8114612c9657600080fd5b50565b600081359050612ca881612c82565b92915050565b600060208284031215612cc457612cc3612c4c565b5b6000612cd284828501612c99565b91505092915050565b60008115159050919050565b612cf081612cdb565b82525050565b6000602082019050612d0b6000830184612ce7565b92915050565b612d1a81612c0e565b8114612d2557600080fd5b50565b600081359050612d3781612d11565b92915050565b60008060408385031215612d5457612d53612c4c565b5b6000612d6285828601612d28565b9250506020612d7385828601612d28565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612db7578082015181840152602081019050612d9c565b60008484015250505050565b6000601f19601f8301169050919050565b6000612ddf82612d7d565b612de98185612d88565b9350612df9818560208601612d99565b612e0281612dc3565b840191505092915050565b60006020820190508181036000830152612e278184612dd4565b905092915050565b600060208284031215612e4557612e44612c4c565b5b6000612e5384828501612d28565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612e8782612e5c565b9050919050565b612e9781612e7c565b82525050565b6000602082019050612eb26000830184612e8e565b92915050565b612ec181612e7c565b8114612ecc57600080fd5b50565b600081359050612ede81612eb8565b92915050565b60008060408385031215612efb57612efa612c4c565b5b6000612f0985828601612ecf565b9250506020612f1a85828601612d28565b9150509250929050565b600080600060608486031215612f3d57612f3c612c4c565b5b6000612f4b86828701612ecf565b9350506020612f5c86828701612ecf565b9250506040612f6d86828701612d28565b9150509250925092565b600060208284031215612f8d57612f8c612c4c565b5b6000612f9b84828501612ecf565b91505092915050565b6000612faf82612e7c565b9050919050565b612fbf81612fa4565b8114612fca57600080fd5b50565b600081359050612fdc81612fb6565b92915050565b600060208284031215612ff857612ff7612c4c565b5b600061300684828501612fcd565b91505092915050565b6000819050919050565b600061303461302f61302a84612e5c565b61300f565b612e5c565b9050919050565b600061304682613019565b9050919050565b60006130588261303b565b9050919050565b6130688161304d565b82525050565b6000602082019050613083600083018461305f565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126130ae576130ad613089565b5b8235905067ffffffffffffffff8111156130cb576130ca61308e565b5b6020830191508360208202830111156130e7576130e6613093565b5b9250929050565b60008083601f84011261310457613103613089565b5b8235905067ffffffffffffffff8111156131215761312061308e565b5b60208301915083602082028301111561313d5761313c613093565b5b9250929050565b6000806000806040858703121561315e5761315d612c4c565b5b600085013567ffffffffffffffff81111561317c5761317b612c51565b5b61318887828801613098565b9450945050602085013567ffffffffffffffff8111156131ab576131aa612c51565b5b6131b7878288016130ee565b925092505092959194509250565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61320282612dc3565b810181811067ffffffffffffffff82111715613221576132206131ca565b5b80604052505050565b6000613234612c42565b905061324082826131f9565b919050565b600067ffffffffffffffff8211156132605761325f6131ca565b5b61326982612dc3565b9050602081019050919050565b82818337600083830152505050565b600061329861329384613245565b61322a565b9050828152602081018484840111156132b4576132b36131c5565b5b6132bf848285613276565b509392505050565b600082601f8301126132dc576132db613089565b5b81356132ec848260208601613285565b91505092915050565b6000806040838503121561330c5761330b612c4c565b5b600083013567ffffffffffffffff81111561332a57613329612c51565b5b613336858286016132c7565b925050602083013567ffffffffffffffff81111561335757613356612c51565b5b613363858286016132c7565b9150509250929050565b60008083601f84011261338357613382613089565b5b8235905067ffffffffffffffff8111156133a05761339f61308e565b5b6020830191508360208202830111156133bc576133bb613093565b5b9250929050565b600080602083850312156133da576133d9612c4c565b5b600083013567ffffffffffffffff8111156133f8576133f7612c51565b5b6134048582860161336d565b92509250509250929050565b61341981612cdb565b811461342457600080fd5b50565b60008135905061343681613410565b92915050565b6000806040838503121561345357613452612c4c565b5b600061346185828601612ecf565b925050602061347285828601613427565b9150509250929050565b600067ffffffffffffffff821115613497576134966131ca565b5b6134a082612dc3565b9050602081019050919050565b60006134c06134bb8461347c565b61322a565b9050828152602081018484840111156134dc576134db6131c5565b5b6134e7848285613276565b509392505050565b600082601f83011261350457613503613089565b5b81356135148482602086016134ad565b91505092915050565b6000806000806080858703121561353757613536612c4c565b5b600061354587828801612ecf565b945050602061355687828801612ecf565b935050604061356787828801612d28565b925050606085013567ffffffffffffffff81111561358857613587612c51565b5b613594878288016134ef565b91505092959194509250565b600080604083850312156135b7576135b6612c4c565b5b60006135c585828601612ecf565b92505060206135d685828601612ecf565b9150509250929050565b600080604083850312156135f7576135f6612c4c565b5b600061360585828601613427565b925050602061361685828601613427565b9150509250929050565b6000806040838503121561363757613636612c4c565b5b600061364585828601612d28565b925050602083013567ffffffffffffffff81111561366657613665612c51565b5b613672858286016134ef565b9150509250929050565b60006040820190506136916000830185612c18565b61369e6020830184612c18565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806136ec57607f821691505b6020821081036136ff576136fe6136a5565b5b50919050565b7f5075626c6963206d696e74696e672064697361626c6564000000000000000000600082015250565b600061373b601783612d88565b915061374682613705565b602082019050919050565b6000602082019050818103600083015261376a8161372e565b9050919050565b7f417272617920617265206f6620646966666572656e742073697a650000000000600082015250565b60006137a7601b83612d88565b91506137b282613771565b602082019050919050565b600060208201905081810360008301526137d68161379a565b9050919050565b7f4172726179732061726520656d70747900000000000000000000000000000000600082015250565b6000613813601083612d88565b915061381e826137dd565b602082019050919050565b6000602082019050818103600083015261384281613806565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561388e5761388d612c4c565b5b600061389c84828501613427565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006138df82612c0e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613911576139106138a5565b5b600182019050919050565b600082825260208201905092915050565b6000819050919050565b61394081612e7c565b82525050565b60006139528383613937565b60208301905092915050565b600061396d6020840184612ecf565b905092915050565b6000602082019050919050565b600061398e838561391c565b93506139998261392d565b8060005b858110156139d2576139af828461395e565b6139b98882613946565b97506139c483613975565b92505060018101905061399d565b5085925050509392505050565b600082825260208201905092915050565b6000819050919050565b613a0381612cdb565b82525050565b6000613a1583836139fa565b60208301905092915050565b6000613a306020840184613427565b905092915050565b6000602082019050919050565b6000613a5183856139df565b9350613a5c826139f0565b8060005b85811015613a9557613a728284613a21565b613a7c8882613a09565b9750613a8783613a38565b925050600181019050613a60565b5085925050509392505050565b60006040820190508181036000830152613abd818688613982565b90508181036020830152613ad2818486613a45565b905095945050505050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302613b3f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613b02565b613b498683613b02565b95508019841693508086168417925050509392505050565b6000613b7c613b77613b7284612c0e565b61300f565b612c0e565b9050919050565b6000819050919050565b613b9683613b61565b613baa613ba282613b83565b848454613b0f565b825550505050565b600090565b613bbf613bb2565b613bca818484613b8d565b505050565b5b81811015613bee57613be3600082613bb7565b600181019050613bd0565b5050565b601f821115613c3357613c0481613add565b613c0d84613af2565b81016020851015613c1c578190505b613c30613c2885613af2565b830182613bcf565b50505b505050565b600082821c905092915050565b6000613c5660001984600802613c38565b1980831691505092915050565b6000613c6f8383613c45565b9150826002028217905092915050565b613c8882612d7d565b67ffffffffffffffff811115613ca157613ca06131ca565b5b613cab82546136d4565b613cb6828285613bf2565b600060209050601f831160018114613ce95760008415613cd7578287015190505b613ce18582613c63565b865550613d49565b601f198416613cf786613add565b60005b82811015613d1f57848901518255600182019150602085019450602081019050613cfa565b86831015613d3c5784890151613d38601f891682613c45565b8355505b6001600288020188555050505b505050505050565b60006040820190508181036000830152613d6b8185612dd4565b90508181036020830152613d7f8184612dd4565b90509392505050565b6000613d9382612c0e565b9150613d9e83612c0e565b9250828201905080821115613db657613db56138a5565b5b92915050565b7f63616e6e6f742072657365727665206d6f726500000000000000000000000000600082015250565b6000613df2601383612d88565b9150613dfd82613dbc565b602082019050919050565b60006020820190508181036000830152613e2181613de5565b9050919050565b7f50726573616c65206d696e74696e672064697361626c65640000000000000000600082015250565b6000613e5e601883612d88565b9150613e6982613e28565b602082019050919050565b60006020820190508181036000830152613e8d81613e51565b9050919050565b600081519050613ea381612eb8565b92915050565b600060208284031215613ebf57613ebe612c4c565b5b6000613ecd84828501613e94565b91505092915050565b7f4164647265737320746f206973206e6f74206f776e6572206f6620626f74746c60008201527f6549640000000000000000000000000000000000000000000000000000000000602082015250565b6000613f32602383612d88565b9150613f3d82613ed6565b604082019050919050565b60006020820190508181036000830152613f6181613f25565b9050919050565b7f426f74746c6549642068617320616c7265616479206265656e20757365640000600082015250565b6000613f9e601e83612d88565b9150613fa982613f68565b602082019050919050565b60006020820190508181036000830152613fcd81613f91565b9050919050565b600082825260208201905092915050565b600080fd5b82818337505050565b6000613fff8385613fd4565b93507f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561403257614031613fe5565b5b602083029250614043838584613fea565b82840190509392505050565b60006040820190506140646000830186612c18565b8181036020830152614077818486613ff3565b9050949350505050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b60006140dd602f83612d88565b91506140e882614081565b604082019050919050565b6000602082019050818103600083015261410c816140d0565b9050919050565b600081905092915050565b6000815461412b816136d4565b6141358186614113565b94506001821660008114614150576001811461416557614198565b60ff1983168652811515820286019350614198565b61416e85613add565b60005b8381101561419057815481890152600182019150602081019050614171565b838801955050505b50505092915050565b60006141ac82612d7d565b6141b68185614113565b93506141c6818560208601612d99565b80840191505092915050565b60006141de828661411e565b91506141ea82856141a1565b91506141f6828461411e565b9150819050949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061425f602683612d88565b915061426a82614203565b604082019050919050565b6000602082019050818103600083015261428e81614252565b9050919050565b7f696e76616c69642068617368206f72207369676e617475726500000000000000600082015250565b60006142cb601983612d88565b91506142d682614295565b602082019050919050565b600060208201905081810360008301526142fa816142be565b9050919050565b7f43616e6e6f74206d696e74206d6f7265207468616e2077616c6c65744c696d6960008201527f7400000000000000000000000000000000000000000000000000000000000000602082015250565b600061435d602183612d88565b915061436882614301565b604082019050919050565b6000602082019050818103600083015261438c81614350565b9050919050565b7f5369676e6572206973206e6f7420646576206e6f72206f776e65720000000000600082015250565b60006143c9601b83612d88565b91506143d482614393565b602082019050919050565b600060208201905081810360008301526143f8816143bc565b9050919050565b7f4d617820737570706c7920657863656564656400000000000000000000000000600082015250565b6000614435601383612d88565b9150614440826143ff565b602082019050919050565b6000602082019050818103600083015261446481614428565b9050919050565b600061447682612c0e565b915061448183612c0e565b925082820261448f81612c0e565b915082820484148315176144a6576144a56138a5565b5b5092915050565b7f696e76616c6964206574682076616c7565000000000000000000000000000000600082015250565b60006144e3601183612d88565b91506144ee826144ad565b602082019050919050565b60006020820190508181036000830152614512816144d6565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061454f602083612d88565b915061455a82614519565b602082019050919050565b6000602082019050818103600083015261457e81614542565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006145ac82614585565b6145b68185614590565b93506145c6818560208601612d99565b6145cf81612dc3565b840191505092915050565b60006080820190506145ef6000830187612e8e565b6145fc6020830186612e8e565b6146096040830185612c18565b818103606083015261461b81846145a1565b905095945050505050565b60008151905061463581612c82565b92915050565b60006020828403121561465157614650612c4c565b5b600061465f84828501614626565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f426f72656447726170657356696e657300000000000000000000000000000000600082015250565b60006146cd601083614113565b91506146d882614697565b601082019050919050565b60008160601b9050919050565b60006146fb826146e3565b9050919050565b600061470d826146f0565b9050919050565b61472561472082612e7c565b614702565b82525050565b6000614736826146c0565b91506147428284614714565b60148201915081905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b6000614787601c83614113565b915061479282614751565b601c82019050919050565b6000819050919050565b6000819050919050565b6147c26147bd8261479d565b6147a7565b82525050565b60006147d38261477a565b91506147df82846147b1565b60208201915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b6000614853601883612d88565b915061485e8261481d565b602082019050919050565b6000602082019050818103600083015261488281614846565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b60006148bf601f83612d88565b91506148ca82614889565b602082019050919050565b600060208201905081810360008301526148ee816148b2565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000614951602283612d88565b915061495c826148f5565b604082019050919050565b6000602082019050818103600083015261498081614944565b9050919050565b6149908161479d565b82525050565b600060ff82169050919050565b6149ac81614996565b82525050565b60006080820190506149c76000830187614987565b6149d460208301866149a3565b6149e16040830185614987565b6149ee6060830184614987565b9594505050505056fea2646970667358221220b0d054cab5eeeec004d19edbdd39789cf15dc621629a38c2bd4fb2e53a9e70ad64736f6c63430008110033

Deployed Bytecode Sourcemap

79869:5673:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80268:53;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18513:639;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;84135:231;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;19415:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25898:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25339:400;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80443:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;15166:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;29605:2817;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80937:39;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80407:29;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;84613:120;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80328:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80845:83;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80373:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;82775:188;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;32518:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80572:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;85155:382;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;20808:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83886:241;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;84375:111;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;16350:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69328:103;;;;;;;;;;;;;:::i;:::-;;83028:219;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68680:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81534:558;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;19591:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80526:39;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26456:308;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80209:52;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33301:399;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83564:314;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;84741:81;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;26921:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80476:43;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;84494:107;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;69586:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;84841:197;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;82332:435;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80268:53;;;;:::o;18513:639::-;18598:4;18937:10;18922:25;;:11;:25;;;;:102;;;;19014:10;18999:25;;:11;:25;;;;18922:102;:179;;;;19091:10;19076:25;;:11;:25;;;;18922:179;18902:199;;18513:639;;;:::o;84135:231::-;83374:13;:11;:13::i;:::-;84242:15:::1;84227:12;:30;;;;84282:14;84268:11;:28;;;;84312:46;84326:15;84343:14;84312:46;;;;;;;:::i;:::-;;;;;;;;84135:231:::0;;:::o;19415:100::-;19469:13;19502:5;19495:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19415:100;:::o;25898:218::-;25974:7;25999:16;26007:7;25999;:16::i;:::-;25994:64;;26024:34;;;;;;;;;;;;;;25994:64;26078:15;:24;26094:7;26078:24;;;;;;;;;;;:30;;;;;;;;;;;;26071:37;;25898:218;;;:::o;25339:400::-;25420:13;25436:16;25444:7;25436;:16::i;:::-;25420:32;;25492:5;25469:28;;:19;:17;:19::i;:::-;:28;;;25465:175;;25517:44;25534:5;25541:19;:17;:19::i;:::-;25517:16;:44::i;:::-;25512:128;;25589:35;;;;;;;;;;;;;;25512:128;25465:175;25685:2;25652:15;:24;25668:7;25652:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;25723:7;25719:2;25703:28;;25712:5;25703:28;;;;;;;;;;;;25409:330;25339:400;;:::o;80443:26::-;;;;;;;;;;;;;:::o;15166:323::-;15227:7;15455:15;:13;:15::i;:::-;15440:12;;15424:13;;:28;:46;15417:53;;15166:323;:::o;29605:2817::-;29739:27;29769;29788:7;29769:18;:27::i;:::-;29739:57;;29854:4;29813:45;;29829:19;29813:45;;;29809:86;;29867:28;;;;;;;;;;;;;;29809:86;29909:27;29938:23;29965:35;29992:7;29965:26;:35::i;:::-;29908:92;;;;30100:68;30125:15;30142:4;30148:19;:17;:19::i;:::-;30100:24;:68::i;:::-;30095:180;;30188:43;30205:4;30211:19;:17;:19::i;:::-;30188:16;:43::i;:::-;30183:92;;30240:35;;;;;;;;;;;;;;30183:92;30095:180;30306:1;30292:16;;:2;:16;;;30288:52;;30317:23;;;;;;;;;;;;;;30288:52;30353:43;30375:4;30381:2;30385:7;30394:1;30353:21;:43::i;:::-;30489:15;30486:160;;;30629:1;30608:19;30601:30;30486:160;31026:18;:24;31045:4;31026:24;;;;;;;;;;;;;;;;31024:26;;;;;;;;;;;;31095:18;:22;31114:2;31095:22;;;;;;;;;;;;;;;;31093:24;;;;;;;;;;;31417:146;31454:2;31503:45;31518:4;31524:2;31528:19;31503:14;:45::i;:::-;11565:8;31475:73;31417:18;:146::i;:::-;31388:17;:26;31406:7;31388:26;;;;;;;;;;;:175;;;;31734:1;11565:8;31683:19;:47;:52;31679:627;;31756:19;31788:1;31778:7;:11;31756:33;;31945:1;31911:17;:30;31929:11;31911:30;;;;;;;;;;;;:35;31907:384;;32049:13;;32034:11;:28;32030:242;;32229:19;32196:17;:30;32214:11;32196:30;;;;;;;;;;;:52;;;;32030:242;31907:384;31737:569;31679:627;32353:7;32349:2;32334:27;;32343:4;32334:27;;;;;;;;;;;;32372:42;32393:4;32399:2;32403:7;32412:1;32372:20;:42::i;:::-;29728:2694;;;29605:2817;;;:::o;80937:39::-;;;;;;;;;;;;;;;;;;;;;;:::o;80407:29::-;;;;;;;;;;;;;:::o;84613:120::-;83374:13;:11;:13::i;:::-;84710:15:::1;84693:14;;:32;;;;;;;;;;;;;;;;;;84613:120:::0;:::o;80328:38::-;80362:4;80328:38;:::o;80845:83::-;;;;;;;;;;;;;:::o;80373:27::-;;;;:::o;82775:188::-;82852:17;;;;;;;;;;;82844:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;82917:38;82929:2;82933:8;82943:11;;82917;:38::i;:::-;82775:188;;:::o;32518:185::-;32656:39;32673:4;32679:2;32683:7;32656:39;;;;;;;;;;;;:16;:39::i;:::-;32518:185;;;:::o;80572:26::-;;;;:::o;85155:382::-;68566:13;:11;:13::i;:::-;85279:6:::1;;:13;;85263:7;;:14;;:29;85255:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;85360:1;85343:7;;:14;;:18;85335:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;85397:6;85393:92;85409:7;;:14;;85407:1;:16;85393:92;;;85464:6;;85471:1;85464:9;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;85444:7;:19;85452:7;;85460:1;85452:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;85444:19;;;;;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;85425:3;;;;;:::i;:::-;;;;85393:92;;;;85500:29;85513:7;;85522:6;;85500:29;;;;;;;;;:::i;:::-;;;;;;;;85155:382:::0;;;;:::o;20808:152::-;20880:7;20923:27;20942:7;20923:18;:27::i;:::-;20900:52;;20808:152;;;:::o;83886:241::-;83374:13;:11;:13::i;:::-;84009:12:::1;83992:14;:29;;;;;;:::i;:::-;;84049:12;84032:14;:29;;;;;;:::i;:::-;;84077:42;84092:12;84106;84077:42;;;;;;;:::i;:::-;;;;;;;;83886:241:::0;;:::o;84375:111::-;83374:13;:11;:13::i;:::-;84464:14:::1;84448:13;;:30;;;;;;;;;;;;;;;;;;84375:111:::0;:::o;16350:233::-;16422:7;16463:1;16446:19;;:5;:19;;;16442:60;;16474:28;;;;;;;;;;;;;;16442:60;10509:13;16520:18;:25;16539:5;16520:25;;;;;;;;;;;;;;;;:55;16513:62;;16350:233;;;:::o;69328:103::-;68566:13;:11;:13::i;:::-;69393:30:::1;69420:1;69393:18;:30::i;:::-;69328:103::o:0;83028:219::-;68566:13;:11;:13::i;:::-;83145:3:::1;83133:8;83116:14;;:25;;;;:::i;:::-;:32;;83108:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;83201:8;83183:14;;:26;;;;;;;:::i;:::-;;;;;;;;83220:19;83226:2;83230:8;83220:5;:19::i;:::-;83028:219:::0;;:::o;68680:87::-;68726:7;68753:6;;;;;;;;;;;68746:13;;68680:87;:::o;81534:558::-;81624:14;;;;;;;;;;;81616:51;;;;;;;;;;;;:::i;:::-;;;;;;;;;81682:6;81678:287;81694:9;;:16;;81692:1;:18;81678:287;;;81777:10;81739:48;;:14;;;;;;;;;;;:22;;;81762:9;;81772:1;81762:12;;;;;;;:::i;:::-;;;;;;;;81739:36;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:48;;;81731:96;;;;;;;;;;;;:::i;:::-;;;;;;;;;81851:10;:24;81862:9;;81872:1;81862:12;;;;;;;:::i;:::-;;;;;;;;81851:24;;;;;;;;;;;;;;;;;;;;;81850:25;81842:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;81949:4;81924:10;:24;81935:9;;81945:1;81935:12;;;;;;;:::i;:::-;;;;;;;;81924:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;81712:3;;;;;:::i;:::-;;;;81678:287;;;;81975:55;81987:10;81999:9;;:16;;82017:12;;81975:11;:55::i;:::-;82046:38;82058:14;:12;:14::i;:::-;82074:9;;82046:38;;;;;;;;:::i;:::-;;;;;;;;81534:558;;:::o;19591:104::-;19647:13;19680:7;19673:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19591:104;:::o;80526:39::-;;;;;;;;;;;;;;;;;;;;;;:::o;26456:308::-;26567:19;:17;:19::i;:::-;26555:31;;:8;:31;;;26551:61;;26595:17;;;;;;;;;;;;;;26551:61;26677:8;26625:18;:39;26644:19;:17;:19::i;:::-;26625:39;;;;;;;;;;;;;;;:49;26665:8;26625:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;26737:8;26701:55;;26716:19;:17;:19::i;:::-;26701:55;;;26747:8;26701:55;;;;;;:::i;:::-;;;;;;;;26456:308;;:::o;80209:52::-;;;;:::o;33301:399::-;33468:31;33481:4;33487:2;33491:7;33468:12;:31::i;:::-;33532:1;33514:2;:14;;;:19;33510:183;;33553:56;33584:4;33590:2;33594:7;33603:5;33553:30;:56::i;:::-;33548:145;;33637:40;;;;;;;;;;;;;;33548:145;33510:183;33301:399;;;;:::o;83564:314::-;83634:13;83668:16;83676:7;83668;:16::i;:::-;83660:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;83785:1;83760:14;83754:28;;;;;:::i;:::-;;;:32;:116;;;;;;;;;;;;;;;;;83813:14;83829:18;:7;:16;:18::i;:::-;83849:14;83796:68;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;83754:116;83747:123;;83564:314;;;:::o;84741:81::-;68566:13;:11;:13::i;:::-;84808:6:::1;84802:3;;:12;;;;;;;;;;;;;;;;;;84741:81:::0;:::o;26921:164::-;27018:4;27042:18;:25;27061:5;27042:25;;;;;;;;;;;;;;;:35;27068:8;27042:35;;;;;;;;;;;;;;;;;;;;;;;;;27035:42;;26921:164;;;;:::o;80476:43::-;;;;;;;;;;;;;;;;;:::o;84494:107::-;83374:13;:11;:13::i;:::-;84581:12:::1;84567:11;:26;;;;84494:107:::0;:::o;69586:201::-;68566:13;:11;:13::i;:::-;69695:1:::1;69675:22;;:8;:22;;::::0;69667:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;69751:28;69770:8;69751:18;:28::i;:::-;69586:201:::0;:::o;84841:197::-;83374:13;:11;:13::i;:::-;84958:15:::1;84941:14;;:32;;;;;;;;;;;;;;;;;;85004:18;84984:17;;:38;;;;;;;;;;;;;;;;;;84841:197:::0;;:::o;82332:435::-;82428:14;;;;;;;;;;;82420:51;;;;;;;;;;;;:::i;:::-;;;;;;;;;82507:52;82522:25;82536:10;82522:12;:25::i;:::-;82549:9;82507:13;:52::i;:::-;82490:69;;:13;;;;;;;;;;;:69;;;82482:107;;;;;;;;;;;;:::i;:::-;;;;;;;;;82645:11;;82633:8;82609:11;:23;82621:10;82609:23;;;;;;;;;;;;;;;;:32;;;;:::i;:::-;:47;;82600:94;;;;;;;;;;;;:::i;:::-;;;;;;;;;82713:46;82725:10;82737:8;82747:11;;82713;:46::i;:::-;82332:435;;:::o;83415:137::-;83482:10;83473:19;;:7;:5;:7::i;:::-;:19;;;83472:40;;;;83501:10;83496:15;;:3;;;;;;;;;;;:15;;;83472:40;83463:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;83415:137::o;27343:282::-;27408:4;27464:7;27445:15;:13;:15::i;:::-;:26;;:66;;;;;27498:13;;27488:7;:23;27445:66;:153;;;;;27597:1;11285:8;27549:17;:26;27567:7;27549:26;;;;;;;;;;;;:44;:49;27445:153;27425:173;;27343:282;;;:::o;49109:105::-;49169:7;49196:10;49189:17;;49109:105;:::o;85046:101::-;85111:7;85138:1;85131:8;;85046:101;:::o;21963:1275::-;22030:7;22050:12;22065:7;22050:22;;22133:4;22114:15;:13;:15::i;:::-;:23;22110:1061;;22167:13;;22160:4;:20;22156:1015;;;22205:14;22222:17;:23;22240:4;22222:23;;;;;;;;;;;;22205:40;;22339:1;11285:8;22311:6;:24;:29;22307:845;;22976:113;22993:1;22983:6;:11;22976:113;;23036:17;:25;23054:6;;;;;;;23036:25;;;;;;;;;;;;23027:34;;22976:113;;;23122:6;23115:13;;;;;;22307:845;22182:989;22156:1015;22110:1061;23199:31;;;;;;;;;;;;;;21963:1275;;;;:::o;28506:479::-;28608:27;28637:23;28678:38;28719:15;:24;28735:7;28719:24;;;;;;;;;;;28678:65;;28890:18;28867:41;;28947:19;28941:26;28922:45;;28852:126;28506:479;;;:::o;27734:659::-;27883:11;28048:16;28041:5;28037:28;28028:37;;28208:16;28197:9;28193:32;28180:45;;28358:15;28347:9;28344:30;28336:5;28325:9;28322:20;28319:56;28309:66;;27734:659;;;;;:::o;34362:159::-;;;;;:::o;48418:311::-;48553:7;48573:16;11689:3;48599:19;:41;;48573:68;;11689:3;48667:31;48678:4;48684:2;48688:9;48667:10;:31::i;:::-;48659:40;;:62;;48652:69;;;48418:311;;;;;:::o;23786:450::-;23866:14;24034:16;24027:5;24023:28;24014:37;;24211:5;24197:11;24172:23;24168:41;24165:52;24158:5;24155:63;24145:73;;23786:450;;;;:::o;35186:158::-;;;;;:::o;81185:341::-;80362:4;81287:8;81273:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:36;;81265:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;81370:9;81358:8;81352:5;:14;;;;:::i;:::-;:27;81344:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;81422:7;:5;:7::i;:::-;81414:25;;:36;81440:9;81414:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81463:19;81469:2;81473:8;81463:5;:19::i;:::-;81510:8;81493:11;:15;81505:2;81493:15;;;;;;;;;;;;;;;;:25;;;;;;;:::i;:::-;;;;;;;;81185:341;;;:::o;68845:132::-;68920:12;:10;:12::i;:::-;68909:23;;:7;:5;:7::i;:::-;:23;;;68901:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;68845:132::o;69947:191::-;70021:16;70040:6;;;;;;;;;;;70021:25;;70066:8;70057:6;;:17;;;;;;;;;;;;;;;;;;70121:8;70090:40;;70111:8;70090:40;;;;;;;;;;;;70010:128;69947:191;:::o;36962:2454::-;37035:20;37058:13;;37035:36;;37098:1;37086:8;:13;37082:44;;37108:18;;;;;;;;;;;;;;37082:44;37139:61;37169:1;37173:2;37177:12;37191:8;37139:21;:61::i;:::-;37683:1;10647:2;37653:1;:26;;37652:32;37640:8;:45;37614:18;:22;37633:2;37614:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;37962:139;37999:2;38053:33;38076:1;38080:2;38084:1;38053:14;:33::i;:::-;38020:30;38041:8;38020:20;:30::i;:::-;:66;37962:18;:139::i;:::-;37928:17;:31;37946:12;37928:31;;;;;;;;;;;:173;;;;38118:16;38149:11;38178:8;38163:12;:23;38149:37;;38433:16;38429:2;38425:25;38413:37;;38805:12;38765:8;38724:1;38662:25;38603:1;38542;38515:335;38930:1;38916:12;38912:20;38870:346;38971:3;38962:7;38959:16;38870:346;;39189:7;39179:8;39176:1;39149:25;39146:1;39143;39138:59;39024:1;39015:7;39011:15;39000:26;;38870:346;;;38874:77;39261:1;39249:8;:13;39245:45;;39271:19;;;;;;;;;;;;;;39245:45;39323:3;39307:13;:19;;;;37388:1950;;39348:60;39377:1;39381:2;39385:12;39399:8;39348:20;:60::i;:::-;37024:2392;36962:2454;;:::o;15587:296::-;15642:7;15849:15;:13;:15::i;:::-;15833:13;;:31;15826:38;;15587:296;:::o;35784:716::-;35947:4;35993:2;35968:45;;;36014:19;:17;:19::i;:::-;36035:4;36041:7;36050:5;35968:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;35964:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36268:1;36251:6;:13;:18;36247:235;;36297:40;;;;;;;;;;;;;;36247:235;36440:6;36434:13;36425:6;36421:2;36417:15;36410:38;35964:529;36137:54;;;36127:64;;;:6;:64;;;;36120:71;;;35784:716;;;;;;:::o;64644:::-;64700:13;64751:14;64788:1;64768:17;64779:5;64768:10;:17::i;:::-;:21;64751:38;;64804:20;64838:6;64827:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64804:41;;64860:11;64989:6;64985:2;64981:15;64973:6;64969:28;64962:35;;65026:288;65033:4;65026:288;;;65058:5;;;;;;;;65200:8;65195:2;65188:5;65184:14;65179:30;65174:3;65166:44;65256:2;65247:11;;;;;;:::i;:::-;;;;;65290:1;65281:5;:10;65026:288;65277:21;65026:288;65335:6;65328:13;;;;;64644:716;;;:::o;82100:224::-;82160:7;82297:6;82261:43;;;;;;;;:::i;:::-;;;;;;;;;;;;;82251:54;;;;;;82197:109;;;;;;;;:::i;:::-;;;;;;;;;;;;;82187:120;;;;;;82180:127;;82100:224;;;:::o;73907:231::-;73985:7;74006:17;74025:18;74047:27;74058:4;74064:9;74047:10;:27::i;:::-;74005:69;;;;74085:18;74097:5;74085:11;:18::i;:::-;74121:9;74114:16;;;;73907:231;;;;:::o;48119:147::-;48256:6;48119:147;;;;;:::o;67225:98::-;67278:7;67305:10;67298:17;;67225:98;:::o;24338:324::-;24408:14;24641:1;24631:8;24628:15;24602:24;24598:46;24588:56;;24338:324;;;:::o;61504:922::-;61557:7;61577:14;61594:1;61577:18;;61644:6;61635:5;:15;61631:102;;61680:6;61671:15;;;;;;:::i;:::-;;;;;61715:2;61705:12;;;;61631:102;61760:6;61751:5;:15;61747:102;;61796:6;61787:15;;;;;;:::i;:::-;;;;;61831:2;61821:12;;;;61747:102;61876:6;61867:5;:15;61863:102;;61912:6;61903:15;;;;;;:::i;:::-;;;;;61947:2;61937:12;;;;61863:102;61992:5;61983;:14;61979:99;;62027:5;62018:14;;;;;;:::i;:::-;;;;;62061:1;62051:11;;;;61979:99;62105:5;62096;:14;62092:99;;62140:5;62131:14;;;;;;:::i;:::-;;;;;62174:1;62164:11;;;;62092:99;62218:5;62209;:14;62205:99;;62253:5;62244:14;;;;;;:::i;:::-;;;;;62287:1;62277:11;;;;62205:99;62331:5;62322;:14;62318:66;;62367:1;62357:11;;;;62318:66;62412:6;62405:13;;;61504:922;;;:::o;72358:747::-;72439:7;72448:12;72497:2;72477:9;:16;:22;72473:625;;72516:9;72540;72564:7;72821:4;72810:9;72806:20;72800:27;72795:32;;72871:4;72860:9;72856:20;72850:27;72845:32;;72929:4;72918:9;72914:20;72908:27;72905:1;72900:36;72895:41;;72972:25;72983:4;72989:1;72992;72995;72972:10;:25::i;:::-;72965:32;;;;;;;;;72473:625;73046:1;73050:35;73030:56;;;;72358:747;;;;;;:::o;70751:521::-;70829:20;70820:29;;;;;;;;:::i;:::-;;:5;:29;;;;;;;;:::i;:::-;;;70816:449;70866:7;70816:449;70927:29;70918:38;;;;;;;;:::i;:::-;;:5;:38;;;;;;;;:::i;:::-;;;70914:351;;70973:34;;;;;;;;;;:::i;:::-;;;;;;;;70914:351;71038:35;71029:44;;;;;;;;:::i;:::-;;:5;:44;;;;;;;;:::i;:::-;;;71025:240;;71090:41;;;;;;;;;;:::i;:::-;;;;;;;;71025:240;71162:30;71153:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;71149:116;;71209:44;;;;;;;;;;:::i;:::-;;;;;;;;71149:116;70751:521;;:::o;75359:1520::-;75490:7;75499:12;76424:66;76419:1;76411:10;;:79;76407:163;;;76523:1;76527:30;76507:51;;;;;;76407:163;76667:14;76684:24;76694:4;76700:1;76703;76706;76684:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76667:41;;76741:1;76723:20;;:6;:20;;;76719:103;;76776:1;76780:29;76760:50;;;;;;;76719:103;76842:6;76850:20;76834:37;;;;;75359:1520;;;;;;;;:::o;7:77:1:-;44:7;73:5;62:16;;7:77;;;:::o;90:118::-;177:24;195:5;177:24;:::i;:::-;172:3;165:37;90:118;;:::o;214:222::-;307:4;345:2;334:9;330:18;322:26;;358:71;426:1;415:9;411:17;402:6;358:71;:::i;:::-;214:222;;;;:::o;442:75::-;475:6;508:2;502:9;492:19;;442:75;:::o;523:117::-;632:1;629;622:12;646:117;755:1;752;745:12;769:149;805:7;845:66;838:5;834:78;823:89;;769:149;;;:::o;924:120::-;996:23;1013:5;996:23;:::i;:::-;989:5;986:34;976:62;;1034:1;1031;1024:12;976:62;924:120;:::o;1050:137::-;1095:5;1133:6;1120:20;1111:29;;1149:32;1175:5;1149:32;:::i;:::-;1050:137;;;;:::o;1193:327::-;1251:6;1300:2;1288:9;1279:7;1275:23;1271:32;1268:119;;;1306:79;;:::i;:::-;1268:119;1426:1;1451:52;1495:7;1486:6;1475:9;1471:22;1451:52;:::i;:::-;1441:62;;1397:116;1193:327;;;;:::o;1526:90::-;1560:7;1603:5;1596:13;1589:21;1578:32;;1526:90;;;:::o;1622:109::-;1703:21;1718:5;1703:21;:::i;:::-;1698:3;1691:34;1622:109;;:::o;1737:210::-;1824:4;1862:2;1851:9;1847:18;1839:26;;1875:65;1937:1;1926:9;1922:17;1913:6;1875:65;:::i;:::-;1737:210;;;;:::o;1953:122::-;2026:24;2044:5;2026:24;:::i;:::-;2019:5;2016:35;2006:63;;2065:1;2062;2055:12;2006:63;1953:122;:::o;2081:139::-;2127:5;2165:6;2152:20;2143:29;;2181:33;2208:5;2181:33;:::i;:::-;2081:139;;;;:::o;2226:474::-;2294:6;2302;2351:2;2339:9;2330:7;2326:23;2322:32;2319:119;;;2357:79;;:::i;:::-;2319:119;2477:1;2502:53;2547:7;2538:6;2527:9;2523:22;2502:53;:::i;:::-;2492:63;;2448:117;2604:2;2630:53;2675:7;2666:6;2655:9;2651:22;2630:53;:::i;:::-;2620:63;;2575:118;2226:474;;;;;:::o;2706:99::-;2758:6;2792:5;2786:12;2776:22;;2706:99;;;:::o;2811:169::-;2895:11;2929:6;2924:3;2917:19;2969:4;2964:3;2960:14;2945:29;;2811:169;;;;:::o;2986:246::-;3067:1;3077:113;3091:6;3088:1;3085:13;3077:113;;;3176:1;3171:3;3167:11;3161:18;3157:1;3152:3;3148:11;3141:39;3113:2;3110:1;3106:10;3101:15;;3077:113;;;3224:1;3215:6;3210:3;3206:16;3199:27;3048:184;2986:246;;;:::o;3238:102::-;3279:6;3330:2;3326:7;3321:2;3314:5;3310:14;3306:28;3296:38;;3238:102;;;:::o;3346:377::-;3434:3;3462:39;3495:5;3462:39;:::i;:::-;3517:71;3581:6;3576:3;3517:71;:::i;:::-;3510:78;;3597:65;3655:6;3650:3;3643:4;3636:5;3632:16;3597:65;:::i;:::-;3687:29;3709:6;3687:29;:::i;:::-;3682:3;3678:39;3671:46;;3438:285;3346:377;;;;:::o;3729:313::-;3842:4;3880:2;3869:9;3865:18;3857:26;;3929:9;3923:4;3919:20;3915:1;3904:9;3900:17;3893:47;3957:78;4030:4;4021:6;3957:78;:::i;:::-;3949:86;;3729:313;;;;:::o;4048:329::-;4107:6;4156:2;4144:9;4135:7;4131:23;4127:32;4124:119;;;4162:79;;:::i;:::-;4124:119;4282:1;4307:53;4352:7;4343:6;4332:9;4328:22;4307:53;:::i;:::-;4297:63;;4253:117;4048:329;;;;:::o;4383:126::-;4420:7;4460:42;4453:5;4449:54;4438:65;;4383:126;;;:::o;4515:96::-;4552:7;4581:24;4599:5;4581:24;:::i;:::-;4570:35;;4515:96;;;:::o;4617:118::-;4704:24;4722:5;4704:24;:::i;:::-;4699:3;4692:37;4617:118;;:::o;4741:222::-;4834:4;4872:2;4861:9;4857:18;4849:26;;4885:71;4953:1;4942:9;4938:17;4929:6;4885:71;:::i;:::-;4741:222;;;;:::o;4969:122::-;5042:24;5060:5;5042:24;:::i;:::-;5035:5;5032:35;5022:63;;5081:1;5078;5071:12;5022:63;4969:122;:::o;5097:139::-;5143:5;5181:6;5168:20;5159:29;;5197:33;5224:5;5197:33;:::i;:::-;5097:139;;;;:::o;5242:474::-;5310:6;5318;5367:2;5355:9;5346:7;5342:23;5338:32;5335:119;;;5373:79;;:::i;:::-;5335:119;5493:1;5518:53;5563:7;5554:6;5543:9;5539:22;5518:53;:::i;:::-;5508:63;;5464:117;5620:2;5646:53;5691:7;5682:6;5671:9;5667:22;5646:53;:::i;:::-;5636:63;;5591:118;5242:474;;;;;:::o;5722:619::-;5799:6;5807;5815;5864:2;5852:9;5843:7;5839:23;5835:32;5832:119;;;5870:79;;:::i;:::-;5832:119;5990:1;6015:53;6060:7;6051:6;6040:9;6036:22;6015:53;:::i;:::-;6005:63;;5961:117;6117:2;6143:53;6188:7;6179:6;6168:9;6164:22;6143:53;:::i;:::-;6133:63;;6088:118;6245:2;6271:53;6316:7;6307:6;6296:9;6292:22;6271:53;:::i;:::-;6261:63;;6216:118;5722:619;;;;;:::o;6347:329::-;6406:6;6455:2;6443:9;6434:7;6430:23;6426:32;6423:119;;;6461:79;;:::i;:::-;6423:119;6581:1;6606:53;6651:7;6642:6;6631:9;6627:22;6606:53;:::i;:::-;6596:63;;6552:117;6347:329;;;;:::o;6682:112::-;6735:7;6764:24;6782:5;6764:24;:::i;:::-;6753:35;;6682:112;;;:::o;6800:154::-;6889:40;6923:5;6889:40;:::i;:::-;6882:5;6879:51;6869:79;;6944:1;6941;6934:12;6869:79;6800:154;:::o;6960:171::-;7022:5;7060:6;7047:20;7038:29;;7076:49;7119:5;7076:49;:::i;:::-;6960:171;;;;:::o;7137:361::-;7212:6;7261:2;7249:9;7240:7;7236:23;7232:32;7229:119;;;7267:79;;:::i;:::-;7229:119;7387:1;7412:69;7473:7;7464:6;7453:9;7449:22;7412:69;:::i;:::-;7402:79;;7358:133;7137:361;;;;:::o;7504:60::-;7532:3;7553:5;7546:12;;7504:60;;;:::o;7570:142::-;7620:9;7653:53;7671:34;7680:24;7698:5;7680:24;:::i;:::-;7671:34;:::i;:::-;7653:53;:::i;:::-;7640:66;;7570:142;;;:::o;7718:126::-;7768:9;7801:37;7832:5;7801:37;:::i;:::-;7788:50;;7718:126;;;:::o;7850:142::-;7916:9;7949:37;7980:5;7949:37;:::i;:::-;7936:50;;7850:142;;;:::o;7998:163::-;8101:53;8148:5;8101:53;:::i;:::-;8096:3;8089:66;7998:163;;:::o;8167:254::-;8276:4;8314:2;8303:9;8299:18;8291:26;;8327:87;8411:1;8400:9;8396:17;8387:6;8327:87;:::i;:::-;8167:254;;;;:::o;8427:117::-;8536:1;8533;8526:12;8550:117;8659:1;8656;8649:12;8673:117;8782:1;8779;8772:12;8813:568;8886:8;8896:6;8946:3;8939:4;8931:6;8927:17;8923:27;8913:122;;8954:79;;:::i;:::-;8913:122;9067:6;9054:20;9044:30;;9097:18;9089:6;9086:30;9083:117;;;9119:79;;:::i;:::-;9083:117;9233:4;9225:6;9221:17;9209:29;;9287:3;9279:4;9271:6;9267:17;9257:8;9253:32;9250:41;9247:128;;;9294:79;;:::i;:::-;9247:128;8813:568;;;;;:::o;9401:565::-;9471:8;9481:6;9531:3;9524:4;9516:6;9512:17;9508:27;9498:122;;9539:79;;:::i;:::-;9498:122;9652:6;9639:20;9629:30;;9682:18;9674:6;9671:30;9668:117;;;9704:79;;:::i;:::-;9668:117;9818:4;9810:6;9806:17;9794:29;;9872:3;9864:4;9856:6;9852:17;9842:8;9838:32;9835:41;9832:128;;;9879:79;;:::i;:::-;9832:128;9401:565;;;;;:::o;9972:928::-;10091:6;10099;10107;10115;10164:2;10152:9;10143:7;10139:23;10135:32;10132:119;;;10170:79;;:::i;:::-;10132:119;10318:1;10307:9;10303:17;10290:31;10348:18;10340:6;10337:30;10334:117;;;10370:79;;:::i;:::-;10334:117;10483:80;10555:7;10546:6;10535:9;10531:22;10483:80;:::i;:::-;10465:98;;;;10261:312;10640:2;10629:9;10625:18;10612:32;10671:18;10663:6;10660:30;10657:117;;;10693:79;;:::i;:::-;10657:117;10806:77;10875:7;10866:6;10855:9;10851:22;10806:77;:::i;:::-;10788:95;;;;10583:310;9972:928;;;;;;;:::o;10906:117::-;11015:1;11012;11005:12;11029:180;11077:77;11074:1;11067:88;11174:4;11171:1;11164:15;11198:4;11195:1;11188:15;11215:281;11298:27;11320:4;11298:27;:::i;:::-;11290:6;11286:40;11428:6;11416:10;11413:22;11392:18;11380:10;11377:34;11374:62;11371:88;;;11439:18;;:::i;:::-;11371:88;11479:10;11475:2;11468:22;11258:238;11215:281;;:::o;11502:129::-;11536:6;11563:20;;:::i;:::-;11553:30;;11592:33;11620:4;11612:6;11592:33;:::i;:::-;11502:129;;;:::o;11637:308::-;11699:4;11789:18;11781:6;11778:30;11775:56;;;11811:18;;:::i;:::-;11775:56;11849:29;11871:6;11849:29;:::i;:::-;11841:37;;11933:4;11927;11923:15;11915:23;;11637:308;;;:::o;11951:146::-;12048:6;12043:3;12038;12025:30;12089:1;12080:6;12075:3;12071:16;12064:27;11951:146;;;:::o;12103:425::-;12181:5;12206:66;12222:49;12264:6;12222:49;:::i;:::-;12206:66;:::i;:::-;12197:75;;12295:6;12288:5;12281:21;12333:4;12326:5;12322:16;12371:3;12362:6;12357:3;12353:16;12350:25;12347:112;;;12378:79;;:::i;:::-;12347:112;12468:54;12515:6;12510:3;12505;12468:54;:::i;:::-;12187:341;12103:425;;;;;:::o;12548:340::-;12604:5;12653:3;12646:4;12638:6;12634:17;12630:27;12620:122;;12661:79;;:::i;:::-;12620:122;12778:6;12765:20;12803:79;12878:3;12870:6;12863:4;12855:6;12851:17;12803:79;:::i;:::-;12794:88;;12610:278;12548:340;;;;:::o;12894:834::-;12982:6;12990;13039:2;13027:9;13018:7;13014:23;13010:32;13007:119;;;13045:79;;:::i;:::-;13007:119;13193:1;13182:9;13178:17;13165:31;13223:18;13215:6;13212:30;13209:117;;;13245:79;;:::i;:::-;13209:117;13350:63;13405:7;13396:6;13385:9;13381:22;13350:63;:::i;:::-;13340:73;;13136:287;13490:2;13479:9;13475:18;13462:32;13521:18;13513:6;13510:30;13507:117;;;13543:79;;:::i;:::-;13507:117;13648:63;13703:7;13694:6;13683:9;13679:22;13648:63;:::i;:::-;13638:73;;13433:288;12894:834;;;;;:::o;13751:568::-;13824:8;13834:6;13884:3;13877:4;13869:6;13865:17;13861:27;13851:122;;13892:79;;:::i;:::-;13851:122;14005:6;13992:20;13982:30;;14035:18;14027:6;14024:30;14021:117;;;14057:79;;:::i;:::-;14021:117;14171:4;14163:6;14159:17;14147:29;;14225:3;14217:4;14209:6;14205:17;14195:8;14191:32;14188:41;14185:128;;;14232:79;;:::i;:::-;14185:128;13751:568;;;;;:::o;14325:559::-;14411:6;14419;14468:2;14456:9;14447:7;14443:23;14439:32;14436:119;;;14474:79;;:::i;:::-;14436:119;14622:1;14611:9;14607:17;14594:31;14652:18;14644:6;14641:30;14638:117;;;14674:79;;:::i;:::-;14638:117;14787:80;14859:7;14850:6;14839:9;14835:22;14787:80;:::i;:::-;14769:98;;;;14565:312;14325:559;;;;;:::o;14890:116::-;14960:21;14975:5;14960:21;:::i;:::-;14953:5;14950:32;14940:60;;14996:1;14993;14986:12;14940:60;14890:116;:::o;15012:133::-;15055:5;15093:6;15080:20;15071:29;;15109:30;15133:5;15109:30;:::i;:::-;15012:133;;;;:::o;15151:468::-;15216:6;15224;15273:2;15261:9;15252:7;15248:23;15244:32;15241:119;;;15279:79;;:::i;:::-;15241:119;15399:1;15424:53;15469:7;15460:6;15449:9;15445:22;15424:53;:::i;:::-;15414:63;;15370:117;15526:2;15552:50;15594:7;15585:6;15574:9;15570:22;15552:50;:::i;:::-;15542:60;;15497:115;15151:468;;;;;:::o;15625:307::-;15686:4;15776:18;15768:6;15765:30;15762:56;;;15798:18;;:::i;:::-;15762:56;15836:29;15858:6;15836:29;:::i;:::-;15828:37;;15920:4;15914;15910:15;15902:23;;15625:307;;;:::o;15938:423::-;16015:5;16040:65;16056:48;16097:6;16056:48;:::i;:::-;16040:65;:::i;:::-;16031:74;;16128:6;16121:5;16114:21;16166:4;16159:5;16155:16;16204:3;16195:6;16190:3;16186:16;16183:25;16180:112;;;16211:79;;:::i;:::-;16180:112;16301:54;16348:6;16343:3;16338;16301:54;:::i;:::-;16021:340;15938:423;;;;;:::o;16380:338::-;16435:5;16484:3;16477:4;16469:6;16465:17;16461:27;16451:122;;16492:79;;:::i;:::-;16451:122;16609:6;16596:20;16634:78;16708:3;16700:6;16693:4;16685:6;16681:17;16634:78;:::i;:::-;16625:87;;16441:277;16380:338;;;;:::o;16724:943::-;16819:6;16827;16835;16843;16892:3;16880:9;16871:7;16867:23;16863:33;16860:120;;;16899:79;;:::i;:::-;16860:120;17019:1;17044:53;17089:7;17080:6;17069:9;17065:22;17044:53;:::i;:::-;17034:63;;16990:117;17146:2;17172:53;17217:7;17208:6;17197:9;17193:22;17172:53;:::i;:::-;17162:63;;17117:118;17274:2;17300:53;17345:7;17336:6;17325:9;17321:22;17300:53;:::i;:::-;17290:63;;17245:118;17430:2;17419:9;17415:18;17402:32;17461:18;17453:6;17450:30;17447:117;;;17483:79;;:::i;:::-;17447:117;17588:62;17642:7;17633:6;17622:9;17618:22;17588:62;:::i;:::-;17578:72;;17373:287;16724:943;;;;;;;:::o;17673:474::-;17741:6;17749;17798:2;17786:9;17777:7;17773:23;17769:32;17766:119;;;17804:79;;:::i;:::-;17766:119;17924:1;17949:53;17994:7;17985:6;17974:9;17970:22;17949:53;:::i;:::-;17939:63;;17895:117;18051:2;18077:53;18122:7;18113:6;18102:9;18098:22;18077:53;:::i;:::-;18067:63;;18022:118;17673:474;;;;;:::o;18153:462::-;18215:6;18223;18272:2;18260:9;18251:7;18247:23;18243:32;18240:119;;;18278:79;;:::i;:::-;18240:119;18398:1;18423:50;18465:7;18456:6;18445:9;18441:22;18423:50;:::i;:::-;18413:60;;18369:114;18522:2;18548:50;18590:7;18581:6;18570:9;18566:22;18548:50;:::i;:::-;18538:60;;18493:115;18153:462;;;;;:::o;18621:652::-;18698:6;18706;18755:2;18743:9;18734:7;18730:23;18726:32;18723:119;;;18761:79;;:::i;:::-;18723:119;18881:1;18906:53;18951:7;18942:6;18931:9;18927:22;18906:53;:::i;:::-;18896:63;;18852:117;19036:2;19025:9;19021:18;19008:32;19067:18;19059:6;19056:30;19053:117;;;19089:79;;:::i;:::-;19053:117;19194:62;19248:7;19239:6;19228:9;19224:22;19194:62;:::i;:::-;19184:72;;18979:287;18621:652;;;;;:::o;19279:332::-;19400:4;19438:2;19427:9;19423:18;19415:26;;19451:71;19519:1;19508:9;19504:17;19495:6;19451:71;:::i;:::-;19532:72;19600:2;19589:9;19585:18;19576:6;19532:72;:::i;:::-;19279:332;;;;;:::o;19617:180::-;19665:77;19662:1;19655:88;19762:4;19759:1;19752:15;19786:4;19783:1;19776:15;19803:320;19847:6;19884:1;19878:4;19874:12;19864:22;;19931:1;19925:4;19921:12;19952:18;19942:81;;20008:4;20000:6;19996:17;19986:27;;19942:81;20070:2;20062:6;20059:14;20039:18;20036:38;20033:84;;20089:18;;:::i;:::-;20033:84;19854:269;19803:320;;;:::o;20129:173::-;20269:25;20265:1;20257:6;20253:14;20246:49;20129:173;:::o;20308:366::-;20450:3;20471:67;20535:2;20530:3;20471:67;:::i;:::-;20464:74;;20547:93;20636:3;20547:93;:::i;:::-;20665:2;20660:3;20656:12;20649:19;;20308:366;;;:::o;20680:419::-;20846:4;20884:2;20873:9;20869:18;20861:26;;20933:9;20927:4;20923:20;20919:1;20908:9;20904:17;20897:47;20961:131;21087:4;20961:131;:::i;:::-;20953:139;;20680:419;;;:::o;21105:177::-;21245:29;21241:1;21233:6;21229:14;21222:53;21105:177;:::o;21288:366::-;21430:3;21451:67;21515:2;21510:3;21451:67;:::i;:::-;21444:74;;21527:93;21616:3;21527:93;:::i;:::-;21645:2;21640:3;21636:12;21629:19;;21288:366;;;:::o;21660:419::-;21826:4;21864:2;21853:9;21849:18;21841:26;;21913:9;21907:4;21903:20;21899:1;21888:9;21884:17;21877:47;21941:131;22067:4;21941:131;:::i;:::-;21933:139;;21660:419;;;:::o;22085:166::-;22225:18;22221:1;22213:6;22209:14;22202:42;22085:166;:::o;22257:366::-;22399:3;22420:67;22484:2;22479:3;22420:67;:::i;:::-;22413:74;;22496:93;22585:3;22496:93;:::i;:::-;22614:2;22609:3;22605:12;22598:19;;22257:366;;;:::o;22629:419::-;22795:4;22833:2;22822:9;22818:18;22810:26;;22882:9;22876:4;22872:20;22868:1;22857:9;22853:17;22846:47;22910:131;23036:4;22910:131;:::i;:::-;22902:139;;22629:419;;;:::o;23054:180::-;23102:77;23099:1;23092:88;23199:4;23196:1;23189:15;23223:4;23220:1;23213:15;23240:323;23296:6;23345:2;23333:9;23324:7;23320:23;23316:32;23313:119;;;23351:79;;:::i;:::-;23313:119;23471:1;23496:50;23538:7;23529:6;23518:9;23514:22;23496:50;:::i;:::-;23486:60;;23442:114;23240:323;;;;:::o;23569:180::-;23617:77;23614:1;23607:88;23714:4;23711:1;23704:15;23738:4;23735:1;23728:15;23755:233;23794:3;23817:24;23835:5;23817:24;:::i;:::-;23808:33;;23863:66;23856:5;23853:77;23850:103;;23933:18;;:::i;:::-;23850:103;23980:1;23973:5;23969:13;23962:20;;23755:233;;;:::o;23994:184::-;24093:11;24127:6;24122:3;24115:19;24167:4;24162:3;24158:14;24143:29;;23994:184;;;;:::o;24184:102::-;24253:4;24276:3;24268:11;;24184:102;;;:::o;24292:108::-;24369:24;24387:5;24369:24;:::i;:::-;24364:3;24357:37;24292:108;;:::o;24406:179::-;24475:10;24496:46;24538:3;24530:6;24496:46;:::i;:::-;24574:4;24569:3;24565:14;24551:28;;24406:179;;;;:::o;24591:122::-;24643:5;24668:39;24703:2;24698:3;24694:12;24689:3;24668:39;:::i;:::-;24659:48;;24591:122;;;;:::o;24719:115::-;24791:4;24823;24818:3;24814:14;24806:22;;24719:115;;;:::o;24870:699::-;24999:3;25022:86;25101:6;25096:3;25022:86;:::i;:::-;25015:93;;25132:58;25184:5;25132:58;:::i;:::-;25213:7;25244:1;25229:315;25254:6;25251:1;25248:13;25229:315;;;25324:42;25359:6;25350:7;25324:42;:::i;:::-;25386:63;25445:3;25430:13;25386:63;:::i;:::-;25379:70;;25472:62;25527:6;25472:62;:::i;:::-;25462:72;;25289:255;25276:1;25273;25269:9;25264:14;;25229:315;;;25233:14;25560:3;25553:10;;25004:565;;24870:699;;;;;:::o;25575:181::-;25671:11;25705:6;25700:3;25693:19;25745:4;25740:3;25736:14;25721:29;;25575:181;;;;:::o;25762:99::-;25828:4;25851:3;25843:11;;25762:99;;;:::o;25867:::-;25938:21;25953:5;25938:21;:::i;:::-;25933:3;25926:34;25867:99;;:::o;25972:167::-;26035:10;26056:40;26092:3;26084:6;26056:40;:::i;:::-;26128:4;26123:3;26119:14;26105:28;;25972:167;;;;:::o;26145:116::-;26194:5;26219:36;26251:2;26246:3;26242:12;26237:3;26219:36;:::i;:::-;26210:45;;26145:116;;;;:::o;26267:112::-;26336:4;26368;26363:3;26359:14;26351:22;;26267:112;;;:::o;26409:675::-;26532:3;26555:83;26631:6;26626:3;26555:83;:::i;:::-;26548:90;;26662:55;26711:5;26662:55;:::i;:::-;26740:7;26771:1;26756:303;26781:6;26778:1;26775:13;26756:303;;;26851:39;26883:6;26874:7;26851:39;:::i;:::-;26910:57;26963:3;26948:13;26910:57;:::i;:::-;26903:64;;26990:59;27042:6;26990:59;:::i;:::-;26980:69;;26816:243;26803:1;26800;26796:9;26791:14;;26756:303;;;26760:14;27075:3;27068:10;;26537:547;;26409:675;;;;;:::o;27090:662::-;27325:4;27363:2;27352:9;27348:18;27340:26;;27412:9;27406:4;27402:20;27398:1;27387:9;27383:17;27376:47;27440:118;27553:4;27544:6;27536;27440:118;:::i;:::-;27432:126;;27605:9;27599:4;27595:20;27590:2;27579:9;27575:18;27568:48;27633:112;27740:4;27731:6;27723;27633:112;:::i;:::-;27625:120;;27090:662;;;;;;;:::o;27758:141::-;27807:4;27830:3;27822:11;;27853:3;27850:1;27843:14;27887:4;27884:1;27874:18;27866:26;;27758:141;;;:::o;27905:93::-;27942:6;27989:2;27984;27977:5;27973:14;27969:23;27959:33;;27905:93;;;:::o;28004:107::-;28048:8;28098:5;28092:4;28088:16;28067:37;;28004:107;;;;:::o;28117:393::-;28186:6;28236:1;28224:10;28220:18;28259:97;28289:66;28278:9;28259:97;:::i;:::-;28377:39;28407:8;28396:9;28377:39;:::i;:::-;28365:51;;28449:4;28445:9;28438:5;28434:21;28425:30;;28498:4;28488:8;28484:19;28477:5;28474:30;28464:40;;28193:317;;28117:393;;;;;:::o;28516:142::-;28566:9;28599:53;28617:34;28626:24;28644:5;28626:24;:::i;:::-;28617:34;:::i;:::-;28599:53;:::i;:::-;28586:66;;28516:142;;;:::o;28664:75::-;28707:3;28728:5;28721:12;;28664:75;;;:::o;28745:269::-;28855:39;28886:7;28855:39;:::i;:::-;28916:91;28965:41;28989:16;28965:41;:::i;:::-;28957:6;28950:4;28944:11;28916:91;:::i;:::-;28910:4;28903:105;28821:193;28745:269;;;:::o;29020:73::-;29065:3;29020:73;:::o;29099:189::-;29176:32;;:::i;:::-;29217:65;29275:6;29267;29261:4;29217:65;:::i;:::-;29152:136;29099:189;;:::o;29294:186::-;29354:120;29371:3;29364:5;29361:14;29354:120;;;29425:39;29462:1;29455:5;29425:39;:::i;:::-;29398:1;29391:5;29387:13;29378:22;;29354:120;;;29294:186;;:::o;29486:543::-;29587:2;29582:3;29579:11;29576:446;;;29621:38;29653:5;29621:38;:::i;:::-;29705:29;29723:10;29705:29;:::i;:::-;29695:8;29691:44;29888:2;29876:10;29873:18;29870:49;;;29909:8;29894:23;;29870:49;29932:80;29988:22;30006:3;29988:22;:::i;:::-;29978:8;29974:37;29961:11;29932:80;:::i;:::-;29591:431;;29576:446;29486:543;;;:::o;30035:117::-;30089:8;30139:5;30133:4;30129:16;30108:37;;30035:117;;;;:::o;30158:169::-;30202:6;30235:51;30283:1;30279:6;30271:5;30268:1;30264:13;30235:51;:::i;:::-;30231:56;30316:4;30310;30306:15;30296:25;;30209:118;30158:169;;;;:::o;30332:295::-;30408:4;30554:29;30579:3;30573:4;30554:29;:::i;:::-;30546:37;;30616:3;30613:1;30609:11;30603:4;30600:21;30592:29;;30332:295;;;;:::o;30632:1395::-;30749:37;30782:3;30749:37;:::i;:::-;30851:18;30843:6;30840:30;30837:56;;;30873:18;;:::i;:::-;30837:56;30917:38;30949:4;30943:11;30917:38;:::i;:::-;31002:67;31062:6;31054;31048:4;31002:67;:::i;:::-;31096:1;31120:4;31107:17;;31152:2;31144:6;31141:14;31169:1;31164:618;;;;31826:1;31843:6;31840:77;;;31892:9;31887:3;31883:19;31877:26;31868:35;;31840:77;31943:67;32003:6;31996:5;31943:67;:::i;:::-;31937:4;31930:81;31799:222;31134:887;;31164:618;31216:4;31212:9;31204:6;31200:22;31250:37;31282:4;31250:37;:::i;:::-;31309:1;31323:208;31337:7;31334:1;31331:14;31323:208;;;31416:9;31411:3;31407:19;31401:26;31393:6;31386:42;31467:1;31459:6;31455:14;31445:24;;31514:2;31503:9;31499:18;31486:31;;31360:4;31357:1;31353:12;31348:17;;31323:208;;;31559:6;31550:7;31547:19;31544:179;;;31617:9;31612:3;31608:19;31602:26;31660:48;31702:4;31694:6;31690:17;31679:9;31660:48;:::i;:::-;31652:6;31645:64;31567:156;31544:179;31769:1;31765;31757:6;31753:14;31749:22;31743:4;31736:36;31171:611;;;31134:887;;30724:1303;;;30632:1395;;:::o;32033:514::-;32194:4;32232:2;32221:9;32217:18;32209:26;;32281:9;32275:4;32271:20;32267:1;32256:9;32252:17;32245:47;32309:78;32382:4;32373:6;32309:78;:::i;:::-;32301:86;;32434:9;32428:4;32424:20;32419:2;32408:9;32404:18;32397:48;32462:78;32535:4;32526:6;32462:78;:::i;:::-;32454:86;;32033:514;;;;;:::o;32553:191::-;32593:3;32612:20;32630:1;32612:20;:::i;:::-;32607:25;;32646:20;32664:1;32646:20;:::i;:::-;32641:25;;32689:1;32686;32682:9;32675:16;;32710:3;32707:1;32704:10;32701:36;;;32717:18;;:::i;:::-;32701:36;32553:191;;;;:::o;32750:169::-;32890:21;32886:1;32878:6;32874:14;32867:45;32750:169;:::o;32925:366::-;33067:3;33088:67;33152:2;33147:3;33088:67;:::i;:::-;33081:74;;33164:93;33253:3;33164:93;:::i;:::-;33282:2;33277:3;33273:12;33266:19;;32925:366;;;:::o;33297:419::-;33463:4;33501:2;33490:9;33486:18;33478:26;;33550:9;33544:4;33540:20;33536:1;33525:9;33521:17;33514:47;33578:131;33704:4;33578:131;:::i;:::-;33570:139;;33297:419;;;:::o;33722:174::-;33862:26;33858:1;33850:6;33846:14;33839:50;33722:174;:::o;33902:366::-;34044:3;34065:67;34129:2;34124:3;34065:67;:::i;:::-;34058:74;;34141:93;34230:3;34141:93;:::i;:::-;34259:2;34254:3;34250:12;34243:19;;33902:366;;;:::o;34274:419::-;34440:4;34478:2;34467:9;34463:18;34455:26;;34527:9;34521:4;34517:20;34513:1;34502:9;34498:17;34491:47;34555:131;34681:4;34555:131;:::i;:::-;34547:139;;34274:419;;;:::o;34699:143::-;34756:5;34787:6;34781:13;34772:22;;34803:33;34830:5;34803:33;:::i;:::-;34699:143;;;;:::o;34848:351::-;34918:6;34967:2;34955:9;34946:7;34942:23;34938:32;34935:119;;;34973:79;;:::i;:::-;34935:119;35093:1;35118:64;35174:7;35165:6;35154:9;35150:22;35118:64;:::i;:::-;35108:74;;35064:128;34848:351;;;;:::o;35205:222::-;35345:34;35341:1;35333:6;35329:14;35322:58;35414:5;35409:2;35401:6;35397:15;35390:30;35205:222;:::o;35433:366::-;35575:3;35596:67;35660:2;35655:3;35596:67;:::i;:::-;35589:74;;35672:93;35761:3;35672:93;:::i;:::-;35790:2;35785:3;35781:12;35774:19;;35433:366;;;:::o;35805:419::-;35971:4;36009:2;35998:9;35994:18;35986:26;;36058:9;36052:4;36048:20;36044:1;36033:9;36029:17;36022:47;36086:131;36212:4;36086:131;:::i;:::-;36078:139;;35805:419;;;:::o;36230:180::-;36370:32;36366:1;36358:6;36354:14;36347:56;36230:180;:::o;36416:366::-;36558:3;36579:67;36643:2;36638:3;36579:67;:::i;:::-;36572:74;;36655:93;36744:3;36655:93;:::i;:::-;36773:2;36768:3;36764:12;36757:19;;36416:366;;;:::o;36788:419::-;36954:4;36992:2;36981:9;36977:18;36969:26;;37041:9;37035:4;37031:20;37027:1;37016:9;37012:17;37005:47;37069:131;37195:4;37069:131;:::i;:::-;37061:139;;36788:419;;;:::o;37213:184::-;37312:11;37346:6;37341:3;37334:19;37386:4;37381:3;37377:14;37362:29;;37213:184;;;;:::o;37403:117::-;37512:1;37509;37502:12;37526:98;37610:6;37605:3;37600;37587:30;37526:98;;;:::o;37660:537::-;37788:3;37809:86;37888:6;37883:3;37809:86;:::i;:::-;37802:93;;37919:66;37911:6;37908:78;37905:165;;;37989:79;;:::i;:::-;37905:165;38101:4;38093:6;38089:17;38079:27;;38116:43;38152:6;38147:3;38140:5;38116:43;:::i;:::-;38184:6;38179:3;38175:16;38168:23;;37660:537;;;;;:::o;38203:503::-;38384:4;38422:2;38411:9;38407:18;38399:26;;38435:71;38503:1;38492:9;38488:17;38479:6;38435:71;:::i;:::-;38553:9;38547:4;38543:20;38538:2;38527:9;38523:18;38516:48;38581:118;38694:4;38685:6;38677;38581:118;:::i;:::-;38573:126;;38203:503;;;;;;:::o;38712:234::-;38852:34;38848:1;38840:6;38836:14;38829:58;38921:17;38916:2;38908:6;38904:15;38897:42;38712:234;:::o;38952:366::-;39094:3;39115:67;39179:2;39174:3;39115:67;:::i;:::-;39108:74;;39191:93;39280:3;39191:93;:::i;:::-;39309:2;39304:3;39300:12;39293:19;;38952:366;;;:::o;39324:419::-;39490:4;39528:2;39517:9;39513:18;39505:26;;39577:9;39571:4;39567:20;39563:1;39552:9;39548:17;39541:47;39605:131;39731:4;39605:131;:::i;:::-;39597:139;;39324:419;;;:::o;39749:148::-;39851:11;39888:3;39873:18;;39749:148;;;;:::o;39927:874::-;40030:3;40067:5;40061:12;40096:36;40122:9;40096:36;:::i;:::-;40148:89;40230:6;40225:3;40148:89;:::i;:::-;40141:96;;40268:1;40257:9;40253:17;40284:1;40279:166;;;;40459:1;40454:341;;;;40246:549;;40279:166;40363:4;40359:9;40348;40344:25;40339:3;40332:38;40425:6;40418:14;40411:22;40403:6;40399:35;40394:3;40390:45;40383:52;;40279:166;;40454:341;40521:38;40553:5;40521:38;:::i;:::-;40581:1;40595:154;40609:6;40606:1;40603:13;40595:154;;;40683:7;40677:14;40673:1;40668:3;40664:11;40657:35;40733:1;40724:7;40720:15;40709:26;;40631:4;40628:1;40624:12;40619:17;;40595:154;;;40778:6;40773:3;40769:16;40762:23;;40461:334;;40246:549;;40034:767;;39927:874;;;;:::o;40807:390::-;40913:3;40941:39;40974:5;40941:39;:::i;:::-;40996:89;41078:6;41073:3;40996:89;:::i;:::-;40989:96;;41094:65;41152:6;41147:3;41140:4;41133:5;41129:16;41094:65;:::i;:::-;41184:6;41179:3;41175:16;41168:23;;40917:280;40807:390;;;;:::o;41203:583::-;41425:3;41447:92;41535:3;41526:6;41447:92;:::i;:::-;41440:99;;41556:95;41647:3;41638:6;41556:95;:::i;:::-;41549:102;;41668:92;41756:3;41747:6;41668:92;:::i;:::-;41661:99;;41777:3;41770:10;;41203:583;;;;;;:::o;41792:225::-;41932:34;41928:1;41920:6;41916:14;41909:58;42001:8;41996:2;41988:6;41984:15;41977:33;41792:225;:::o;42023:366::-;42165:3;42186:67;42250:2;42245:3;42186:67;:::i;:::-;42179:74;;42262:93;42351:3;42262:93;:::i;:::-;42380:2;42375:3;42371:12;42364:19;;42023:366;;;:::o;42395:419::-;42561:4;42599:2;42588:9;42584:18;42576:26;;42648:9;42642:4;42638:20;42634:1;42623:9;42619:17;42612:47;42676:131;42802:4;42676:131;:::i;:::-;42668:139;;42395:419;;;:::o;42820:175::-;42960:27;42956:1;42948:6;42944:14;42937:51;42820:175;:::o;43001:366::-;43143:3;43164:67;43228:2;43223:3;43164:67;:::i;:::-;43157:74;;43240:93;43329:3;43240:93;:::i;:::-;43358:2;43353:3;43349:12;43342:19;;43001:366;;;:::o;43373:419::-;43539:4;43577:2;43566:9;43562:18;43554:26;;43626:9;43620:4;43616:20;43612:1;43601:9;43597:17;43590:47;43654:131;43780:4;43654:131;:::i;:::-;43646:139;;43373:419;;;:::o;43798:220::-;43938:34;43934:1;43926:6;43922:14;43915:58;44007:3;44002:2;43994:6;43990:15;43983:28;43798:220;:::o;44024:366::-;44166:3;44187:67;44251:2;44246:3;44187:67;:::i;:::-;44180:74;;44263:93;44352:3;44263:93;:::i;:::-;44381:2;44376:3;44372:12;44365:19;;44024:366;;;:::o;44396:419::-;44562:4;44600:2;44589:9;44585:18;44577:26;;44649:9;44643:4;44639:20;44635:1;44624:9;44620:17;44613:47;44677:131;44803:4;44677:131;:::i;:::-;44669:139;;44396:419;;;:::o;44821:177::-;44961:29;44957:1;44949:6;44945:14;44938:53;44821:177;:::o;45004:366::-;45146:3;45167:67;45231:2;45226:3;45167:67;:::i;:::-;45160:74;;45243:93;45332:3;45243:93;:::i;:::-;45361:2;45356:3;45352:12;45345:19;;45004:366;;;:::o;45376:419::-;45542:4;45580:2;45569:9;45565:18;45557:26;;45629:9;45623:4;45619:20;45615:1;45604:9;45600:17;45593:47;45657:131;45783:4;45657:131;:::i;:::-;45649:139;;45376:419;;;:::o;45801:169::-;45941:21;45937:1;45929:6;45925:14;45918:45;45801:169;:::o;45976:366::-;46118:3;46139:67;46203:2;46198:3;46139:67;:::i;:::-;46132:74;;46215:93;46304:3;46215:93;:::i;:::-;46333:2;46328:3;46324:12;46317:19;;45976:366;;;:::o;46348:419::-;46514:4;46552:2;46541:9;46537:18;46529:26;;46601:9;46595:4;46591:20;46587:1;46576:9;46572:17;46565:47;46629:131;46755:4;46629:131;:::i;:::-;46621:139;;46348:419;;;:::o;46773:410::-;46813:7;46836:20;46854:1;46836:20;:::i;:::-;46831:25;;46870:20;46888:1;46870:20;:::i;:::-;46865:25;;46925:1;46922;46918:9;46947:30;46965:11;46947:30;:::i;:::-;46936:41;;47126:1;47117:7;47113:15;47110:1;47107:22;47087:1;47080:9;47060:83;47037:139;;47156:18;;:::i;:::-;47037:139;46821:362;46773:410;;;;:::o;47189:167::-;47329:19;47325:1;47317:6;47313:14;47306:43;47189:167;:::o;47362:366::-;47504:3;47525:67;47589:2;47584:3;47525:67;:::i;:::-;47518:74;;47601:93;47690:3;47601:93;:::i;:::-;47719:2;47714:3;47710:12;47703:19;;47362:366;;;:::o;47734:419::-;47900:4;47938:2;47927:9;47923:18;47915:26;;47987:9;47981:4;47977:20;47973:1;47962:9;47958:17;47951:47;48015:131;48141:4;48015:131;:::i;:::-;48007:139;;47734:419;;;:::o;48159:182::-;48299:34;48295:1;48287:6;48283:14;48276:58;48159:182;:::o;48347:366::-;48489:3;48510:67;48574:2;48569:3;48510:67;:::i;:::-;48503:74;;48586:93;48675:3;48586:93;:::i;:::-;48704:2;48699:3;48695:12;48688:19;;48347:366;;;:::o;48719:419::-;48885:4;48923:2;48912:9;48908:18;48900:26;;48972:9;48966:4;48962:20;48958:1;48947:9;48943:17;48936:47;49000:131;49126:4;49000:131;:::i;:::-;48992:139;;48719:419;;;:::o;49144:98::-;49195:6;49229:5;49223:12;49213:22;;49144:98;;;:::o;49248:168::-;49331:11;49365:6;49360:3;49353:19;49405:4;49400:3;49396:14;49381:29;;49248:168;;;;:::o;49422:373::-;49508:3;49536:38;49568:5;49536:38;:::i;:::-;49590:70;49653:6;49648:3;49590:70;:::i;:::-;49583:77;;49669:65;49727:6;49722:3;49715:4;49708:5;49704:16;49669:65;:::i;:::-;49759:29;49781:6;49759:29;:::i;:::-;49754:3;49750:39;49743:46;;49512:283;49422:373;;;;:::o;49801:640::-;49996:4;50034:3;50023:9;50019:19;50011:27;;50048:71;50116:1;50105:9;50101:17;50092:6;50048:71;:::i;:::-;50129:72;50197:2;50186:9;50182:18;50173:6;50129:72;:::i;:::-;50211;50279:2;50268:9;50264:18;50255:6;50211:72;:::i;:::-;50330:9;50324:4;50320:20;50315:2;50304:9;50300:18;50293:48;50358:76;50429:4;50420:6;50358:76;:::i;:::-;50350:84;;49801:640;;;;;;;:::o;50447:141::-;50503:5;50534:6;50528:13;50519:22;;50550:32;50576:5;50550:32;:::i;:::-;50447:141;;;;:::o;50594:349::-;50663:6;50712:2;50700:9;50691:7;50687:23;50683:32;50680:119;;;50718:79;;:::i;:::-;50680:119;50838:1;50863:63;50918:7;50909:6;50898:9;50894:22;50863:63;:::i;:::-;50853:73;;50809:127;50594:349;;;;:::o;50949:180::-;50997:77;50994:1;50987:88;51094:4;51091:1;51084:15;51118:4;51115:1;51108:15;51135:166;51275:18;51271:1;51263:6;51259:14;51252:42;51135:166;:::o;51307:402::-;51467:3;51488:85;51570:2;51565:3;51488:85;:::i;:::-;51481:92;;51582:93;51671:3;51582:93;:::i;:::-;51700:2;51695:3;51691:12;51684:19;;51307:402;;;:::o;51715:94::-;51748:8;51796:5;51792:2;51788:14;51767:35;;51715:94;;;:::o;51815:::-;51854:7;51883:20;51897:5;51883:20;:::i;:::-;51872:31;;51815:94;;;:::o;51915:100::-;51954:7;51983:26;52003:5;51983:26;:::i;:::-;51972:37;;51915:100;;;:::o;52021:157::-;52126:45;52146:24;52164:5;52146:24;:::i;:::-;52126:45;:::i;:::-;52121:3;52114:58;52021:157;;:::o;52184:522::-;52397:3;52419:148;52563:3;52419:148;:::i;:::-;52412:155;;52577:75;52648:3;52639:6;52577:75;:::i;:::-;52677:2;52672:3;52668:12;52661:19;;52697:3;52690:10;;52184:522;;;;:::o;52712:214::-;52852:66;52848:1;52840:6;52836:14;52829:90;52712:214;:::o;52932:402::-;53092:3;53113:85;53195:2;53190:3;53113:85;:::i;:::-;53106:92;;53207:93;53296:3;53207:93;:::i;:::-;53325:2;53320:3;53316:12;53309:19;;52932:402;;;:::o;53340:77::-;53377:7;53406:5;53395:16;;53340:77;;;:::o;53423:79::-;53462:7;53491:5;53480:16;;53423:79;;;:::o;53508:157::-;53613:45;53633:24;53651:5;53633:24;:::i;:::-;53613:45;:::i;:::-;53608:3;53601:58;53508:157;;:::o;53671:522::-;53884:3;53906:148;54050:3;53906:148;:::i;:::-;53899:155;;54064:75;54135:3;54126:6;54064:75;:::i;:::-;54164:2;54159:3;54155:12;54148:19;;54184:3;54177:10;;53671:522;;;;:::o;54199:180::-;54247:77;54244:1;54237:88;54344:4;54341:1;54334:15;54368:4;54365:1;54358:15;54385:174;54525:26;54521:1;54513:6;54509:14;54502:50;54385:174;:::o;54565:366::-;54707:3;54728:67;54792:2;54787:3;54728:67;:::i;:::-;54721:74;;54804:93;54893:3;54804:93;:::i;:::-;54922:2;54917:3;54913:12;54906:19;;54565:366;;;:::o;54937:419::-;55103:4;55141:2;55130:9;55126:18;55118:26;;55190:9;55184:4;55180:20;55176:1;55165:9;55161:17;55154:47;55218:131;55344:4;55218:131;:::i;:::-;55210:139;;54937:419;;;:::o;55362:181::-;55502:33;55498:1;55490:6;55486:14;55479:57;55362:181;:::o;55549:366::-;55691:3;55712:67;55776:2;55771:3;55712:67;:::i;:::-;55705:74;;55788:93;55877:3;55788:93;:::i;:::-;55906:2;55901:3;55897:12;55890:19;;55549:366;;;:::o;55921:419::-;56087:4;56125:2;56114:9;56110:18;56102:26;;56174:9;56168:4;56164:20;56160:1;56149:9;56145:17;56138:47;56202:131;56328:4;56202:131;:::i;:::-;56194:139;;55921:419;;;:::o;56346:221::-;56486:34;56482:1;56474:6;56470:14;56463:58;56555:4;56550:2;56542:6;56538:15;56531:29;56346:221;:::o;56573:366::-;56715:3;56736:67;56800:2;56795:3;56736:67;:::i;:::-;56729:74;;56812:93;56901:3;56812:93;:::i;:::-;56930:2;56925:3;56921:12;56914:19;;56573:366;;;:::o;56945:419::-;57111:4;57149:2;57138:9;57134:18;57126:26;;57198:9;57192:4;57188:20;57184:1;57173:9;57169:17;57162:47;57226:131;57352:4;57226:131;:::i;:::-;57218:139;;56945:419;;;:::o;57370:118::-;57457:24;57475:5;57457:24;:::i;:::-;57452:3;57445:37;57370:118;;:::o;57494:86::-;57529:7;57569:4;57562:5;57558:16;57547:27;;57494:86;;;:::o;57586:112::-;57669:22;57685:5;57669:22;:::i;:::-;57664:3;57657:35;57586:112;;:::o;57704:545::-;57877:4;57915:3;57904:9;57900:19;57892:27;;57929:71;57997:1;57986:9;57982:17;57973:6;57929:71;:::i;:::-;58010:68;58074:2;58063:9;58059:18;58050:6;58010:68;:::i;:::-;58088:72;58156:2;58145:9;58141:18;58132:6;58088:72;:::i;:::-;58170;58238:2;58227:9;58223:18;58214:6;58170:72;:::i;:::-;57704:545;;;;;;;:::o

Swarm Source

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