ETH Price: $3,340.01 (-1.03%)
Gas: 9 Gwei

Token

Citizenship (EMBASSY)
 

Overview

Max Total Supply

212 EMBASSY

Holders

143

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 EMBASSY
0x3f3fdD1Ee0653C12eFfE705bFFc2C49a640c68dc
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:
Web3Embassy

Compiler Version
v0.8.25+commit.b61c2a91

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, Unlicense license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2024-05-26
*/

// SPDX-License-Identifier: UNLICENSED
// File: erc721a/contracts/IERC721A.sol


// ERC721A Contracts v4.3.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();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: erc721a/contracts/ERC721A.sol


// ERC721A Contracts v4.3.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()`.
 *
 * The `_sequentialUpTo()` function can be overriden to enable spot mints
 * (i.e. non-consecutive mints) for `tokenId`s greater than `_sequentialUpTo()`.
 *
 * Assumptions:
 *
 * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364).
    struct TokenApprovalRef {
        address value;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        return _tokenApprovals[tokenId].value;
    }

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

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

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

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

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

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

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

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

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

        // Mask `from` to the lower 160 bits, in case the upper bits somehow aren't clean.
        from = address(uint160(uint256(uint160(from)) & _BITMASK_ADDRESS));

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

        (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.selector);

        _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;
                    }
                }
            }
        }

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

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

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

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

    /**
     * @dev 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.selector);
            }
            assembly {
                revert(add(32, reason), mload(reason))
            }
        }
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            ++_spotMinted;
        }

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

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

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

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

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

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

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

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

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

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

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

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

        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.selector);
        }

        _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 + _spotMinted` 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.selector);
        uint256 extraDataCasted;
        // Cast `extraData` with assembly to avoid redundant masking.
        assembly {
            extraDataCasted := extraData
        }
        packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA);
        _packedOwnerships[index] = packed;
    }

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

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

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

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

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

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

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

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

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

// File: @limitbreak/creator-token-contracts/contracts/utils/TransferPolicy.sol


pragma solidity ^0.8.4;

enum AllowlistTypes {
    Operators,
    PermittedContractReceivers
}

enum ReceiverConstraints {
    None,
    NoCode,
    EOA
}

enum CallerConstraints {
    None,
    OperatorWhitelistEnableOTC,
    OperatorWhitelistDisableOTC
}

enum StakerConstraints {
    None,
    CallerIsTxOrigin,
    EOA
}

enum TransferSecurityLevels {
    Zero,
    One,
    Two,
    Three,
    Four,
    Five,
    Six
}

struct TransferSecurityPolicy {
    CallerConstraints callerConstraints;
    ReceiverConstraints receiverConstraints;
}

struct CollectionSecurityPolicy {
    TransferSecurityLevels transferSecurityLevel;
    uint120 operatorWhitelistId;
    uint120 permittedContractReceiversId;
}

// File: @limitbreak/creator-token-contracts/contracts/interfaces/ITransferValidator.sol


pragma solidity ^0.8.4;


interface ITransferValidator {
    function applyCollectionTransferPolicy(address caller, address from, address to) external view;
}
// File: @limitbreak/creator-token-contracts/contracts/interfaces/ITransferSecurityRegistry.sol


pragma solidity ^0.8.4;


interface ITransferSecurityRegistry {
    event AddedToAllowlist(AllowlistTypes indexed kind, uint256 indexed id, address indexed account);
    event CreatedAllowlist(AllowlistTypes indexed kind, uint256 indexed id, string indexed name);
    event ReassignedAllowlistOwnership(AllowlistTypes indexed kind, uint256 indexed id, address indexed newOwner);
    event RemovedFromAllowlist(AllowlistTypes indexed kind, uint256 indexed id, address indexed account);
    event SetAllowlist(AllowlistTypes indexed kind, address indexed collection, uint120 indexed id);
    event SetTransferSecurityLevel(address indexed collection, TransferSecurityLevels level);

    function createOperatorWhitelist(string calldata name) external returns (uint120);
    function createPermittedContractReceiverAllowlist(string calldata name) external returns (uint120);
    function reassignOwnershipOfOperatorWhitelist(uint120 id, address newOwner) external;
    function reassignOwnershipOfPermittedContractReceiverAllowlist(uint120 id, address newOwner) external;
    function renounceOwnershipOfOperatorWhitelist(uint120 id) external;
    function renounceOwnershipOfPermittedContractReceiverAllowlist(uint120 id) external;
    function setTransferSecurityLevelOfCollection(address collection, TransferSecurityLevels level) external;
    function setOperatorWhitelistOfCollection(address collection, uint120 id) external;
    function setPermittedContractReceiverAllowlistOfCollection(address collection, uint120 id) external;
    function addOperatorToWhitelist(uint120 id, address operator) external;
    function addPermittedContractReceiverToAllowlist(uint120 id, address receiver) external;
    function removeOperatorFromWhitelist(uint120 id, address operator) external;
    function removePermittedContractReceiverFromAllowlist(uint120 id, address receiver) external;
    function getCollectionSecurityPolicy(address collection) external view returns (CollectionSecurityPolicy memory);
    function getWhitelistedOperators(uint120 id) external view returns (address[] memory);
    function getPermittedContractReceivers(uint120 id) external view returns (address[] memory);
    function isOperatorWhitelisted(uint120 id, address operator) external view returns (bool);
    function isContractReceiverPermitted(uint120 id, address receiver) external view returns (bool);
}
// File: @openzeppelin/contracts/utils/introspection/IERC165.sol


// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// File: @openzeppelin/contracts/interfaces/IERC165.sol


// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol)

pragma solidity ^0.8.20;


// File: @limitbreak/creator-token-contracts/contracts/interfaces/IEOARegistry.sol


pragma solidity ^0.8.4;


interface IEOARegistry is IERC165 {
    function isVerifiedEOA(address account) external view returns (bool);
}
// File: @limitbreak/creator-token-contracts/contracts/interfaces/ICreatorTokenTransferValidator.sol


pragma solidity ^0.8.4;




interface ICreatorTokenTransferValidator is ITransferSecurityRegistry, ITransferValidator, IEOARegistry {}
// File: @limitbreak/creator-token-contracts/contracts/interfaces/ICreatorToken.sol


pragma solidity ^0.8.4;


interface ICreatorToken {
    event TransferValidatorUpdated(address oldValidator, address newValidator);

    function getTransferValidator() external view returns (ICreatorTokenTransferValidator);
    function getSecurityPolicy() external view returns (CollectionSecurityPolicy memory);
    function getWhitelistedOperators() external view returns (address[] memory);
    function getPermittedContractReceivers() external view returns (address[] memory);
    function isOperatorWhitelisted(address operator) external view returns (bool);
    function isContractReceiverPermitted(address receiver) external view returns (bool);
    function isTransferAllowed(address caller, address from, address to) external view returns (bool);
}

// File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol


// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.20;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The tree and the proofs can be generated using our
 * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
 * You will find a quickstart guide in the readme.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the Merkle tree could be reinterpreted as a leaf value.
 * OpenZeppelin's JavaScript library generates Merkle trees that are safe
 * against this attack out of the box.
 */
library MerkleProof {
    /**
     *@dev The multiproof provided is not valid.
     */
    error MerkleProofInvalidMultiproof();

    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Calldata version of {verify}
     */
    function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
        return processProofCalldata(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Calldata version of {processProof}
     */
    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.
     */
    function multiProofVerify(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProof(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Calldata version of {multiProofVerify}
     *
     * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.
     */
    function multiProofVerifyCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProofCalldata(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
     * respectively.
     *
     * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
     */
    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the Merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 proofLen = proof.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        if (leavesLen + proofLen != totalHashes + 1) {
            revert MerkleProofInvalidMultiproof();
        }

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i]
                ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
                : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            if (proofPos != proofLen) {
                revert MerkleProofInvalidMultiproof();
            }
            unchecked {
                return hashes[totalHashes - 1];
            }
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}.
     *
     * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the Merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 proofLen = proof.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        if (leavesLen + proofLen != totalHashes + 1) {
            revert MerkleProofInvalidMultiproof();
        }

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i]
                ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
                : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            if (proofPos != proofLen) {
                revert MerkleProofInvalidMultiproof();
            }
            unchecked {
                return hashes[totalHashes - 1];
            }
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Sorts the pair (a, b) and hashes the result.
     */
    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
    }

    /**
     * @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory.
     */
    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

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

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

// File: @limitbreak/creator-token-contracts/contracts/utils/TransferValidation.sol


pragma solidity ^0.8.4;


/**
 * @title TransferValidation
 * @author Limit Break, Inc.
 * @notice A mix-in that can be combined with ERC-721 contracts to provide more granular hooks.
 * Openzeppelin's ERC721 contract only provides hooks for before and after transfer.  This allows
 * developers to validate or customize transfers within the context of a mint, a burn, or a transfer.
 */
abstract contract TransferValidation is Context {
    
    error ShouldNotMintToBurnAddress();

    /// @dev Inheriting contracts should call this function in the _beforeTokenTransfer function to get more granular hooks.
    function _validateBeforeTransfer(address from, address to, uint256 tokenId) internal virtual {
        bool fromZeroAddress = from == address(0);
        bool toZeroAddress = to == address(0);

        if(fromZeroAddress && toZeroAddress) {
            revert ShouldNotMintToBurnAddress();
        } else if(fromZeroAddress) {
            _preValidateMint(_msgSender(), to, tokenId, msg.value);
        } else if(toZeroAddress) {
            _preValidateBurn(_msgSender(), from, tokenId, msg.value);
        } else {
            _preValidateTransfer(_msgSender(), from, to, tokenId, msg.value);
        }
    }

    /// @dev Inheriting contracts should call this function in the _afterTokenTransfer function to get more granular hooks.
    function _validateAfterTransfer(address from, address to, uint256 tokenId) internal virtual {
        bool fromZeroAddress = from == address(0);
        bool toZeroAddress = to == address(0);

        if(fromZeroAddress && toZeroAddress) {
            revert ShouldNotMintToBurnAddress();
        } else if(fromZeroAddress) {
            _postValidateMint(_msgSender(), to, tokenId, msg.value);
        } else if(toZeroAddress) {
            _postValidateBurn(_msgSender(), from, tokenId, msg.value);
        } else {
            _postValidateTransfer(_msgSender(), from, to, tokenId, msg.value);
        }
    }

    /// @dev Optional validation hook that fires before a mint
    function _preValidateMint(address caller, address to, uint256 tokenId, uint256 value) internal virtual {}

    /// @dev Optional validation hook that fires after a mint
    function _postValidateMint(address caller, address to, uint256 tokenId, uint256 value) internal virtual {}

    /// @dev Optional validation hook that fires before a burn
    function _preValidateBurn(address caller, address from, uint256 tokenId, uint256 value) internal virtual {}

    /// @dev Optional validation hook that fires after a burn
    function _postValidateBurn(address caller, address from, uint256 tokenId, uint256 value) internal virtual {}

    /// @dev Optional validation hook that fires before a transfer
    function _preValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 value) internal virtual {}

    /// @dev Optional validation hook that fires after a transfer
    function _postValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 value) internal virtual {}
}

// File: @limitbreak/creator-token-contracts/contracts/access/OwnablePermissions.sol


pragma solidity ^0.8.4;


abstract contract OwnablePermissions is Context {
    function _requireCallerIsContractOwner() internal view virtual;
}

// File: @limitbreak/creator-token-contracts/contracts/utils/CreatorTokenBase.sol


pragma solidity ^0.8.4;






/**
 * @title CreatorTokenBase
 * @author Limit Break, Inc.
 * @notice CreatorTokenBase is an abstract contract that provides basic functionality for managing token 
 * transfer policies through an implementation of ICreatorTokenTransferValidator. This contract is intended to be used
 * as a base for creator-specific token contracts, enabling customizable transfer restrictions and security policies.
 *
 * <h4>Features:</h4>
 * <ul>Ownable: This contract can have an owner who can set and update the transfer validator.</ul>
 * <ul>TransferValidation: Implements the basic token transfer validation interface.</ul>
 * <ul>ICreatorToken: Implements the interface for creator tokens, providing view functions for token security policies.</ul>
 *
 * <h4>Benefits:</h4>
 * <ul>Provides a flexible and modular way to implement custom token transfer restrictions and security policies.</ul>
 * <ul>Allows creators to enforce policies such as whitelisted operators and permitted contract receivers.</ul>
 * <ul>Can be easily integrated into other token contracts as a base contract.</ul>
 *
 * <h4>Intended Usage:</h4>
 * <ul>Use as a base contract for creator token implementations that require advanced transfer restrictions and 
 *   security policies.</ul>
 * <ul>Set and update the ICreatorTokenTransferValidator implementation contract to enforce desired policies for the 
 *   creator token.</ul>
 */
abstract contract CreatorTokenBase is OwnablePermissions, TransferValidation, ICreatorToken {
    
    error CreatorTokenBase__InvalidTransferValidatorContract();
    error CreatorTokenBase__SetTransferValidatorFirst();

    address public constant DEFAULT_TRANSFER_VALIDATOR = address(0x0000721C310194CcfC01E523fc93C9cCcFa2A0Ac);
    TransferSecurityLevels public constant DEFAULT_TRANSFER_SECURITY_LEVEL = TransferSecurityLevels.One;
    uint120 public constant DEFAULT_OPERATOR_WHITELIST_ID = uint120(1);

    ICreatorTokenTransferValidator private transferValidator;

    /**
     * @notice Allows the contract owner to set the transfer validator to the official validator contract
     *         and set the security policy to the recommended default settings.
     * @dev    May be overridden to change the default behavior of an individual collection.
     */
    function setToDefaultSecurityPolicy() public virtual {
        _requireCallerIsContractOwner();
        setTransferValidator(DEFAULT_TRANSFER_VALIDATOR);
        ICreatorTokenTransferValidator(DEFAULT_TRANSFER_VALIDATOR).setTransferSecurityLevelOfCollection(address(this), DEFAULT_TRANSFER_SECURITY_LEVEL);
        ICreatorTokenTransferValidator(DEFAULT_TRANSFER_VALIDATOR).setOperatorWhitelistOfCollection(address(this), DEFAULT_OPERATOR_WHITELIST_ID);
    }

    /**
     * @notice Allows the contract owner to set the transfer validator to a custom validator contract
     *         and set the security policy to their own custom settings.
     */
    function setToCustomValidatorAndSecurityPolicy(
        address validator, 
        TransferSecurityLevels level, 
        uint120 operatorWhitelistId, 
        uint120 permittedContractReceiversAllowlistId) public {
        _requireCallerIsContractOwner();

        setTransferValidator(validator);

        ICreatorTokenTransferValidator(validator).
            setTransferSecurityLevelOfCollection(address(this), level);

        ICreatorTokenTransferValidator(validator).
            setOperatorWhitelistOfCollection(address(this), operatorWhitelistId);

        ICreatorTokenTransferValidator(validator).
            setPermittedContractReceiverAllowlistOfCollection(address(this), permittedContractReceiversAllowlistId);
    }

    /**
     * @notice Allows the contract owner to set the security policy to their own custom settings.
     * @dev    Reverts if the transfer validator has not been set.
     */
    function setToCustomSecurityPolicy(
        TransferSecurityLevels level, 
        uint120 operatorWhitelistId, 
        uint120 permittedContractReceiversAllowlistId) public {
        _requireCallerIsContractOwner();

        ICreatorTokenTransferValidator validator = getTransferValidator();
        if (address(validator) == address(0)) {
            revert CreatorTokenBase__SetTransferValidatorFirst();
        }

        validator.setTransferSecurityLevelOfCollection(address(this), level);
        validator.setOperatorWhitelistOfCollection(address(this), operatorWhitelistId);
        validator.setPermittedContractReceiverAllowlistOfCollection(address(this), permittedContractReceiversAllowlistId);
    }

    /**
     * @notice Sets the transfer validator for the token contract.
     *
     * @dev    Throws when provided validator contract is not the zero address and doesn't support 
     *         the ICreatorTokenTransferValidator interface. 
     * @dev    Throws when the caller is not the contract owner.
     *
     * @dev    <h4>Postconditions:</h4>
     *         1. The transferValidator address is updated.
     *         2. The `TransferValidatorUpdated` event is emitted.
     *
     * @param transferValidator_ The address of the transfer validator contract.
     */
    function setTransferValidator(address transferValidator_) public {
        _requireCallerIsContractOwner();

        bool isValidTransferValidator = false;

        if(transferValidator_.code.length > 0) {
            try IERC165(transferValidator_).supportsInterface(type(ICreatorTokenTransferValidator).interfaceId) 
                returns (bool supportsInterface) {
                isValidTransferValidator = supportsInterface;
            } catch {}
        }

        if(transferValidator_ != address(0) && !isValidTransferValidator) {
            revert CreatorTokenBase__InvalidTransferValidatorContract();
        }

        emit TransferValidatorUpdated(address(transferValidator), transferValidator_);

        transferValidator = ICreatorTokenTransferValidator(transferValidator_);
    }

    /**
     * @notice Returns the transfer validator contract address for this token contract.
     */
    function getTransferValidator() public view override returns (ICreatorTokenTransferValidator) {
        return transferValidator;
    }

    /**
     * @notice Returns the security policy for this token contract, which includes:
     *         Transfer security level, operator whitelist id, permitted contract receiver allowlist id.
     */
    function getSecurityPolicy() public view override returns (CollectionSecurityPolicy memory) {
        if (address(transferValidator) != address(0)) {
            return transferValidator.getCollectionSecurityPolicy(address(this));
        }

        return CollectionSecurityPolicy({
            transferSecurityLevel: TransferSecurityLevels.Zero,
            operatorWhitelistId: 0,
            permittedContractReceiversId: 0
        });
    }

    /**
     * @notice Returns the list of all whitelisted operators for this token contract.
     * @dev    This can be an expensive call and should only be used in view-only functions.
     */
    function getWhitelistedOperators() public view override returns (address[] memory) {
        if (address(transferValidator) != address(0)) {
            return transferValidator.getWhitelistedOperators(
                transferValidator.getCollectionSecurityPolicy(address(this)).operatorWhitelistId);
        }

        return new address[](0);
    }

    /**
     * @notice Returns the list of permitted contract receivers for this token contract.
     * @dev    This can be an expensive call and should only be used in view-only functions.
     */
    function getPermittedContractReceivers() public view override returns (address[] memory) {
        if (address(transferValidator) != address(0)) {
            return transferValidator.getPermittedContractReceivers(
                transferValidator.getCollectionSecurityPolicy(address(this)).permittedContractReceiversId);
        }

        return new address[](0);
    }

    /**
     * @notice Checks if an operator is whitelisted for this token contract.
     * @param operator The address of the operator to check.
     */
    function isOperatorWhitelisted(address operator) public view override returns (bool) {
        if (address(transferValidator) != address(0)) {
            return transferValidator.isOperatorWhitelisted(
                transferValidator.getCollectionSecurityPolicy(address(this)).operatorWhitelistId, operator);
        }

        return false;
    }

    /**
     * @notice Checks if a contract receiver is permitted for this token contract.
     * @param receiver The address of the receiver to check.
     */
    function isContractReceiverPermitted(address receiver) public view override returns (bool) {
        if (address(transferValidator) != address(0)) {
            return transferValidator.isContractReceiverPermitted(
                transferValidator.getCollectionSecurityPolicy(address(this)).permittedContractReceiversId, receiver);
        }

        return false;
    }

    /**
     * @notice Determines if a transfer is allowed based on the token contract's security policy.  Use this function
     *         to simulate whether or not a transfer made by the specified `caller` from the `from` address to the `to`
     *         address would be allowed by this token's security policy.
     *
     * @notice This function only checks the security policy restrictions and does not check whether token ownership
     *         or approvals are in place. 
     *
     * @param caller The address of the simulated caller.
     * @param from   The address of the sender.
     * @param to     The address of the receiver.
     * @return       True if the transfer is allowed, false otherwise.
     */
    function isTransferAllowed(address caller, address from, address to) public view override returns (bool) {
        if (address(transferValidator) != address(0)) {
            try transferValidator.applyCollectionTransferPolicy(caller, from, to) {
                return true;
            } catch {
                return false;
            }
        }
        return true;
    }

    /**
     * @dev Pre-validates a token transfer, reverting if the transfer is not allowed by this token's security policy.
     *      Inheriting contracts are responsible for overriding the _beforeTokenTransfer function, or its equivalent
     *      and calling _validateBeforeTransfer so that checks can be properly applied during token transfers.
     *
     * @dev Throws when the transfer doesn't comply with the collection's transfer policy, if the transferValidator is
     *      set to a non-zero address.
     *
     * @param caller  The address of the caller.
     * @param from    The address of the sender.
     * @param to      The address of the receiver.
     */
    function _preValidateTransfer(
        address caller, 
        address from, 
        address to, 
        uint256 /*tokenId*/, 
        uint256 /*value*/) internal virtual override {
        if (address(transferValidator) != address(0)) {
            transferValidator.applyCollectionTransferPolicy(caller, from, to);
        }
    }
}

// File: @limitbreak/creator-token-contracts/contracts/erc721c/ERC721AC.sol


pragma solidity ^0.8.4;



/**
 * @title ERC721AC
 * @author Limit Break, Inc.
 * @notice Extends Azuki's ERC721-A implementation with Creator Token functionality, which
 *         allows the contract owner to update the transfer validation logic by managing a security policy in
 *         an external transfer validation security policy registry.  See {CreatorTokenTransferValidator}.
 */
abstract contract ERC721AC is ERC721A, CreatorTokenBase {

    constructor(string memory name_, string memory symbol_) CreatorTokenBase() ERC721A(name_, symbol_) {}

    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(ICreatorToken).interfaceId || super.supportsInterface(interfaceId);
    }

    /// @dev Ties the erc721a _beforeTokenTransfers hook to more granular transfer validation logic
    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual override {
        for (uint256 i = 0; i < quantity;) {
            _validateBeforeTransfer(from, to, startTokenId + i);
            unchecked {
                ++i;
            }
        }
    }

    /// @dev Ties the erc721a _afterTokenTransfer hook to more granular transfer validation logic
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual override {
        for (uint256 i = 0; i < quantity;) {
            _validateAfterTransfer(from, to, startTokenId + i);
            unchecked {
                ++i;
            }
        }
    }

    function _msgSenderERC721A() internal view virtual override returns (address) {
        return _msgSender();
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;


/**
 * @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.
 *
 * The initial owner is set to the address provided by the deployer. 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;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

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

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @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 {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling 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 {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _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: contracts2/Web3Embassy/Web3Embassy.sol


pragma solidity ^0.8.24;

/*
 __    __                                     __                                           
/\ \__/\ \                                   /\ \                                          
\ \ ,_\ \ \___      __          __    ___ ___\ \ \____     __      ____    ____  __  __    
 \ \ \/\ \  _ `\  /'__`\      /'__`\/' __` __`\ \ '__`\  /'__`\   /',__\  /',__\/\ \/\ \   
  \ \ \_\ \ \ \ \/\  __/     /\  __//\ \/\ \/\ \ \ \L\ \/\ \L\.\_/\__, `\/\__, `\ \ \_\ \  
   \ \__\\ \_\ \_\ \____\    \ \____\ \_\ \_\ \_\ \_,__/\ \__/.\_\/\____/\/\____/\/`____ \ 
    \/__/ \/_/\/_/\/____/     \/____/\/_/\/_/\/_/\/___/  \/__/\/_/\/___/  \/___/  `/___/> \
                                                                                     /\___/
                                                                                     \/__/ 

    Website: https://web3embassy.xyz/
    Twitter: https://twitter.com/web3embassy
    Discord: https://discord.com/invite/embassy
*/




contract Web3Embassy is ERC721AC, Ownable {

    uint256 public maxSupply = 300;
    uint256 public publicSupply = 250;
    uint256 public price = 0.05 ether;
    uint8 public ogMaxMint = 2;
    uint8 public wlMaxMint = 1;
    uint8 public publicMaxMint = 1;
    string public baseURI;
    string public baseExtension = ".json";
    
    mapping(address => bool) public publicMinted;

    bytes32 public ogRoot;
    bytes32 public wlRoot;

    enum MintPhase {
        PAUSED,
        OG_WL_MINT,
        PUBLIC_MINT
    }

    MintPhase public mintPhase;

    constructor(
        address initialOwner,
        string memory initialUri,
        address initialRecipient,
        bytes32 initialOgRoot,
        bytes32 initialWlRoot
    ) 
    ERC721AC("Citizenship", "EMBASSY") 
    Ownable(initialOwner) {

        ogRoot = initialOgRoot;
        wlRoot = initialWlRoot;
        setBaseURI(initialUri);
        _safeMint(initialRecipient, 1);
    }

    function adminMint(address to, uint256 quantity) external onlyOwner {
        require(totalSupply() + quantity <= maxSupply, "Max supply exceed");
        _safeMint(to, quantity);
    }

    function ogMint(uint256 quantity, bytes32[] calldata proof) external payable {
        
        uint256 prevMinted = _getAux(_msgSender());
        bytes32 leaf = keccak256(abi.encodePacked(_msgSender()));

        require(mintPhase == MintPhase.OG_WL_MINT, "Mint phase is not live for OG minting");
        require(MerkleProof.verify(proof, ogRoot, leaf), "Invalid proof");
        require(prevMinted == 0, "OG passes can only be minted in one transaction");
        require(prevMinted + quantity <= ogMaxMint, "You have already minted the maximum amount of OG passes");
        require(totalSupply() + quantity <= publicSupply, "Max supply exceed");
        require(msg.value >= price * quantity, "Insufficient ether sent");

        _setAux(_msgSender(), uint64(prevMinted + quantity));
        _safeMint(_msgSender(), quantity);
    }

    function wlMint(uint256 quantity, bytes32[] calldata proof) external payable {
        
        uint256 prevMinted = _getAux(_msgSender());
        bytes32 leaf = keccak256(abi.encodePacked(_msgSender()));

        require(mintPhase == MintPhase.OG_WL_MINT, "Mint phase is not live for WL minting");
        require(MerkleProof.verify(proof, wlRoot, leaf), "Invalid proof");
        require(prevMinted + quantity <= wlMaxMint, "You have already minted the maximum amount of WL passes");
        require(totalSupply() + quantity <= publicSupply, "Max supply exceed");
        require(msg.value >= price * quantity, "Insufficient ether sent");

        _setAux(_msgSender(), uint64(prevMinted + quantity));
        _safeMint(_msgSender(), quantity);
    }

    function mint(uint256 quantity) external payable {
        
        uint256 prevMinted = _getAux(_msgSender());

        require(mintPhase == MintPhase.PUBLIC_MINT, "Mint phase is not live for public minting");
        require(quantity <= publicMaxMint, "Max public mint exceed");
        require(!publicMinted[msg.sender], "You have already minted the maximum amount of public passes");
        require(totalSupply() + quantity <= publicSupply, "Max supply exceed");
        require(msg.value >= price * quantity, "Insufficient ether sent");

        publicMinted[msg.sender] = true;
        _setAux(_msgSender(), uint64(prevMinted + quantity));
        _safeMint(_msgSender(), quantity);
    }


    ///////////////////////////////////////////////////////////
    // ERC721AC - Creator royalties
    ///////////////////////////////////////////////////////////
    function _requireCallerIsContractOwner() internal view override{}


    // View functions
    function amountMinted(address wallet) external view returns (uint256) {
        return _getAux(wallet);
    }
    
    function _baseURI() internal view virtual override returns (string memory) {
        return baseURI;
    }

    function _startTokenId() internal view virtual override returns (uint256) {
        return 1;
    }
    
    function tokenURI(uint256 tokenId)
    public
    view
    virtual
    override
    returns (string memory)
    {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
           
        string memory currentBaseURI = _baseURI();
        return bytes(currentBaseURI).length > 0
        ? string(abi.encodePacked(currentBaseURI, _toString(tokenId), baseExtension))
        : "";

    }


    // Admin functions
    function setMintPhase(MintPhase phase) external onlyOwner {
        mintPhase = phase;
    }

    function setRoots(bytes32 og, bytes32 wl) external onlyOwner {
        ogRoot = og;
        wlRoot = wl;
    }

    function cutSupply(uint256 newMaxSupply) external onlyOwner {
        require(newMaxSupply < maxSupply, "New max supply must be less than current max supply");
        maxSupply = newMaxSupply;
    }
    
    function setBaseURI(string memory _newURI) public onlyOwner {
        baseURI = _newURI;
    }

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"initialOwner","type":"address"},{"internalType":"string","name":"initialUri","type":"string"},{"internalType":"address","name":"initialRecipient","type":"address"},{"internalType":"bytes32","name":"initialOgRoot","type":"bytes32"},{"internalType":"bytes32","name":"initialWlRoot","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"CreatorTokenBase__InvalidTransferValidatorContract","type":"error"},{"inputs":[],"name":"CreatorTokenBase__SetTransferValidatorFirst","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"NotCompatibleWithSpotMints","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"SequentialMintExceedsLimit","type":"error"},{"inputs":[],"name":"SequentialUpToTooSmall","type":"error"},{"inputs":[],"name":"ShouldNotMintToBurnAddress","type":"error"},{"inputs":[],"name":"SpotMintTokenIdTooSmall","type":"error"},{"inputs":[],"name":"TokenAlreadyExists","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldValidator","type":"address"},{"indexed":false,"internalType":"address","name":"newValidator","type":"address"}],"name":"TransferValidatorUpdated","type":"event"},{"inputs":[],"name":"DEFAULT_OPERATOR_WHITELIST_ID","outputs":[{"internalType":"uint120","name":"","type":"uint120"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_TRANSFER_SECURITY_LEVEL","outputs":[{"internalType":"enum TransferSecurityLevels","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_TRANSFER_VALIDATOR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"adminMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"amountMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxSupply","type":"uint256"}],"name":"cutSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPermittedContractReceivers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSecurityPolicy","outputs":[{"components":[{"internalType":"enum TransferSecurityLevels","name":"transferSecurityLevel","type":"uint8"},{"internalType":"uint120","name":"operatorWhitelistId","type":"uint120"},{"internalType":"uint120","name":"permittedContractReceiversId","type":"uint120"}],"internalType":"struct CollectionSecurityPolicy","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTransferValidator","outputs":[{"internalType":"contract ICreatorTokenTransferValidator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWhitelistedOperators","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"isContractReceiverPermitted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"isOperatorWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"isTransferAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintPhase","outputs":[{"internalType":"enum Web3Embassy.MintPhase","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ogMaxMint","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"ogMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"ogRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicMaxMint","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"publicMinted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum Web3Embassy.MintPhase","name":"phase","type":"uint8"}],"name":"setMintPhase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"og","type":"bytes32"},{"internalType":"bytes32","name":"wl","type":"bytes32"}],"name":"setRoots","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum TransferSecurityLevels","name":"level","type":"uint8"},{"internalType":"uint120","name":"operatorWhitelistId","type":"uint120"},{"internalType":"uint120","name":"permittedContractReceiversAllowlistId","type":"uint120"}],"name":"setToCustomSecurityPolicy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"},{"internalType":"enum TransferSecurityLevels","name":"level","type":"uint8"},{"internalType":"uint120","name":"operatorWhitelistId","type":"uint120"},{"internalType":"uint120","name":"permittedContractReceiversAllowlistId","type":"uint120"}],"name":"setToCustomValidatorAndSecurityPolicy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setToDefaultSecurityPolicy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"transferValidator_","type":"address"}],"name":"setTransferValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wlMaxMint","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"wlMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"wlRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"}]

608060405261012c600b5560fa600c5566b1a2bc2ec50000600d556002600e5f6101000a81548160ff021916908360ff1602179055506001600e60016101000a81548160ff021916908360ff1602179055506001600e60026101000a81548160ff021916908360ff1602179055506040518060400160405280600581526020017f2e6a736f6e000000000000000000000000000000000000000000000000000000815250601090816100b19190610e59565b503480156100bd575f80fd5b50604051616f78380380616f7883398181016040528101906100df91906110d5565b846040518060400160405280600b81526020017f436974697a656e736869700000000000000000000000000000000000000000008152506040518060400160405280600781526020017f454d4241535359000000000000000000000000000000000000000000000000008152508181816002908161015d9190610e59565b50806003908161016d9190610e59565b5061017c61027660201b60201c565b5f8190555061018f61027660201b60201c565b61019d61027e60201b60201c565b10156101ba576101b963fed8210f60e01b6102a560201b60201c565b5b505050505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361022e575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016102259190611177565b60405180910390fd5b61023d816102ad60201b60201c565b50816012819055508060138190555061025b8461037060201b60201c565b61026c83600161039160201b60201c565b5050505050611350565b5f6001905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b805f5260045ffd5b5f600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61037e6103b460201b60201c565b80600f908161038d9190610e59565b5050565b6103b0828260405180602001604052805f81525061044d60201b60201c565b5050565b6103c26104d560201b60201c565b73ffffffffffffffffffffffffffffffffffffffff166103e66104dc60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff161461044b5761040f6104d560201b60201c565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016104429190611177565b60405180910390fd5b565b61045d838361050460201b60201c565b5f8373ffffffffffffffffffffffffffffffffffffffff163b146104d0575f805490505f83820390505b61049f5f8683806001019450866106ae60201b60201c565b6104ba576104b963d1a57ed660e01b6102a560201b60201c565b5b81811061048757815f54146104cd575f80fd5b50505b505050565b5f33905090565b5f600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f805490505f82036105275761052663b562e8dd60e01b6102a560201b60201c565b5b6105395f8483856107e460201b60201c565b6105698361054e5f865f61081c60201b60201c565b61055d8561084960201b60201c565b1761085860201b60201c565b60045f8381526020019081526020015f2081905550600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505f73ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161690505f81036106205761061f632e07630060e01b6102a560201b60201c565b5b5f83830190505f83905061063861027e60201b60201c565b600183031115610659576106586381647e3a60e01b6102a560201b60201c565b5b5b80835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a481816001019150810361065a57815f819055505050506106a95f84838561088260201b60201c565b505050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a026106d96108ba60201b60201c565b8786866040518563ffffffff1660e01b81526004016106fb94939291906111f1565b6020604051808303815f875af192505050801561073657506040513d601f19601f820116820180604052508101906107339190611290565b60015b610791573d805f8114610764576040519150601f19603f3d011682016040523d82523d5f602084013e610769565b606091505b505f8151036107895761078863d1a57ed660e01b6102a560201b60201c565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b5f5b818110156108155761080a858583866107ff91906112e8565b6108ce60201b60201c565b8060010190506107e6565b5050505050565b5f8060e883901c905060e86108388686846109f060201b60201c565b62ffffff16901b9150509392505050565b5f6001821460e11b9050919050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b5f5b818110156108b3576108a88585838661089d91906112e8565b6109f860201b60201c565b806001019050610884565b5050505050565b5f6108c96104d560201b60201c565b905090565b5f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490505f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614905081801561093c5750805b15610973576040517f5cbd944100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b811561099d5761099861098a6104d560201b60201c565b858534610b1a60201b60201c565b6109e9565b80156109c7576109c26109b46104d560201b60201c565b868534610b2060201b60201c565b6109e8565b6109e76109d86104d560201b60201c565b86868634610b2660201b60201c565b5b5b5050505050565b5f9392505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490505f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16149050818015610a665750805b15610a9d576040517f5cbd944100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115610ac757610ac2610ab46104d560201b60201c565b858534610c0c60201b60201c565b610b13565b8015610af157610aec610ade6104d560201b60201c565b868534610c1260201b60201c565b610b12565b610b11610b026104d560201b60201c565b86868634610c1860201b60201c565b5b5b5050505050565b50505050565b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c055760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663285fb8c88686866040518463ffffffff1660e01b8152600401610bd89392919061131b565b5f6040518083038186803b158015610bee575f80fd5b505afa158015610c00573d5f803e3d5ffd5b505050505b5050505050565b50505050565b50505050565b5050505050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680610c9a57607f821691505b602082108103610cad57610cac610c56565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302610d0f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610cd4565b610d198683610cd4565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f610d5d610d58610d5384610d31565b610d3a565b610d31565b9050919050565b5f819050919050565b610d7683610d43565b610d8a610d8282610d64565b848454610ce0565b825550505050565b5f90565b610d9e610d92565b610da9818484610d6d565b505050565b5b81811015610dcc57610dc15f82610d96565b600181019050610daf565b5050565b601f821115610e1157610de281610cb3565b610deb84610cc5565b81016020851015610dfa578190505b610e0e610e0685610cc5565b830182610dae565b50505b505050565b5f82821c905092915050565b5f610e315f1984600802610e16565b1980831691505092915050565b5f610e498383610e22565b9150826002028217905092915050565b610e6282610c1f565b67ffffffffffffffff811115610e7b57610e7a610c29565b5b610e858254610c83565b610e90828285610dd0565b5f60209050601f831160018114610ec1575f8415610eaf578287015190505b610eb98582610e3e565b865550610f20565b601f198416610ecf86610cb3565b5f5b82811015610ef657848901518255600182019150602085019450602081019050610ed1565b86831015610f135784890151610f0f601f891682610e22565b8355505b6001600288020188555050505b505050505050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610f6282610f39565b9050919050565b610f7281610f58565b8114610f7c575f80fd5b50565b5f81519050610f8d81610f69565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b610fb482610f9b565b810181811067ffffffffffffffff82111715610fd357610fd2610c29565b5b80604052505050565b5f610fe5610f28565b9050610ff18282610fab565b919050565b5f67ffffffffffffffff8211156110105761100f610c29565b5b61101982610f9b565b9050602081019050919050565b8281835e5f83830152505050565b5f61104661104184610ff6565b610fdc565b90508281526020810184848401111561106257611061610f97565b5b61106d848285611026565b509392505050565b5f82601f83011261108957611088610f93565b5b8151611099848260208601611034565b91505092915050565b5f819050919050565b6110b4816110a2565b81146110be575f80fd5b50565b5f815190506110cf816110ab565b92915050565b5f805f805f60a086880312156110ee576110ed610f31565b5b5f6110fb88828901610f7f565b955050602086015167ffffffffffffffff81111561111c5761111b610f35565b5b61112888828901611075565b945050604061113988828901610f7f565b935050606061114a888289016110c1565b925050608061115b888289016110c1565b9150509295509295909350565b61117181610f58565b82525050565b5f60208201905061118a5f830184611168565b92915050565b61119981610d31565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f6111c38261119f565b6111cd81856111a9565b93506111dd818560208601611026565b6111e681610f9b565b840191505092915050565b5f6080820190506112045f830187611168565b6112116020830186611168565b61121e6040830185611190565b818103606083015261123081846111b9565b905095945050505050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61126f8161123b565b8114611279575f80fd5b50565b5f8151905061128a81611266565b92915050565b5f602082840312156112a5576112a4610f31565b5b5f6112b28482850161127c565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6112f282610d31565b91506112fd83610d31565b9250828201905080821115611315576113146112bb565b5b92915050565b5f60608201905061132e5f830186611168565b61133b6020830185611168565b6113486040830184611168565b949350505050565b615c1b8061135d5f395ff3fe608060405260043610610319575f3560e01c80636c0360eb116101aa578063ab864ad9116100f6578063da3e316511610094578063e985e9c51161006e578063e985e9c514610b2f578063f2fde38b14610b6b578063f4c4456914610b93578063fd762d9214610bbb57610319565b8063da3e316514610ab3578063e4b3568314610add578063e58306f914610b0757610319565b8063c6682862116100d0578063c6682862146109f9578063c87b56dd14610a23578063d007af5c14610a5f578063d5abeb0114610a8957610319565b8063ab864ad91461098b578063b88d4fde146109b3578063be537f43146109cf57610319565b8063903afdc011610163578063a035b1fe1161013d578063a035b1fe146108f5578063a0712d681461091f578063a22cb4651461093b578063a9fc664e1461096357610319565b8063903afdc01461086557806395d89b411461088f5780639d645a44146108b957610319565b80636c0360eb1461077f5780636c3b8699146107a957806370a08231146107bf578063715018a6146107fb57806382c30987146108115780638da5cb5b1461083b57610319565b80632e8da82911610269578063438a67e7116102225780635d4c1d46116101fc5780635d4c1d46146106c75780635e84d723146106f1578063613471621461071b5780636352211e1461074357610319565b8063438a67e714610639578063495c8bf91461067557806355f804b31461069f57610319565b80632e8da8291461055d578063305c7d4a1461059957806331c07bbf146105c35780633ccfd60b146105eb5780633ef0d36d1461060157806342842e0e1461061d57610319565b80631015805b116102d65780631b25b077116102b05780631b25b077146104bf5780631c33b328146104fb57806323b872dd146105255780632b314dc61461054157610319565b80631015805b1461042f57806317881cbf1461046b57806318160ddd1461049557610319565b8063014635461461031d57806301ffc9a71461034757806306fdde0314610383578063081812fc146103ad578063095ea7b3146103e9578063098144d414610405575b5f80fd5b348015610328575f80fd5b50610331610be3565b60405161033e9190613f98565b60405180910390f35b348015610352575f80fd5b5061036d60048036038101906103689190614017565b610bf9565b60405161037a919061405c565b60405180910390f35b34801561038e575f80fd5b50610397610c72565b6040516103a491906140e5565b60405180910390f35b3480156103b8575f80fd5b506103d360048036038101906103ce9190614138565b610d02565b6040516103e09190613f98565b60405180910390f35b61040360048036038101906103fe919061418d565b610d5b565b005b348015610410575f80fd5b50610419610d6b565b6040516104269190614226565b60405180910390f35b34801561043a575f80fd5b506104556004803603810190610450919061423f565b610d93565b604051610462919061405c565b60405180910390f35b348015610476575f80fd5b5061047f610db0565b60405161048c91906142dd565b60405180910390f35b3480156104a0575f80fd5b506104a9610dc2565b6040516104b69190614305565b60405180910390f35b3480156104ca575f80fd5b506104e560048036038101906104e0919061431e565b610e0d565b6040516104f2919061405c565b60405180910390f35b348015610506575f80fd5b5061050f610f08565b60405161051c91906143b4565b60405180910390f35b61053f600480360381019061053a91906143cd565b610f0d565b005b61055b6004803603810190610556919061447e565b6111b8565b005b348015610568575f80fd5b50610583600480360381019061057e919061423f565b611483565b604051610590919061405c565b60405180910390f35b3480156105a4575f80fd5b506105ad61161f565b6040516105ba91906144f6565b60405180910390f35b3480156105ce575f80fd5b506105e960048036038101906105e49190614532565b611632565b005b3480156105f6575f80fd5b506105ff611666565b005b61061b6004803603810190610616919061447e565b611720565b005b610637600480360381019061063291906143cd565b6119aa565b005b348015610644575f80fd5b5061065f600480360381019061065a919061423f565b6119c9565b60405161066c9190614305565b60405180910390f35b348015610680575f80fd5b506106896119e4565b6040516106969190614614565b60405180910390f35b3480156106aa575f80fd5b506106c560048036038101906106c0919061475c565b611bc8565b005b3480156106d2575f80fd5b506106db611be3565b6040516106e891906147cc565b60405180910390f35b3480156106fc575f80fd5b50610705611be8565b6040516107129190614305565b60405180910390f35b348015610726575f80fd5b50610741600480360381019061073c9190614832565b611bee565b005b34801561074e575f80fd5b5061076960048036038101906107649190614138565b611da4565b6040516107769190613f98565b60405180910390f35b34801561078a575f80fd5b50610793611db5565b6040516107a091906140e5565b60405180910390f35b3480156107b4575f80fd5b506107bd611e41565b005b3480156107ca575f80fd5b506107e560048036038101906107e0919061423f565b611f5c565b6040516107f29190614305565b60405180910390f35b348015610806575f80fd5b5061080f611ff0565b005b34801561081c575f80fd5b50610825612003565b604051610832919061489a565b60405180910390f35b348015610846575f80fd5b5061084f612009565b60405161085c9190613f98565b60405180910390f35b348015610870575f80fd5b50610879612031565b604051610886919061489a565b60405180910390f35b34801561089a575f80fd5b506108a3612037565b6040516108b091906140e5565b60405180910390f35b3480156108c4575f80fd5b506108df60048036038101906108da919061423f565b6120c7565b6040516108ec919061405c565b60405180910390f35b348015610900575f80fd5b50610909612263565b6040516109169190614305565b60405180910390f35b61093960048036038101906109349190614138565b612269565b005b348015610946575f80fd5b50610961600480360381019061095c91906148dd565b612506565b005b34801561096e575f80fd5b506109896004803603810190610984919061423f565b61260c565b005b348015610996575f80fd5b506109b160048036038101906109ac9190614945565b6127c1565b005b6109cd60048036038101906109c89190614a21565b6127db565b005b3480156109da575f80fd5b506109e361282c565b6040516109f09190614aff565b60405180910390f35b348015610a04575f80fd5b50610a0d61297d565b604051610a1a91906140e5565b60405180910390f35b348015610a2e575f80fd5b50610a496004803603810190610a449190614138565b612a09565b604051610a5691906140e5565b60405180910390f35b348015610a6a575f80fd5b50610a73612ab0565b604051610a809190614614565b60405180910390f35b348015610a94575f80fd5b50610a9d612c94565b604051610aaa9190614305565b60405180910390f35b348015610abe575f80fd5b50610ac7612c9a565b604051610ad491906144f6565b60405180910390f35b348015610ae8575f80fd5b50610af1612cac565b604051610afe91906144f6565b60405180910390f35b348015610b12575f80fd5b50610b2d6004803603810190610b28919061418d565b612cbf565b005b348015610b3a575f80fd5b50610b556004803603810190610b509190614b18565b612d2c565b604051610b62919061405c565b60405180910390f35b348015610b76575f80fd5b50610b916004803603810190610b8c919061423f565b612dba565b005b348015610b9e575f80fd5b50610bb96004803603810190610bb49190614138565b612e3e565b005b348015610bc6575f80fd5b50610be16004803603810190610bdc9190614b56565b612e94565b005b71721c310194ccfc01e523fc93c9cccfa2a0ac81565b5f7f86455d28000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610c6b5750610c6a82612fe3565b5b9050919050565b606060028054610c8190614be7565b80601f0160208091040260200160405190810160405280929190818152602001828054610cad90614be7565b8015610cf85780601f10610ccf57610100808354040283529160200191610cf8565b820191905f5260205f20905b815481529060010190602001808311610cdb57829003601f168201915b5050505050905090565b5f610d0c82613074565b610d2157610d2063cf4700e460e01b613117565b5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b610d678282600161311f565b5050565b5f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6011602052805f5260405f205f915054906101000a900460ff1681565b60145f9054906101000a900460ff1681565b5f610dcb613249565b6001545f54030390507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610dfd613251565b14610e0a57600854810190505b90565b5f8073ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610efc5760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663285fb8c88585856040518463ffffffff1660e01b8152600401610ec093929190614c17565b5f6040518083038186803b158015610ed6575f80fd5b505afa925050508015610ee7575060015b610ef3575f9050610f01565b60019050610f01565b600190505b9392505050565b600181565b5f610f1782613278565b905073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161693508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610f8c57610f8b63a114810060e01b613117565b5b5f80610f9784613387565b91509150610fad8187610fa86133aa565b6133b8565b610fd857610fc286610fbd6133aa565b612d2c565b610fd757610fd66359c896be60e01b613117565b5b5b610fe586868660016133fb565b8015610fef575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600101919050819055506110b78561109388888761342d565b7c020000000000000000000000000000000000000000000000000000000017613454565b60045f8681526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000841603611133575f6001850190505f60045f8381526020019081526020015f205403611131575f548114611130578360045f8381526020019081526020015f20819055505b5b505b5f73ffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff161690508481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a45f81036111a2576111a163ea553b3460e01b613117565b5b6111af878787600161347e565b50505050505050565b5f6111c96111c46134b0565b6134b7565b67ffffffffffffffff1690505f6111de6134b0565b6040516020016111ee9190614c91565b6040516020818303038152906040528051906020012090506001600281111561121a5761121961426a565b5b60145f9054906101000a900460ff16600281111561123b5761123a61426a565b5b1461127b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127290614d1b565b60405180910390fd5b6112c88484808060200260200160405190810160405280939291908181526020018383602002808284375f81840152601f19601f8201169050808301925050505050505060125483613501565b611307576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112fe90614d83565b60405180910390fd5b5f8214611349576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134090614e11565b60405180910390fd5b600e5f9054906101000a900460ff1660ff1685836113679190614e5c565b11156113a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139f90614eff565b60405180910390fd5b600c54856113b4610dc2565b6113be9190614e5c565b11156113ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113f690614f67565b60405180910390fd5b84600d5461140d9190614f85565b34101561144f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161144690615010565b60405180910390fd5b61146b61145a6134b0565b86846114669190614e5c565b613517565b61147c6114766134b0565b866135c7565b5050505050565b5f8073ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146116165760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d72dde5e60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b815260040161156f9190613f98565b606060405180830381865afa15801561158a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115ae91906150bb565b60200151846040518363ffffffff1660e01b81526004016115d09291906150e6565b602060405180830381865afa1580156115eb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061160f9190615121565b905061161a565b5f90505b919050565b600e60029054906101000a900460ff1681565b61163a6135e4565b8060145f6101000a81548160ff0219169083600281111561165e5761165d61426a565b5b021790555050565b61166e6135e4565b5f611677612009565b73ffffffffffffffffffffffffffffffffffffffff164760405161169a90615179565b5f6040518083038185875af1925050503d805f81146116d4576040519150601f19603f3d011682016040523d82523d5f602084013e6116d9565b606091505b505090508061171d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611714906151d7565b60405180910390fd5b50565b5f61173161172c6134b0565b6134b7565b67ffffffffffffffff1690505f6117466134b0565b6040516020016117569190614c91565b604051602081830303815290604052805190602001209050600160028111156117825761178161426a565b5b60145f9054906101000a900460ff1660028111156117a3576117a261426a565b5b146117e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117da90615265565b60405180910390fd5b6118308484808060200260200160405190810160405280939291908181526020018383602002808284375f81840152601f19601f8201169050808301925050505050505060135483613501565b61186f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186690614d83565b60405180910390fd5b600e60019054906101000a900460ff1660ff16858361188e9190614e5c565b11156118cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118c6906152f3565b60405180910390fd5b600c54856118db610dc2565b6118e59190614e5c565b1115611926576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161191d90614f67565b60405180910390fd5b84600d546119349190614f85565b341015611976576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196d90615010565b60405180910390fd5b6119926119816134b0565b868461198d9190614e5c565b613517565b6119a361199d6134b0565b866135c7565b5050505050565b6119c483838360405180602001604052805f8152506127db565b505050565b5f6119d3826134b7565b67ffffffffffffffff169050919050565b60605f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611b795760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633fe5df9960095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b8152600401611ad19190613f98565b606060405180830381865afa158015611aec573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b1091906150bb565b602001516040518263ffffffff1660e01b8152600401611b3091906147cc565b5f60405180830381865afa158015611b4a573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190611b7291906153e5565b9050611bc5565b5f67ffffffffffffffff811115611b9357611b92614638565b5b604051908082528060200260200182016040528015611bc15781602001602082028036833780820191505090505b5090505b90565b611bd06135e4565b80600f9081611bdf91906155c0565b5050565b600181565b600c5481565b611bf661366b565b5f611bff610d6b565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611c66576040517f39ffc7ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663da0194c030866040518363ffffffff1660e01b8152600401611ca192919061568f565b5f604051808303815f87803b158015611cb8575f80fd5b505af1158015611cca573d5f803e3d5ffd5b505050508073ffffffffffffffffffffffffffffffffffffffff16632304aa0230856040518363ffffffff1660e01b8152600401611d099291906156b6565b5f604051808303815f87803b158015611d20575f80fd5b505af1158015611d32573d5f803e3d5ffd5b505050508073ffffffffffffffffffffffffffffffffffffffff16638d74431430846040518363ffffffff1660e01b8152600401611d719291906156b6565b5f604051808303815f87803b158015611d88575f80fd5b505af1158015611d9a573d5f803e3d5ffd5b5050505050505050565b5f611dae82613278565b9050919050565b600f8054611dc290614be7565b80601f0160208091040260200160405190810160405280929190818152602001828054611dee90614be7565b8015611e395780601f10611e1057610100808354040283529160200191611e39565b820191905f5260205f20905b815481529060010190602001808311611e1c57829003601f168201915b505050505081565b611e4961366b565b611e6471721c310194ccfc01e523fc93c9cccfa2a0ac61260c565b71721c310194ccfc01e523fc93c9cccfa2a0ac73ffffffffffffffffffffffffffffffffffffffff1663da0194c03060016040518363ffffffff1660e01b8152600401611eb292919061568f565b5f604051808303815f87803b158015611ec9575f80fd5b505af1158015611edb573d5f803e3d5ffd5b5050505071721c310194ccfc01e523fc93c9cccfa2a0ac73ffffffffffffffffffffffffffffffffffffffff16632304aa023060016040518363ffffffff1660e01b8152600401611f2d9291906156b6565b5f604051808303815f87803b158015611f44575f80fd5b505af1158015611f56573d5f803e3d5ffd5b50505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611fa157611fa0638f4eb60460e01b613117565b5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b611ff86135e4565b6120015f61366d565b565b60135481565b5f600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60125481565b60606003805461204690614be7565b80601f016020809104026020016040519081016040528092919081815260200182805461207290614be7565b80156120bd5780601f10612094576101008083540402835291602001916120bd565b820191905f5260205f20905b8154815290600101906020018083116120a057829003601f168201915b5050505050905090565b5f8073ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461225a5760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639445f53060095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b81526004016121b39190613f98565b606060405180830381865afa1580156121ce573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121f291906150bb565b60400151846040518363ffffffff1660e01b81526004016122149291906150e6565b602060405180830381865afa15801561222f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122539190615121565b905061225e565b5f90505b919050565b600d5481565b5f61227a6122756134b0565b6134b7565b67ffffffffffffffff1690506002808111156122995761229861426a565b5b60145f9054906101000a900460ff1660028111156122ba576122b961426a565b5b146122fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122f19061574d565b60405180910390fd5b600e60029054906101000a900460ff1660ff1682111561234f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612346906157b5565b60405180910390fd5b60115f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16156123d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123d090615843565b60405180910390fd5b600c54826123e5610dc2565b6123ef9190614e5c565b1115612430576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161242790614f67565b60405180910390fd5b81600d5461243e9190614f85565b341015612480576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161247790615010565b60405180910390fd5b600160115f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506124f16124e06134b0565b83836124ec9190614e5c565b613517565b6125026124fc6134b0565b836135c7565b5050565b8060075f6125126133aa565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166125bb6133aa565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612600919061405c565b60405180910390a35050565b61261461366b565b5f808273ffffffffffffffffffffffffffffffffffffffff163b11156126b2578173ffffffffffffffffffffffffffffffffffffffff166301ffc9a75f6040518263ffffffff1660e01b815260040161266d9190615870565b602060405180830381865afa9250505080156126a757506040513d601f19601f820116820180604052508101906126a49190615121565b60015b156126b157809150505b5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156126ec575080155b15612723576040517f32483afb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fcc5dc080ff977b3c3a211fa63ab74f90f658f5ba9d3236e92c8f59570f442aac60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683604051612775929190615889565b60405180910390a18160095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6127c96135e4565b81601281905550806013819055505050565b6127e6848484610f0d565b5f8373ffffffffffffffffffffffffffffffffffffffff163b146128265761281084848484613730565b6128255761282463d1a57ed660e01b613117565b5b5b50505050565b612834613f07565b5f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146129285760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b81526004016128e29190613f98565b606060405180830381865afa1580156128fd573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061292191906150bb565b905061297a565b60405180606001604052805f60068111156129465761294561426a565b5b81526020015f6effffffffffffffffffffffffffffff1681526020015f6effffffffffffffffffffffffffffff1681525090505b90565b6010805461298a90614be7565b80601f01602080910402602001604051908101604052809291908181526020018280546129b690614be7565b8015612a015780601f106129d857610100808354040283529160200191612a01565b820191905f5260205f20905b8154815290600101906020018083116129e457829003601f168201915b505050505081565b6060612a1482613074565b612a53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a4a90615920565b60405180910390fd5b5f612a5c61385a565b90505f815111612a7a5760405180602001604052805f815250612aa8565b80612a84846138ea565b6010604051602001612a98939291906159f8565b6040516020818303038152906040525b915050919050565b60605f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612c455760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166317e94a6c60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b8152600401612b9d9190613f98565b606060405180830381865afa158015612bb8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612bdc91906150bb565b604001516040518263ffffffff1660e01b8152600401612bfc91906147cc565b5f60405180830381865afa158015612c16573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190612c3e91906153e5565b9050612c91565b5f67ffffffffffffffff811115612c5f57612c5e614638565b5b604051908082528060200260200182016040528015612c8d5781602001602082028036833780820191505090505b5090505b90565b600b5481565b600e5f9054906101000a900460ff1681565b600e60019054906101000a900460ff1681565b612cc76135e4565b600b5481612cd3610dc2565b612cdd9190614e5c565b1115612d1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1590614f67565b60405180910390fd5b612d2882826135c7565b5050565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b612dc26135e4565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612e32575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401612e299190613f98565b60405180910390fd5b612e3b8161366d565b50565b612e466135e4565b600b548110612e8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e8190615a98565b60405180910390fd5b80600b8190555050565b612e9c61366b565b612ea58461260c565b8373ffffffffffffffffffffffffffffffffffffffff1663da0194c030856040518363ffffffff1660e01b8152600401612ee092919061568f565b5f604051808303815f87803b158015612ef7575f80fd5b505af1158015612f09573d5f803e3d5ffd5b505050508373ffffffffffffffffffffffffffffffffffffffff16632304aa0230846040518363ffffffff1660e01b8152600401612f489291906156b6565b5f604051808303815f87803b158015612f5f575f80fd5b505af1158015612f71573d5f803e3d5ffd5b505050508373ffffffffffffffffffffffffffffffffffffffff16638d74431430836040518363ffffffff1660e01b8152600401612fb09291906156b6565b5f604051808303815f87803b158015612fc7575f80fd5b505af1158015612fd9573d5f803e3d5ffd5b5050505050505050565b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061303d57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061306d5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b5f8161307e613249565b116131115761308b613251565b8211156130b3576130ac60045f8481526020019081526020015f2054613939565b9050613112565b5f54821015613110575f5b5f60045f8581526020019081526020015f2054915081036130ea57826130e390615ab6565b92506130be565b5f7c01000000000000000000000000000000000000000000000000000000008216149150505b5b5b919050565b805f5260045ffd5b5f61312983611da4565b905081801561316b57508073ffffffffffffffffffffffffffffffffffffffff166131526133aa565b73ffffffffffffffffffffffffffffffffffffffff1614155b15613197576131818161317c6133aa565b612d2c565b6131965761319563cfb3b94260e01b613117565b5b5b8360065f8581526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b5f6001905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b5f81613282613249565b116133715760045f8381526020019081526020015f205490506132a3613251565b8211156132c8576132b381613939565b613382576132c763df2d9b4260e01b613117565b5b5f8103613349575f5482106132e8576132e763df2d9b4260e01b613117565b5b5b60045f836001900393508381526020019081526020015f205490505f810315613344575f7c0100000000000000000000000000000000000000000000000000000000821603156133825761334363df2d9b4260e01b613117565b5b6132e9565b5f7c010000000000000000000000000000000000000000000000000000000082160315613382575b61338163df2d9b4260e01b613117565b5b919050565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f6133b36134b0565b905090565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b5f5b818110156134265761341b858583866134169190614e5c565b613979565b8060010190506133fd565b5050505050565b5f8060e883901c905060e8613443868684613a77565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b5f5b818110156134a95761349e858583866134999190614e5c565b613a7f565b806001019050613480565b5050505050565b5f33905090565b5f60c060055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054901c9050919050565b5f8261350d8584613b7d565b1490509392505050565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490505f82905060c081901b77ffffffffffffffffffffffffffffffffffffffffffffffff83161791508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208190555050505050565b6135e0828260405180602001604052805f815250613bcb565b5050565b6135ec6134b0565b73ffffffffffffffffffffffffffffffffffffffff1661360a612009565b73ffffffffffffffffffffffffffffffffffffffff16146136695761362d6134b0565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016136609190613f98565b60405180910390fd5b565b565b5f600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a026137556133aa565b8786866040518563ffffffff1660e01b81526004016137779493929190615b2f565b6020604051808303815f875af19250505080156137b257506040513d601f19601f820116820180604052508101906137af9190615b8d565b60015b613807573d805f81146137e0576040519150601f19603f3d011682016040523d82523d5f602084013e6137e5565b606091505b505f8151036137ff576137fe63d1a57ed660e01b613117565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600f805461386990614be7565b80601f016020809104026020016040519081016040528092919081815260200182805461389590614be7565b80156138e05780601f106138b7576101008083540402835291602001916138e0565b820191905f5260205f20905b8154815290600101906020018083116138c357829003601f168201915b5050505050905090565b606060a060405101806040526020810391505f825281835b60011561392457600184039350600a81066030018453600a8104905080613902575b50828103602084039350808452505050919050565b5f7c0100000000000000000000000000000000000000000000000000000000821673ffffffffffffffffffffffffffffffffffffffff8316119050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490505f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490508180156139e75750805b15613a1e576040517f5cbd944100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115613a3c57613a37613a2f6134b0565b858534613c41565b613a70565b8015613a5a57613a55613a4d6134b0565b868534613c47565b613a6f565b613a6e613a656134b0565b86868634613c4d565b5b5b5050505050565b5f9392505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490505f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16149050818015613aed5750805b15613b24576040517f5cbd944100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115613b4257613b3d613b356134b0565b858534613d33565b613b76565b8015613b6057613b5b613b536134b0565b868534613d39565b613b75565b613b74613b6b6134b0565b86868634613d3f565b5b5b5050505050565b5f808290505f5b8451811015613bc057613bb182868381518110613ba457613ba3615bb8565b5b6020026020010151613d46565b91508080600101915050613b84565b508091505092915050565b613bd58383613d70565b5f8373ffffffffffffffffffffffffffffffffffffffff163b14613c3c575f805490505f83820390505b613c115f868380600101945086613730565b613c2657613c2563d1a57ed660e01b613117565b5b818110613bff57815f5414613c39575f80fd5b50505b505050565b50505050565b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613d2c5760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663285fb8c88686866040518463ffffffff1660e01b8152600401613cff93929190614c17565b5f6040518083038186803b158015613d15575f80fd5b505afa158015613d27573d5f803e3d5ffd5b505050505b5050505050565b50505050565b50505050565b5050505050565b5f818310613d5d57613d588284613ee4565b613d68565b613d678383613ee4565b5b905092915050565b5f805490505f8203613d8d57613d8c63b562e8dd60e01b613117565b5b613d995f8483856133fb565b613db783613da85f865f61342d565b613db185613ef8565b17613454565b60045f8381526020019081526020015f2081905550600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505f73ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161690505f8103613e6857613e67632e07630060e01b613117565b5b5f83830190505f839050613e7a613251565b600183031115613e9557613e946381647e3a60e01b613117565b5b5b80835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4818160010191508103613e9657815f81905550505050613edf5f84838561347e565b505050565b5f825f528160205260405f20905092915050565b5f6001821460e11b9050919050565b60405180606001604052805f6006811115613f2557613f2461426a565b5b81526020015f6effffffffffffffffffffffffffffff1681526020015f6effffffffffffffffffffffffffffff1681525090565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f613f8282613f59565b9050919050565b613f9281613f78565b82525050565b5f602082019050613fab5f830184613f89565b92915050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613ff681613fc2565b8114614000575f80fd5b50565b5f8135905061401181613fed565b92915050565b5f6020828403121561402c5761402b613fba565b5b5f61403984828501614003565b91505092915050565b5f8115159050919050565b61405681614042565b82525050565b5f60208201905061406f5f83018461404d565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6140b782614075565b6140c1818561407f565b93506140d181856020860161408f565b6140da8161409d565b840191505092915050565b5f6020820190508181035f8301526140fd81846140ad565b905092915050565b5f819050919050565b61411781614105565b8114614121575f80fd5b50565b5f813590506141328161410e565b92915050565b5f6020828403121561414d5761414c613fba565b5b5f61415a84828501614124565b91505092915050565b61416c81613f78565b8114614176575f80fd5b50565b5f8135905061418781614163565b92915050565b5f80604083850312156141a3576141a2613fba565b5b5f6141b085828601614179565b92505060206141c185828601614124565b9150509250929050565b5f819050919050565b5f6141ee6141e96141e484613f59565b6141cb565b613f59565b9050919050565b5f6141ff826141d4565b9050919050565b5f614210826141f5565b9050919050565b61422081614206565b82525050565b5f6020820190506142395f830184614217565b92915050565b5f6020828403121561425457614253613fba565b5b5f61426184828501614179565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b600381106142a8576142a761426a565b5b50565b5f8190506142b882614297565b919050565b5f6142c7826142ab565b9050919050565b6142d7816142bd565b82525050565b5f6020820190506142f05f8301846142ce565b92915050565b6142ff81614105565b82525050565b5f6020820190506143185f8301846142f6565b92915050565b5f805f6060848603121561433557614334613fba565b5b5f61434286828701614179565b935050602061435386828701614179565b925050604061436486828701614179565b9150509250925092565b6007811061437f5761437e61426a565b5b50565b5f81905061438f8261436e565b919050565b5f61439e82614382565b9050919050565b6143ae81614394565b82525050565b5f6020820190506143c75f8301846143a5565b92915050565b5f805f606084860312156143e4576143e3613fba565b5b5f6143f186828701614179565b935050602061440286828701614179565b925050604061441386828701614124565b9150509250925092565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261443e5761443d61441d565b5b8235905067ffffffffffffffff81111561445b5761445a614421565b5b60208301915083602082028301111561447757614476614425565b5b9250929050565b5f805f6040848603121561449557614494613fba565b5b5f6144a286828701614124565b935050602084013567ffffffffffffffff8111156144c3576144c2613fbe565b5b6144cf86828701614429565b92509250509250925092565b5f60ff82169050919050565b6144f0816144db565b82525050565b5f6020820190506145095f8301846144e7565b92915050565b6003811061451b575f80fd5b50565b5f8135905061452c8161450f565b92915050565b5f6020828403121561454757614546613fba565b5b5f6145548482850161451e565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61458f81613f78565b82525050565b5f6145a08383614586565b60208301905092915050565b5f602082019050919050565b5f6145c28261455d565b6145cc8185614567565b93506145d783614577565b805f5b838110156146075781516145ee8882614595565b97506145f9836145ac565b9250506001810190506145da565b5085935050505092915050565b5f6020820190508181035f83015261462c81846145b8565b905092915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61466e8261409d565b810181811067ffffffffffffffff8211171561468d5761468c614638565b5b80604052505050565b5f61469f613fb1565b90506146ab8282614665565b919050565b5f67ffffffffffffffff8211156146ca576146c9614638565b5b6146d38261409d565b9050602081019050919050565b828183375f83830152505050565b5f6147006146fb846146b0565b614696565b90508281526020810184848401111561471c5761471b614634565b5b6147278482856146e0565b509392505050565b5f82601f8301126147435761474261441d565b5b81356147538482602086016146ee565b91505092915050565b5f6020828403121561477157614770613fba565b5b5f82013567ffffffffffffffff81111561478e5761478d613fbe565b5b61479a8482850161472f565b91505092915050565b5f6effffffffffffffffffffffffffffff82169050919050565b6147c6816147a3565b82525050565b5f6020820190506147df5f8301846147bd565b92915050565b600781106147f1575f80fd5b50565b5f81359050614802816147e5565b92915050565b614811816147a3565b811461481b575f80fd5b50565b5f8135905061482c81614808565b92915050565b5f805f6060848603121561484957614848613fba565b5b5f614856868287016147f4565b93505060206148678682870161481e565b92505060406148788682870161481e565b9150509250925092565b5f819050919050565b61489481614882565b82525050565b5f6020820190506148ad5f83018461488b565b92915050565b6148bc81614042565b81146148c6575f80fd5b50565b5f813590506148d7816148b3565b92915050565b5f80604083850312156148f3576148f2613fba565b5b5f61490085828601614179565b9250506020614911858286016148c9565b9150509250929050565b61492481614882565b811461492e575f80fd5b50565b5f8135905061493f8161491b565b92915050565b5f806040838503121561495b5761495a613fba565b5b5f61496885828601614931565b925050602061497985828601614931565b9150509250929050565b5f67ffffffffffffffff82111561499d5761499c614638565b5b6149a68261409d565b9050602081019050919050565b5f6149c56149c084614983565b614696565b9050828152602081018484840111156149e1576149e0614634565b5b6149ec8482856146e0565b509392505050565b5f82601f830112614a0857614a0761441d565b5b8135614a188482602086016149b3565b91505092915050565b5f805f8060808587031215614a3957614a38613fba565b5b5f614a4687828801614179565b9450506020614a5787828801614179565b9350506040614a6887828801614124565b925050606085013567ffffffffffffffff811115614a8957614a88613fbe565b5b614a95878288016149f4565b91505092959194509250565b614aaa81614394565b82525050565b614ab9816147a3565b82525050565b606082015f820151614ad35f850182614aa1565b506020820151614ae66020850182614ab0565b506040820151614af96040850182614ab0565b50505050565b5f606082019050614b125f830184614abf565b92915050565b5f8060408385031215614b2e57614b2d613fba565b5b5f614b3b85828601614179565b9250506020614b4c85828601614179565b9150509250929050565b5f805f8060808587031215614b6e57614b6d613fba565b5b5f614b7b87828801614179565b9450506020614b8c878288016147f4565b9350506040614b9d8782880161481e565b9250506060614bae8782880161481e565b91505092959194509250565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680614bfe57607f821691505b602082108103614c1157614c10614bba565b5b50919050565b5f606082019050614c2a5f830186613f89565b614c376020830185613f89565b614c446040830184613f89565b949350505050565b5f8160601b9050919050565b5f614c6282614c4c565b9050919050565b5f614c7382614c58565b9050919050565b614c8b614c8682613f78565b614c69565b82525050565b5f614c9c8284614c7a565b60148201915081905092915050565b7f4d696e74207068617365206973206e6f74206c69766520666f72204f47206d695f8201527f6e74696e67000000000000000000000000000000000000000000000000000000602082015250565b5f614d0560258361407f565b9150614d1082614cab565b604082019050919050565b5f6020820190508181035f830152614d3281614cf9565b9050919050565b7f496e76616c69642070726f6f66000000000000000000000000000000000000005f82015250565b5f614d6d600d8361407f565b9150614d7882614d39565b602082019050919050565b5f6020820190508181035f830152614d9a81614d61565b9050919050565b7f4f47207061737365732063616e206f6e6c79206265206d696e74656420696e205f8201527f6f6e65207472616e73616374696f6e0000000000000000000000000000000000602082015250565b5f614dfb602f8361407f565b9150614e0682614da1565b604082019050919050565b5f6020820190508181035f830152614e2881614def565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f614e6682614105565b9150614e7183614105565b9250828201905080821115614e8957614e88614e2f565b5b92915050565b7f596f75206861766520616c7265616479206d696e74656420746865206d6178695f8201527f6d756d20616d6f756e74206f66204f4720706173736573000000000000000000602082015250565b5f614ee960378361407f565b9150614ef482614e8f565b604082019050919050565b5f6020820190508181035f830152614f1681614edd565b9050919050565b7f4d617820737570706c79206578636565640000000000000000000000000000005f82015250565b5f614f5160118361407f565b9150614f5c82614f1d565b602082019050919050565b5f6020820190508181035f830152614f7e81614f45565b9050919050565b5f614f8f82614105565b9150614f9a83614105565b9250828202614fa881614105565b91508282048414831517614fbf57614fbe614e2f565b5b5092915050565b7f496e73756666696369656e742065746865722073656e740000000000000000005f82015250565b5f614ffa60178361407f565b915061500582614fc6565b602082019050919050565b5f6020820190508181035f83015261502781614fee565b9050919050565b5f80fd5b5f81519050615040816147e5565b92915050565b5f8151905061505481614808565b92915050565b5f6060828403121561506f5761506e61502e565b5b6150796060614696565b90505f61508884828501615032565b5f83015250602061509b84828501615046565b60208301525060406150af84828501615046565b60408301525092915050565b5f606082840312156150d0576150cf613fba565b5b5f6150dd8482850161505a565b91505092915050565b5f6040820190506150f95f8301856147bd565b6151066020830184613f89565b9392505050565b5f8151905061511b816148b3565b92915050565b5f6020828403121561513657615135613fba565b5b5f6151438482850161510d565b91505092915050565b5f81905092915050565b50565b5f6151645f8361514c565b915061516f82615156565b5f82019050919050565b5f61518382615159565b9150819050919050565b7f5769746864726177206661696c656400000000000000000000000000000000005f82015250565b5f6151c1600f8361407f565b91506151cc8261518d565b602082019050919050565b5f6020820190508181035f8301526151ee816151b5565b9050919050565b7f4d696e74207068617365206973206e6f74206c69766520666f7220574c206d695f8201527f6e74696e67000000000000000000000000000000000000000000000000000000602082015250565b5f61524f60258361407f565b915061525a826151f5565b604082019050919050565b5f6020820190508181035f83015261527c81615243565b9050919050565b7f596f75206861766520616c7265616479206d696e74656420746865206d6178695f8201527f6d756d20616d6f756e74206f6620574c20706173736573000000000000000000602082015250565b5f6152dd60378361407f565b91506152e882615283565b604082019050919050565b5f6020820190508181035f83015261530a816152d1565b9050919050565b5f67ffffffffffffffff82111561532b5761532a614638565b5b602082029050602081019050919050565b5f8151905061534a81614163565b92915050565b5f61536261535d84615311565b614696565b9050808382526020820190506020840283018581111561538557615384614425565b5b835b818110156153ae578061539a888261533c565b845260208401935050602081019050615387565b5050509392505050565b5f82601f8301126153cc576153cb61441d565b5b81516153dc848260208601615350565b91505092915050565b5f602082840312156153fa576153f9613fba565b5b5f82015167ffffffffffffffff81111561541757615416613fbe565b5b615423848285016153b8565b91505092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026154887fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261544d565b615492868361544d565b95508019841693508086168417925050509392505050565b5f6154c46154bf6154ba84614105565b6141cb565b614105565b9050919050565b5f819050919050565b6154dd836154aa565b6154f16154e9826154cb565b848454615459565b825550505050565b5f90565b6155056154f9565b6155108184846154d4565b505050565b5b81811015615533576155285f826154fd565b600181019050615516565b5050565b601f821115615578576155498161542c565b6155528461543e565b81016020851015615561578190505b61557561556d8561543e565b830182615515565b50505b505050565b5f82821c905092915050565b5f6155985f198460080261557d565b1980831691505092915050565b5f6155b08383615589565b9150826002028217905092915050565b6155c982614075565b67ffffffffffffffff8111156155e2576155e1614638565b5b6155ec8254614be7565b6155f7828285615537565b5f60209050601f831160018114615628575f8415615616578287015190505b61562085826155a5565b865550615687565b601f1984166156368661542c565b5f5b8281101561565d57848901518255600182019150602085019450602081019050615638565b8683101561567a5784890151615676601f891682615589565b8355505b6001600288020188555050505b505050505050565b5f6040820190506156a25f830185613f89565b6156af60208301846143a5565b9392505050565b5f6040820190506156c95f830185613f89565b6156d660208301846147bd565b9392505050565b7f4d696e74207068617365206973206e6f74206c69766520666f72207075626c695f8201527f63206d696e74696e670000000000000000000000000000000000000000000000602082015250565b5f61573760298361407f565b9150615742826156dd565b604082019050919050565b5f6020820190508181035f8301526157648161572b565b9050919050565b7f4d6178207075626c6963206d696e7420657863656564000000000000000000005f82015250565b5f61579f60168361407f565b91506157aa8261576b565b602082019050919050565b5f6020820190508181035f8301526157cc81615793565b9050919050565b7f596f75206861766520616c7265616479206d696e74656420746865206d6178695f8201527f6d756d20616d6f756e74206f66207075626c6963207061737365730000000000602082015250565b5f61582d603b8361407f565b9150615838826157d3565b604082019050919050565b5f6020820190508181035f83015261585a81615821565b9050919050565b61586a81613fc2565b82525050565b5f6020820190506158835f830184615861565b92915050565b5f60408201905061589c5f830185613f89565b6158a96020830184613f89565b9392505050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f5f8201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b5f61590a602f8361407f565b9150615915826158b0565b604082019050919050565b5f6020820190508181035f830152615937816158fe565b9050919050565b5f81905092915050565b5f61595282614075565b61595c818561593e565b935061596c81856020860161408f565b80840191505092915050565b5f815461598481614be7565b61598e818661593e565b9450600182165f81146159a857600181146159bd576159ef565b60ff19831686528115158202860193506159ef565b6159c68561542c565b5f5b838110156159e7578154818901526001820191506020810190506159c8565b838801955050505b50505092915050565b5f615a038286615948565b9150615a0f8285615948565b9150615a1b8284615978565b9150819050949350505050565b7f4e6577206d617820737570706c79206d757374206265206c657373207468616e5f8201527f2063757272656e74206d617820737570706c7900000000000000000000000000602082015250565b5f615a8260338361407f565b9150615a8d82615a28565b604082019050919050565b5f6020820190508181035f830152615aaf81615a76565b9050919050565b5f615ac082614105565b91505f8203615ad257615ad1614e2f565b5b600182039050919050565b5f81519050919050565b5f82825260208201905092915050565b5f615b0182615add565b615b0b8185615ae7565b9350615b1b81856020860161408f565b615b248161409d565b840191505092915050565b5f608082019050615b425f830187613f89565b615b4f6020830186613f89565b615b5c60408301856142f6565b8181036060830152615b6e8184615af7565b905095945050505050565b5f81519050615b8781613fed565b92915050565b5f60208284031215615ba257615ba1613fba565b5b5f615baf84828501615b79565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffdfea26469706673582212205505e6f74d10a05e150457f4f5e2c3a472349cdd933516707730b8a5556936b464736f6c63430008190033000000000000000000000000fb0513e9c5877ed22afd053855987932d8572fad00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000f53d86d3c10e914b062926f4a07e443b2a341132861483219d848ef9bda9c45305cf4c3282f346b21ec415aaef139b7e7eb44226781252146237c98bb6fe2404e337cb13a83129307c04fe9a9277f127e06970ec0000000000000000000000000000000000000000000000000000000000000036697066733a2f2f516d53544e5463375947595a506f5344376a70676a67464b6245387576485148354c5367614259736875316733382f00000000000000000000

Deployed Bytecode

0x608060405260043610610319575f3560e01c80636c0360eb116101aa578063ab864ad9116100f6578063da3e316511610094578063e985e9c51161006e578063e985e9c514610b2f578063f2fde38b14610b6b578063f4c4456914610b93578063fd762d9214610bbb57610319565b8063da3e316514610ab3578063e4b3568314610add578063e58306f914610b0757610319565b8063c6682862116100d0578063c6682862146109f9578063c87b56dd14610a23578063d007af5c14610a5f578063d5abeb0114610a8957610319565b8063ab864ad91461098b578063b88d4fde146109b3578063be537f43146109cf57610319565b8063903afdc011610163578063a035b1fe1161013d578063a035b1fe146108f5578063a0712d681461091f578063a22cb4651461093b578063a9fc664e1461096357610319565b8063903afdc01461086557806395d89b411461088f5780639d645a44146108b957610319565b80636c0360eb1461077f5780636c3b8699146107a957806370a08231146107bf578063715018a6146107fb57806382c30987146108115780638da5cb5b1461083b57610319565b80632e8da82911610269578063438a67e7116102225780635d4c1d46116101fc5780635d4c1d46146106c75780635e84d723146106f1578063613471621461071b5780636352211e1461074357610319565b8063438a67e714610639578063495c8bf91461067557806355f804b31461069f57610319565b80632e8da8291461055d578063305c7d4a1461059957806331c07bbf146105c35780633ccfd60b146105eb5780633ef0d36d1461060157806342842e0e1461061d57610319565b80631015805b116102d65780631b25b077116102b05780631b25b077146104bf5780631c33b328146104fb57806323b872dd146105255780632b314dc61461054157610319565b80631015805b1461042f57806317881cbf1461046b57806318160ddd1461049557610319565b8063014635461461031d57806301ffc9a71461034757806306fdde0314610383578063081812fc146103ad578063095ea7b3146103e9578063098144d414610405575b5f80fd5b348015610328575f80fd5b50610331610be3565b60405161033e9190613f98565b60405180910390f35b348015610352575f80fd5b5061036d60048036038101906103689190614017565b610bf9565b60405161037a919061405c565b60405180910390f35b34801561038e575f80fd5b50610397610c72565b6040516103a491906140e5565b60405180910390f35b3480156103b8575f80fd5b506103d360048036038101906103ce9190614138565b610d02565b6040516103e09190613f98565b60405180910390f35b61040360048036038101906103fe919061418d565b610d5b565b005b348015610410575f80fd5b50610419610d6b565b6040516104269190614226565b60405180910390f35b34801561043a575f80fd5b506104556004803603810190610450919061423f565b610d93565b604051610462919061405c565b60405180910390f35b348015610476575f80fd5b5061047f610db0565b60405161048c91906142dd565b60405180910390f35b3480156104a0575f80fd5b506104a9610dc2565b6040516104b69190614305565b60405180910390f35b3480156104ca575f80fd5b506104e560048036038101906104e0919061431e565b610e0d565b6040516104f2919061405c565b60405180910390f35b348015610506575f80fd5b5061050f610f08565b60405161051c91906143b4565b60405180910390f35b61053f600480360381019061053a91906143cd565b610f0d565b005b61055b6004803603810190610556919061447e565b6111b8565b005b348015610568575f80fd5b50610583600480360381019061057e919061423f565b611483565b604051610590919061405c565b60405180910390f35b3480156105a4575f80fd5b506105ad61161f565b6040516105ba91906144f6565b60405180910390f35b3480156105ce575f80fd5b506105e960048036038101906105e49190614532565b611632565b005b3480156105f6575f80fd5b506105ff611666565b005b61061b6004803603810190610616919061447e565b611720565b005b610637600480360381019061063291906143cd565b6119aa565b005b348015610644575f80fd5b5061065f600480360381019061065a919061423f565b6119c9565b60405161066c9190614305565b60405180910390f35b348015610680575f80fd5b506106896119e4565b6040516106969190614614565b60405180910390f35b3480156106aa575f80fd5b506106c560048036038101906106c0919061475c565b611bc8565b005b3480156106d2575f80fd5b506106db611be3565b6040516106e891906147cc565b60405180910390f35b3480156106fc575f80fd5b50610705611be8565b6040516107129190614305565b60405180910390f35b348015610726575f80fd5b50610741600480360381019061073c9190614832565b611bee565b005b34801561074e575f80fd5b5061076960048036038101906107649190614138565b611da4565b6040516107769190613f98565b60405180910390f35b34801561078a575f80fd5b50610793611db5565b6040516107a091906140e5565b60405180910390f35b3480156107b4575f80fd5b506107bd611e41565b005b3480156107ca575f80fd5b506107e560048036038101906107e0919061423f565b611f5c565b6040516107f29190614305565b60405180910390f35b348015610806575f80fd5b5061080f611ff0565b005b34801561081c575f80fd5b50610825612003565b604051610832919061489a565b60405180910390f35b348015610846575f80fd5b5061084f612009565b60405161085c9190613f98565b60405180910390f35b348015610870575f80fd5b50610879612031565b604051610886919061489a565b60405180910390f35b34801561089a575f80fd5b506108a3612037565b6040516108b091906140e5565b60405180910390f35b3480156108c4575f80fd5b506108df60048036038101906108da919061423f565b6120c7565b6040516108ec919061405c565b60405180910390f35b348015610900575f80fd5b50610909612263565b6040516109169190614305565b60405180910390f35b61093960048036038101906109349190614138565b612269565b005b348015610946575f80fd5b50610961600480360381019061095c91906148dd565b612506565b005b34801561096e575f80fd5b506109896004803603810190610984919061423f565b61260c565b005b348015610996575f80fd5b506109b160048036038101906109ac9190614945565b6127c1565b005b6109cd60048036038101906109c89190614a21565b6127db565b005b3480156109da575f80fd5b506109e361282c565b6040516109f09190614aff565b60405180910390f35b348015610a04575f80fd5b50610a0d61297d565b604051610a1a91906140e5565b60405180910390f35b348015610a2e575f80fd5b50610a496004803603810190610a449190614138565b612a09565b604051610a5691906140e5565b60405180910390f35b348015610a6a575f80fd5b50610a73612ab0565b604051610a809190614614565b60405180910390f35b348015610a94575f80fd5b50610a9d612c94565b604051610aaa9190614305565b60405180910390f35b348015610abe575f80fd5b50610ac7612c9a565b604051610ad491906144f6565b60405180910390f35b348015610ae8575f80fd5b50610af1612cac565b604051610afe91906144f6565b60405180910390f35b348015610b12575f80fd5b50610b2d6004803603810190610b28919061418d565b612cbf565b005b348015610b3a575f80fd5b50610b556004803603810190610b509190614b18565b612d2c565b604051610b62919061405c565b60405180910390f35b348015610b76575f80fd5b50610b916004803603810190610b8c919061423f565b612dba565b005b348015610b9e575f80fd5b50610bb96004803603810190610bb49190614138565b612e3e565b005b348015610bc6575f80fd5b50610be16004803603810190610bdc9190614b56565b612e94565b005b71721c310194ccfc01e523fc93c9cccfa2a0ac81565b5f7f86455d28000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610c6b5750610c6a82612fe3565b5b9050919050565b606060028054610c8190614be7565b80601f0160208091040260200160405190810160405280929190818152602001828054610cad90614be7565b8015610cf85780601f10610ccf57610100808354040283529160200191610cf8565b820191905f5260205f20905b815481529060010190602001808311610cdb57829003601f168201915b5050505050905090565b5f610d0c82613074565b610d2157610d2063cf4700e460e01b613117565b5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b610d678282600161311f565b5050565b5f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6011602052805f5260405f205f915054906101000a900460ff1681565b60145f9054906101000a900460ff1681565b5f610dcb613249565b6001545f54030390507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610dfd613251565b14610e0a57600854810190505b90565b5f8073ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610efc5760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663285fb8c88585856040518463ffffffff1660e01b8152600401610ec093929190614c17565b5f6040518083038186803b158015610ed6575f80fd5b505afa925050508015610ee7575060015b610ef3575f9050610f01565b60019050610f01565b600190505b9392505050565b600181565b5f610f1782613278565b905073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161693508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610f8c57610f8b63a114810060e01b613117565b5b5f80610f9784613387565b91509150610fad8187610fa86133aa565b6133b8565b610fd857610fc286610fbd6133aa565b612d2c565b610fd757610fd66359c896be60e01b613117565b5b5b610fe586868660016133fb565b8015610fef575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600101919050819055506110b78561109388888761342d565b7c020000000000000000000000000000000000000000000000000000000017613454565b60045f8681526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000841603611133575f6001850190505f60045f8381526020019081526020015f205403611131575f548114611130578360045f8381526020019081526020015f20819055505b5b505b5f73ffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff161690508481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a45f81036111a2576111a163ea553b3460e01b613117565b5b6111af878787600161347e565b50505050505050565b5f6111c96111c46134b0565b6134b7565b67ffffffffffffffff1690505f6111de6134b0565b6040516020016111ee9190614c91565b6040516020818303038152906040528051906020012090506001600281111561121a5761121961426a565b5b60145f9054906101000a900460ff16600281111561123b5761123a61426a565b5b1461127b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127290614d1b565b60405180910390fd5b6112c88484808060200260200160405190810160405280939291908181526020018383602002808284375f81840152601f19601f8201169050808301925050505050505060125483613501565b611307576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112fe90614d83565b60405180910390fd5b5f8214611349576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134090614e11565b60405180910390fd5b600e5f9054906101000a900460ff1660ff1685836113679190614e5c565b11156113a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139f90614eff565b60405180910390fd5b600c54856113b4610dc2565b6113be9190614e5c565b11156113ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113f690614f67565b60405180910390fd5b84600d5461140d9190614f85565b34101561144f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161144690615010565b60405180910390fd5b61146b61145a6134b0565b86846114669190614e5c565b613517565b61147c6114766134b0565b866135c7565b5050505050565b5f8073ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146116165760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d72dde5e60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b815260040161156f9190613f98565b606060405180830381865afa15801561158a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115ae91906150bb565b60200151846040518363ffffffff1660e01b81526004016115d09291906150e6565b602060405180830381865afa1580156115eb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061160f9190615121565b905061161a565b5f90505b919050565b600e60029054906101000a900460ff1681565b61163a6135e4565b8060145f6101000a81548160ff0219169083600281111561165e5761165d61426a565b5b021790555050565b61166e6135e4565b5f611677612009565b73ffffffffffffffffffffffffffffffffffffffff164760405161169a90615179565b5f6040518083038185875af1925050503d805f81146116d4576040519150601f19603f3d011682016040523d82523d5f602084013e6116d9565b606091505b505090508061171d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611714906151d7565b60405180910390fd5b50565b5f61173161172c6134b0565b6134b7565b67ffffffffffffffff1690505f6117466134b0565b6040516020016117569190614c91565b604051602081830303815290604052805190602001209050600160028111156117825761178161426a565b5b60145f9054906101000a900460ff1660028111156117a3576117a261426a565b5b146117e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117da90615265565b60405180910390fd5b6118308484808060200260200160405190810160405280939291908181526020018383602002808284375f81840152601f19601f8201169050808301925050505050505060135483613501565b61186f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186690614d83565b60405180910390fd5b600e60019054906101000a900460ff1660ff16858361188e9190614e5c565b11156118cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118c6906152f3565b60405180910390fd5b600c54856118db610dc2565b6118e59190614e5c565b1115611926576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161191d90614f67565b60405180910390fd5b84600d546119349190614f85565b341015611976576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196d90615010565b60405180910390fd5b6119926119816134b0565b868461198d9190614e5c565b613517565b6119a361199d6134b0565b866135c7565b5050505050565b6119c483838360405180602001604052805f8152506127db565b505050565b5f6119d3826134b7565b67ffffffffffffffff169050919050565b60605f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611b795760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633fe5df9960095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b8152600401611ad19190613f98565b606060405180830381865afa158015611aec573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b1091906150bb565b602001516040518263ffffffff1660e01b8152600401611b3091906147cc565b5f60405180830381865afa158015611b4a573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190611b7291906153e5565b9050611bc5565b5f67ffffffffffffffff811115611b9357611b92614638565b5b604051908082528060200260200182016040528015611bc15781602001602082028036833780820191505090505b5090505b90565b611bd06135e4565b80600f9081611bdf91906155c0565b5050565b600181565b600c5481565b611bf661366b565b5f611bff610d6b565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611c66576040517f39ffc7ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663da0194c030866040518363ffffffff1660e01b8152600401611ca192919061568f565b5f604051808303815f87803b158015611cb8575f80fd5b505af1158015611cca573d5f803e3d5ffd5b505050508073ffffffffffffffffffffffffffffffffffffffff16632304aa0230856040518363ffffffff1660e01b8152600401611d099291906156b6565b5f604051808303815f87803b158015611d20575f80fd5b505af1158015611d32573d5f803e3d5ffd5b505050508073ffffffffffffffffffffffffffffffffffffffff16638d74431430846040518363ffffffff1660e01b8152600401611d719291906156b6565b5f604051808303815f87803b158015611d88575f80fd5b505af1158015611d9a573d5f803e3d5ffd5b5050505050505050565b5f611dae82613278565b9050919050565b600f8054611dc290614be7565b80601f0160208091040260200160405190810160405280929190818152602001828054611dee90614be7565b8015611e395780601f10611e1057610100808354040283529160200191611e39565b820191905f5260205f20905b815481529060010190602001808311611e1c57829003601f168201915b505050505081565b611e4961366b565b611e6471721c310194ccfc01e523fc93c9cccfa2a0ac61260c565b71721c310194ccfc01e523fc93c9cccfa2a0ac73ffffffffffffffffffffffffffffffffffffffff1663da0194c03060016040518363ffffffff1660e01b8152600401611eb292919061568f565b5f604051808303815f87803b158015611ec9575f80fd5b505af1158015611edb573d5f803e3d5ffd5b5050505071721c310194ccfc01e523fc93c9cccfa2a0ac73ffffffffffffffffffffffffffffffffffffffff16632304aa023060016040518363ffffffff1660e01b8152600401611f2d9291906156b6565b5f604051808303815f87803b158015611f44575f80fd5b505af1158015611f56573d5f803e3d5ffd5b50505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611fa157611fa0638f4eb60460e01b613117565b5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b611ff86135e4565b6120015f61366d565b565b60135481565b5f600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60125481565b60606003805461204690614be7565b80601f016020809104026020016040519081016040528092919081815260200182805461207290614be7565b80156120bd5780601f10612094576101008083540402835291602001916120bd565b820191905f5260205f20905b8154815290600101906020018083116120a057829003601f168201915b5050505050905090565b5f8073ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461225a5760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639445f53060095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b81526004016121b39190613f98565b606060405180830381865afa1580156121ce573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121f291906150bb565b60400151846040518363ffffffff1660e01b81526004016122149291906150e6565b602060405180830381865afa15801561222f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122539190615121565b905061225e565b5f90505b919050565b600d5481565b5f61227a6122756134b0565b6134b7565b67ffffffffffffffff1690506002808111156122995761229861426a565b5b60145f9054906101000a900460ff1660028111156122ba576122b961426a565b5b146122fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122f19061574d565b60405180910390fd5b600e60029054906101000a900460ff1660ff1682111561234f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612346906157b5565b60405180910390fd5b60115f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16156123d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123d090615843565b60405180910390fd5b600c54826123e5610dc2565b6123ef9190614e5c565b1115612430576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161242790614f67565b60405180910390fd5b81600d5461243e9190614f85565b341015612480576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161247790615010565b60405180910390fd5b600160115f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506124f16124e06134b0565b83836124ec9190614e5c565b613517565b6125026124fc6134b0565b836135c7565b5050565b8060075f6125126133aa565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166125bb6133aa565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612600919061405c565b60405180910390a35050565b61261461366b565b5f808273ffffffffffffffffffffffffffffffffffffffff163b11156126b2578173ffffffffffffffffffffffffffffffffffffffff166301ffc9a75f6040518263ffffffff1660e01b815260040161266d9190615870565b602060405180830381865afa9250505080156126a757506040513d601f19601f820116820180604052508101906126a49190615121565b60015b156126b157809150505b5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156126ec575080155b15612723576040517f32483afb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fcc5dc080ff977b3c3a211fa63ab74f90f658f5ba9d3236e92c8f59570f442aac60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683604051612775929190615889565b60405180910390a18160095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6127c96135e4565b81601281905550806013819055505050565b6127e6848484610f0d565b5f8373ffffffffffffffffffffffffffffffffffffffff163b146128265761281084848484613730565b6128255761282463d1a57ed660e01b613117565b5b5b50505050565b612834613f07565b5f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146129285760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b81526004016128e29190613f98565b606060405180830381865afa1580156128fd573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061292191906150bb565b905061297a565b60405180606001604052805f60068111156129465761294561426a565b5b81526020015f6effffffffffffffffffffffffffffff1681526020015f6effffffffffffffffffffffffffffff1681525090505b90565b6010805461298a90614be7565b80601f01602080910402602001604051908101604052809291908181526020018280546129b690614be7565b8015612a015780601f106129d857610100808354040283529160200191612a01565b820191905f5260205f20905b8154815290600101906020018083116129e457829003601f168201915b505050505081565b6060612a1482613074565b612a53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a4a90615920565b60405180910390fd5b5f612a5c61385a565b90505f815111612a7a5760405180602001604052805f815250612aa8565b80612a84846138ea565b6010604051602001612a98939291906159f8565b6040516020818303038152906040525b915050919050565b60605f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612c455760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166317e94a6c60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b9554552306040518263ffffffff1660e01b8152600401612b9d9190613f98565b606060405180830381865afa158015612bb8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612bdc91906150bb565b604001516040518263ffffffff1660e01b8152600401612bfc91906147cc565b5f60405180830381865afa158015612c16573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190612c3e91906153e5565b9050612c91565b5f67ffffffffffffffff811115612c5f57612c5e614638565b5b604051908082528060200260200182016040528015612c8d5781602001602082028036833780820191505090505b5090505b90565b600b5481565b600e5f9054906101000a900460ff1681565b600e60019054906101000a900460ff1681565b612cc76135e4565b600b5481612cd3610dc2565b612cdd9190614e5c565b1115612d1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1590614f67565b60405180910390fd5b612d2882826135c7565b5050565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b612dc26135e4565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612e32575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401612e299190613f98565b60405180910390fd5b612e3b8161366d565b50565b612e466135e4565b600b548110612e8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e8190615a98565b60405180910390fd5b80600b8190555050565b612e9c61366b565b612ea58461260c565b8373ffffffffffffffffffffffffffffffffffffffff1663da0194c030856040518363ffffffff1660e01b8152600401612ee092919061568f565b5f604051808303815f87803b158015612ef7575f80fd5b505af1158015612f09573d5f803e3d5ffd5b505050508373ffffffffffffffffffffffffffffffffffffffff16632304aa0230846040518363ffffffff1660e01b8152600401612f489291906156b6565b5f604051808303815f87803b158015612f5f575f80fd5b505af1158015612f71573d5f803e3d5ffd5b505050508373ffffffffffffffffffffffffffffffffffffffff16638d74431430836040518363ffffffff1660e01b8152600401612fb09291906156b6565b5f604051808303815f87803b158015612fc7575f80fd5b505af1158015612fd9573d5f803e3d5ffd5b5050505050505050565b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061303d57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061306d5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b5f8161307e613249565b116131115761308b613251565b8211156130b3576130ac60045f8481526020019081526020015f2054613939565b9050613112565b5f54821015613110575f5b5f60045f8581526020019081526020015f2054915081036130ea57826130e390615ab6565b92506130be565b5f7c01000000000000000000000000000000000000000000000000000000008216149150505b5b5b919050565b805f5260045ffd5b5f61312983611da4565b905081801561316b57508073ffffffffffffffffffffffffffffffffffffffff166131526133aa565b73ffffffffffffffffffffffffffffffffffffffff1614155b15613197576131818161317c6133aa565b612d2c565b6131965761319563cfb3b94260e01b613117565b5b5b8360065f8581526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b5f6001905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b5f81613282613249565b116133715760045f8381526020019081526020015f205490506132a3613251565b8211156132c8576132b381613939565b613382576132c763df2d9b4260e01b613117565b5b5f8103613349575f5482106132e8576132e763df2d9b4260e01b613117565b5b5b60045f836001900393508381526020019081526020015f205490505f810315613344575f7c0100000000000000000000000000000000000000000000000000000000821603156133825761334363df2d9b4260e01b613117565b5b6132e9565b5f7c010000000000000000000000000000000000000000000000000000000082160315613382575b61338163df2d9b4260e01b613117565b5b919050565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f6133b36134b0565b905090565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b5f5b818110156134265761341b858583866134169190614e5c565b613979565b8060010190506133fd565b5050505050565b5f8060e883901c905060e8613443868684613a77565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b5f5b818110156134a95761349e858583866134999190614e5c565b613a7f565b806001019050613480565b5050505050565b5f33905090565b5f60c060055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054901c9050919050565b5f8261350d8584613b7d565b1490509392505050565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490505f82905060c081901b77ffffffffffffffffffffffffffffffffffffffffffffffff83161791508160055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208190555050505050565b6135e0828260405180602001604052805f815250613bcb565b5050565b6135ec6134b0565b73ffffffffffffffffffffffffffffffffffffffff1661360a612009565b73ffffffffffffffffffffffffffffffffffffffff16146136695761362d6134b0565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016136609190613f98565b60405180910390fd5b565b565b5f600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a026137556133aa565b8786866040518563ffffffff1660e01b81526004016137779493929190615b2f565b6020604051808303815f875af19250505080156137b257506040513d601f19601f820116820180604052508101906137af9190615b8d565b60015b613807573d805f81146137e0576040519150601f19603f3d011682016040523d82523d5f602084013e6137e5565b606091505b505f8151036137ff576137fe63d1a57ed660e01b613117565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600f805461386990614be7565b80601f016020809104026020016040519081016040528092919081815260200182805461389590614be7565b80156138e05780601f106138b7576101008083540402835291602001916138e0565b820191905f5260205f20905b8154815290600101906020018083116138c357829003601f168201915b5050505050905090565b606060a060405101806040526020810391505f825281835b60011561392457600184039350600a81066030018453600a8104905080613902575b50828103602084039350808452505050919050565b5f7c0100000000000000000000000000000000000000000000000000000000821673ffffffffffffffffffffffffffffffffffffffff8316119050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490505f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490508180156139e75750805b15613a1e576040517f5cbd944100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115613a3c57613a37613a2f6134b0565b858534613c41565b613a70565b8015613a5a57613a55613a4d6134b0565b868534613c47565b613a6f565b613a6e613a656134b0565b86868634613c4d565b5b5b5050505050565b5f9392505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161490505f8073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16149050818015613aed5750805b15613b24576040517f5cbd944100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115613b4257613b3d613b356134b0565b858534613d33565b613b76565b8015613b6057613b5b613b536134b0565b868534613d39565b613b75565b613b74613b6b6134b0565b86868634613d3f565b5b5b5050505050565b5f808290505f5b8451811015613bc057613bb182868381518110613ba457613ba3615bb8565b5b6020026020010151613d46565b91508080600101915050613b84565b508091505092915050565b613bd58383613d70565b5f8373ffffffffffffffffffffffffffffffffffffffff163b14613c3c575f805490505f83820390505b613c115f868380600101945086613730565b613c2657613c2563d1a57ed660e01b613117565b5b818110613bff57815f5414613c39575f80fd5b50505b505050565b50505050565b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff1660095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613d2c5760095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663285fb8c88686866040518463ffffffff1660e01b8152600401613cff93929190614c17565b5f6040518083038186803b158015613d15575f80fd5b505afa158015613d27573d5f803e3d5ffd5b505050505b5050505050565b50505050565b50505050565b5050505050565b5f818310613d5d57613d588284613ee4565b613d68565b613d678383613ee4565b5b905092915050565b5f805490505f8203613d8d57613d8c63b562e8dd60e01b613117565b5b613d995f8483856133fb565b613db783613da85f865f61342d565b613db185613ef8565b17613454565b60045f8381526020019081526020015f2081905550600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505f73ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161690505f8103613e6857613e67632e07630060e01b613117565b5b5f83830190505f839050613e7a613251565b600183031115613e9557613e946381647e3a60e01b613117565b5b5b80835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4818160010191508103613e9657815f81905550505050613edf5f84838561347e565b505050565b5f825f528160205260405f20905092915050565b5f6001821460e11b9050919050565b60405180606001604052805f6006811115613f2557613f2461426a565b5b81526020015f6effffffffffffffffffffffffffffff1681526020015f6effffffffffffffffffffffffffffff1681525090565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f613f8282613f59565b9050919050565b613f9281613f78565b82525050565b5f602082019050613fab5f830184613f89565b92915050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613ff681613fc2565b8114614000575f80fd5b50565b5f8135905061401181613fed565b92915050565b5f6020828403121561402c5761402b613fba565b5b5f61403984828501614003565b91505092915050565b5f8115159050919050565b61405681614042565b82525050565b5f60208201905061406f5f83018461404d565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6140b782614075565b6140c1818561407f565b93506140d181856020860161408f565b6140da8161409d565b840191505092915050565b5f6020820190508181035f8301526140fd81846140ad565b905092915050565b5f819050919050565b61411781614105565b8114614121575f80fd5b50565b5f813590506141328161410e565b92915050565b5f6020828403121561414d5761414c613fba565b5b5f61415a84828501614124565b91505092915050565b61416c81613f78565b8114614176575f80fd5b50565b5f8135905061418781614163565b92915050565b5f80604083850312156141a3576141a2613fba565b5b5f6141b085828601614179565b92505060206141c185828601614124565b9150509250929050565b5f819050919050565b5f6141ee6141e96141e484613f59565b6141cb565b613f59565b9050919050565b5f6141ff826141d4565b9050919050565b5f614210826141f5565b9050919050565b61422081614206565b82525050565b5f6020820190506142395f830184614217565b92915050565b5f6020828403121561425457614253613fba565b5b5f61426184828501614179565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b600381106142a8576142a761426a565b5b50565b5f8190506142b882614297565b919050565b5f6142c7826142ab565b9050919050565b6142d7816142bd565b82525050565b5f6020820190506142f05f8301846142ce565b92915050565b6142ff81614105565b82525050565b5f6020820190506143185f8301846142f6565b92915050565b5f805f6060848603121561433557614334613fba565b5b5f61434286828701614179565b935050602061435386828701614179565b925050604061436486828701614179565b9150509250925092565b6007811061437f5761437e61426a565b5b50565b5f81905061438f8261436e565b919050565b5f61439e82614382565b9050919050565b6143ae81614394565b82525050565b5f6020820190506143c75f8301846143a5565b92915050565b5f805f606084860312156143e4576143e3613fba565b5b5f6143f186828701614179565b935050602061440286828701614179565b925050604061441386828701614124565b9150509250925092565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261443e5761443d61441d565b5b8235905067ffffffffffffffff81111561445b5761445a614421565b5b60208301915083602082028301111561447757614476614425565b5b9250929050565b5f805f6040848603121561449557614494613fba565b5b5f6144a286828701614124565b935050602084013567ffffffffffffffff8111156144c3576144c2613fbe565b5b6144cf86828701614429565b92509250509250925092565b5f60ff82169050919050565b6144f0816144db565b82525050565b5f6020820190506145095f8301846144e7565b92915050565b6003811061451b575f80fd5b50565b5f8135905061452c8161450f565b92915050565b5f6020828403121561454757614546613fba565b5b5f6145548482850161451e565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61458f81613f78565b82525050565b5f6145a08383614586565b60208301905092915050565b5f602082019050919050565b5f6145c28261455d565b6145cc8185614567565b93506145d783614577565b805f5b838110156146075781516145ee8882614595565b97506145f9836145ac565b9250506001810190506145da565b5085935050505092915050565b5f6020820190508181035f83015261462c81846145b8565b905092915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61466e8261409d565b810181811067ffffffffffffffff8211171561468d5761468c614638565b5b80604052505050565b5f61469f613fb1565b90506146ab8282614665565b919050565b5f67ffffffffffffffff8211156146ca576146c9614638565b5b6146d38261409d565b9050602081019050919050565b828183375f83830152505050565b5f6147006146fb846146b0565b614696565b90508281526020810184848401111561471c5761471b614634565b5b6147278482856146e0565b509392505050565b5f82601f8301126147435761474261441d565b5b81356147538482602086016146ee565b91505092915050565b5f6020828403121561477157614770613fba565b5b5f82013567ffffffffffffffff81111561478e5761478d613fbe565b5b61479a8482850161472f565b91505092915050565b5f6effffffffffffffffffffffffffffff82169050919050565b6147c6816147a3565b82525050565b5f6020820190506147df5f8301846147bd565b92915050565b600781106147f1575f80fd5b50565b5f81359050614802816147e5565b92915050565b614811816147a3565b811461481b575f80fd5b50565b5f8135905061482c81614808565b92915050565b5f805f6060848603121561484957614848613fba565b5b5f614856868287016147f4565b93505060206148678682870161481e565b92505060406148788682870161481e565b9150509250925092565b5f819050919050565b61489481614882565b82525050565b5f6020820190506148ad5f83018461488b565b92915050565b6148bc81614042565b81146148c6575f80fd5b50565b5f813590506148d7816148b3565b92915050565b5f80604083850312156148f3576148f2613fba565b5b5f61490085828601614179565b9250506020614911858286016148c9565b9150509250929050565b61492481614882565b811461492e575f80fd5b50565b5f8135905061493f8161491b565b92915050565b5f806040838503121561495b5761495a613fba565b5b5f61496885828601614931565b925050602061497985828601614931565b9150509250929050565b5f67ffffffffffffffff82111561499d5761499c614638565b5b6149a68261409d565b9050602081019050919050565b5f6149c56149c084614983565b614696565b9050828152602081018484840111156149e1576149e0614634565b5b6149ec8482856146e0565b509392505050565b5f82601f830112614a0857614a0761441d565b5b8135614a188482602086016149b3565b91505092915050565b5f805f8060808587031215614a3957614a38613fba565b5b5f614a4687828801614179565b9450506020614a5787828801614179565b9350506040614a6887828801614124565b925050606085013567ffffffffffffffff811115614a8957614a88613fbe565b5b614a95878288016149f4565b91505092959194509250565b614aaa81614394565b82525050565b614ab9816147a3565b82525050565b606082015f820151614ad35f850182614aa1565b506020820151614ae66020850182614ab0565b506040820151614af96040850182614ab0565b50505050565b5f606082019050614b125f830184614abf565b92915050565b5f8060408385031215614b2e57614b2d613fba565b5b5f614b3b85828601614179565b9250506020614b4c85828601614179565b9150509250929050565b5f805f8060808587031215614b6e57614b6d613fba565b5b5f614b7b87828801614179565b9450506020614b8c878288016147f4565b9350506040614b9d8782880161481e565b9250506060614bae8782880161481e565b91505092959194509250565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680614bfe57607f821691505b602082108103614c1157614c10614bba565b5b50919050565b5f606082019050614c2a5f830186613f89565b614c376020830185613f89565b614c446040830184613f89565b949350505050565b5f8160601b9050919050565b5f614c6282614c4c565b9050919050565b5f614c7382614c58565b9050919050565b614c8b614c8682613f78565b614c69565b82525050565b5f614c9c8284614c7a565b60148201915081905092915050565b7f4d696e74207068617365206973206e6f74206c69766520666f72204f47206d695f8201527f6e74696e67000000000000000000000000000000000000000000000000000000602082015250565b5f614d0560258361407f565b9150614d1082614cab565b604082019050919050565b5f6020820190508181035f830152614d3281614cf9565b9050919050565b7f496e76616c69642070726f6f66000000000000000000000000000000000000005f82015250565b5f614d6d600d8361407f565b9150614d7882614d39565b602082019050919050565b5f6020820190508181035f830152614d9a81614d61565b9050919050565b7f4f47207061737365732063616e206f6e6c79206265206d696e74656420696e205f8201527f6f6e65207472616e73616374696f6e0000000000000000000000000000000000602082015250565b5f614dfb602f8361407f565b9150614e0682614da1565b604082019050919050565b5f6020820190508181035f830152614e2881614def565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f614e6682614105565b9150614e7183614105565b9250828201905080821115614e8957614e88614e2f565b5b92915050565b7f596f75206861766520616c7265616479206d696e74656420746865206d6178695f8201527f6d756d20616d6f756e74206f66204f4720706173736573000000000000000000602082015250565b5f614ee960378361407f565b9150614ef482614e8f565b604082019050919050565b5f6020820190508181035f830152614f1681614edd565b9050919050565b7f4d617820737570706c79206578636565640000000000000000000000000000005f82015250565b5f614f5160118361407f565b9150614f5c82614f1d565b602082019050919050565b5f6020820190508181035f830152614f7e81614f45565b9050919050565b5f614f8f82614105565b9150614f9a83614105565b9250828202614fa881614105565b91508282048414831517614fbf57614fbe614e2f565b5b5092915050565b7f496e73756666696369656e742065746865722073656e740000000000000000005f82015250565b5f614ffa60178361407f565b915061500582614fc6565b602082019050919050565b5f6020820190508181035f83015261502781614fee565b9050919050565b5f80fd5b5f81519050615040816147e5565b92915050565b5f8151905061505481614808565b92915050565b5f6060828403121561506f5761506e61502e565b5b6150796060614696565b90505f61508884828501615032565b5f83015250602061509b84828501615046565b60208301525060406150af84828501615046565b60408301525092915050565b5f606082840312156150d0576150cf613fba565b5b5f6150dd8482850161505a565b91505092915050565b5f6040820190506150f95f8301856147bd565b6151066020830184613f89565b9392505050565b5f8151905061511b816148b3565b92915050565b5f6020828403121561513657615135613fba565b5b5f6151438482850161510d565b91505092915050565b5f81905092915050565b50565b5f6151645f8361514c565b915061516f82615156565b5f82019050919050565b5f61518382615159565b9150819050919050565b7f5769746864726177206661696c656400000000000000000000000000000000005f82015250565b5f6151c1600f8361407f565b91506151cc8261518d565b602082019050919050565b5f6020820190508181035f8301526151ee816151b5565b9050919050565b7f4d696e74207068617365206973206e6f74206c69766520666f7220574c206d695f8201527f6e74696e67000000000000000000000000000000000000000000000000000000602082015250565b5f61524f60258361407f565b915061525a826151f5565b604082019050919050565b5f6020820190508181035f83015261527c81615243565b9050919050565b7f596f75206861766520616c7265616479206d696e74656420746865206d6178695f8201527f6d756d20616d6f756e74206f6620574c20706173736573000000000000000000602082015250565b5f6152dd60378361407f565b91506152e882615283565b604082019050919050565b5f6020820190508181035f83015261530a816152d1565b9050919050565b5f67ffffffffffffffff82111561532b5761532a614638565b5b602082029050602081019050919050565b5f8151905061534a81614163565b92915050565b5f61536261535d84615311565b614696565b9050808382526020820190506020840283018581111561538557615384614425565b5b835b818110156153ae578061539a888261533c565b845260208401935050602081019050615387565b5050509392505050565b5f82601f8301126153cc576153cb61441d565b5b81516153dc848260208601615350565b91505092915050565b5f602082840312156153fa576153f9613fba565b5b5f82015167ffffffffffffffff81111561541757615416613fbe565b5b615423848285016153b8565b91505092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026154887fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261544d565b615492868361544d565b95508019841693508086168417925050509392505050565b5f6154c46154bf6154ba84614105565b6141cb565b614105565b9050919050565b5f819050919050565b6154dd836154aa565b6154f16154e9826154cb565b848454615459565b825550505050565b5f90565b6155056154f9565b6155108184846154d4565b505050565b5b81811015615533576155285f826154fd565b600181019050615516565b5050565b601f821115615578576155498161542c565b6155528461543e565b81016020851015615561578190505b61557561556d8561543e565b830182615515565b50505b505050565b5f82821c905092915050565b5f6155985f198460080261557d565b1980831691505092915050565b5f6155b08383615589565b9150826002028217905092915050565b6155c982614075565b67ffffffffffffffff8111156155e2576155e1614638565b5b6155ec8254614be7565b6155f7828285615537565b5f60209050601f831160018114615628575f8415615616578287015190505b61562085826155a5565b865550615687565b601f1984166156368661542c565b5f5b8281101561565d57848901518255600182019150602085019450602081019050615638565b8683101561567a5784890151615676601f891682615589565b8355505b6001600288020188555050505b505050505050565b5f6040820190506156a25f830185613f89565b6156af60208301846143a5565b9392505050565b5f6040820190506156c95f830185613f89565b6156d660208301846147bd565b9392505050565b7f4d696e74207068617365206973206e6f74206c69766520666f72207075626c695f8201527f63206d696e74696e670000000000000000000000000000000000000000000000602082015250565b5f61573760298361407f565b9150615742826156dd565b604082019050919050565b5f6020820190508181035f8301526157648161572b565b9050919050565b7f4d6178207075626c6963206d696e7420657863656564000000000000000000005f82015250565b5f61579f60168361407f565b91506157aa8261576b565b602082019050919050565b5f6020820190508181035f8301526157cc81615793565b9050919050565b7f596f75206861766520616c7265616479206d696e74656420746865206d6178695f8201527f6d756d20616d6f756e74206f66207075626c6963207061737365730000000000602082015250565b5f61582d603b8361407f565b9150615838826157d3565b604082019050919050565b5f6020820190508181035f83015261585a81615821565b9050919050565b61586a81613fc2565b82525050565b5f6020820190506158835f830184615861565b92915050565b5f60408201905061589c5f830185613f89565b6158a96020830184613f89565b9392505050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f5f8201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b5f61590a602f8361407f565b9150615915826158b0565b604082019050919050565b5f6020820190508181035f830152615937816158fe565b9050919050565b5f81905092915050565b5f61595282614075565b61595c818561593e565b935061596c81856020860161408f565b80840191505092915050565b5f815461598481614be7565b61598e818661593e565b9450600182165f81146159a857600181146159bd576159ef565b60ff19831686528115158202860193506159ef565b6159c68561542c565b5f5b838110156159e7578154818901526001820191506020810190506159c8565b838801955050505b50505092915050565b5f615a038286615948565b9150615a0f8285615948565b9150615a1b8284615978565b9150819050949350505050565b7f4e6577206d617820737570706c79206d757374206265206c657373207468616e5f8201527f2063757272656e74206d617820737570706c7900000000000000000000000000602082015250565b5f615a8260338361407f565b9150615a8d82615a28565b604082019050919050565b5f6020820190508181035f830152615aaf81615a76565b9050919050565b5f615ac082614105565b91505f8203615ad257615ad1614e2f565b5b600182039050919050565b5f81519050919050565b5f82825260208201905092915050565b5f615b0182615add565b615b0b8185615ae7565b9350615b1b81856020860161408f565b615b248161409d565b840191505092915050565b5f608082019050615b425f830187613f89565b615b4f6020830186613f89565b615b5c60408301856142f6565b8181036060830152615b6e8184615af7565b905095945050505050565b5f81519050615b8781613fed565b92915050565b5f60208284031215615ba257615ba1613fba565b5b5f615baf84828501615b79565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffdfea26469706673582212205505e6f74d10a05e150457f4f5e2c3a472349cdd933516707730b8a5556936b464736f6c63430008190033

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

000000000000000000000000fb0513e9c5877ed22afd053855987932d8572fad00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000f53d86d3c10e914b062926f4a07e443b2a341132861483219d848ef9bda9c45305cf4c3282f346b21ec415aaef139b7e7eb44226781252146237c98bb6fe2404e337cb13a83129307c04fe9a9277f127e06970ec0000000000000000000000000000000000000000000000000000000000000036697066733a2f2f516d53544e5463375947595a506f5344376a70676a67464b6245387576485148354c5367614259736875316733382f00000000000000000000

-----Decoded View---------------
Arg [0] : initialOwner (address): 0xFB0513E9c5877Ed22afd053855987932d8572FAD
Arg [1] : initialUri (string): ipfs://QmSTNTc7YGYZPoSD7jpgjgFKbE8uvHQH5LSgaBYshu1g38/
Arg [2] : initialRecipient (address): 0xF53D86D3c10e914b062926f4A07e443b2A341132
Arg [3] : initialOgRoot (bytes32): 0x861483219d848ef9bda9c45305cf4c3282f346b21ec415aaef139b7e7eb44226
Arg [4] : initialWlRoot (bytes32): 0x781252146237c98bb6fe2404e337cb13a83129307c04fe9a9277f127e06970ec

-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 000000000000000000000000fb0513e9c5877ed22afd053855987932d8572fad
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [2] : 000000000000000000000000f53d86d3c10e914b062926f4a07e443b2a341132
Arg [3] : 861483219d848ef9bda9c45305cf4c3282f346b21ec415aaef139b7e7eb44226
Arg [4] : 781252146237c98bb6fe2404e337cb13a83129307c04fe9a9277f127e06970ec
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000036
Arg [6] : 697066733a2f2f516d53544e5463375947595a506f5344376a70676a67464b62
Arg [7] : 45387576485148354c5367614259736875316733382f00000000000000000000


Deployed Bytecode Sourcemap

99105:5339:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83180:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93588:203;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21530:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;28770:227;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;28487:124;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;87706:137;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99454:44;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99655:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;16732:573;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91490:387;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83291:99;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33042:3523;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;100297:852;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;89835:357;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99339:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103731:94;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;104272:169;;;;;;;;;;;;;:::i;:::-;;101157:766;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;36661:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;102914:111;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88722:358;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104168:96;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83397:66;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99193:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;85446:727;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;22932:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99376:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83837:464;;;;;;;;;;;;;:::i;:::-;;18456:242;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97199:103;;;;;;;;;;;;;:::i;:::-;;99535:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96524:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99507:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21706:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90364:378;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99233:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101931:708;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;29337:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;86773:818;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103833:113;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;37452:416;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;88060:455;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99404:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103266:431;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;89290:379;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99156:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99273:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99306;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;100101:188;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;29728:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97457:220;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103954:202;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;84504:749;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83180:104;83241:42;83180:104;:::o;93588:203::-;93673:4;93712:31;93697:46;;;:11;:46;;;;:86;;;;93747:36;93771:11;93747:23;:36::i;:::-;93697:86;93690:93;;93588:203;;;:::o;21530:100::-;21584:13;21617:5;21610:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21530:100;:::o;28770:227::-;28846:7;28871:16;28879:7;28871;:16::i;:::-;28866:73;;28889:50;28897:41;;;28889:7;:50::i;:::-;28866:73;28959:15;:24;28975:7;28959:24;;;;;;;;;;;:30;;;;;;;;;;;;28952:37;;28770:227;;;:::o;28487:124::-;28576:27;28585:2;28589:7;28598:4;28576:8;:27::i;:::-;28487:124;;:::o;87706:137::-;87768:30;87818:17;;;;;;;;;;;87811:24;;87706:137;:::o;99454:44::-;;;;;;;;;;;;;;;;;;;;;;:::o;99655:26::-;;;;;;;;;;;;;:::o;16732:573::-;16793:14;17191:15;:13;:15::i;:::-;17176:12;;17160:13;;:28;:46;17151:55;;17246:17;17225;:15;:17::i;:::-;:38;17221:65;;17275:11;;17265:21;;;;17221:65;16732:573;:::o;91490:387::-;91589:4;91648:1;91610:40;;91618:17;;;;;;;;;;;91610:40;;;91606:242;;91671:17;;;;;;;;;;;:47;;;91719:6;91727:4;91733:2;91671:65;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91667:170;;91816:5;91809:12;;;;91667:170;91763:4;91756:11;;;;91606:242;91865:4;91858:11;;91490:387;;;;;;:::o;83291:99::-;83364:26;83291:99;:::o;33042:3523::-;33184:27;33214;33233:7;33214:18;:27::i;:::-;33184:57;;12674:14;33385:4;33369:22;;:41;33346:66;;33470:4;33429:45;;33445:19;33429:45;;;33425:95;;33476:44;33484:35;;;33476:7;:44::i;:::-;33425:95;33534:27;33563:23;33590:35;33617:7;33590:26;:35::i;:::-;33533:92;;;;33725:68;33750:15;33767:4;33773:19;:17;:19::i;:::-;33725:24;:68::i;:::-;33720:189;;33813:43;33830:4;33836:19;:17;:19::i;:::-;33813:16;:43::i;:::-;33808:101;;33858:51;33866:42;;;33858:7;:51::i;:::-;33808:101;33720:189;33922:43;33944:4;33950:2;33954:7;33963:1;33922:21;:43::i;:::-;34058:15;34055:160;;;34198:1;34177:19;34170:30;34055:160;34595:18;:24;34614:4;34595:24;;;;;;;;;;;;;;;;34593:26;;;;;;;;;;;;34664:18;:22;34683:2;34664:22;;;;;;;;;;;;;;;;34662:24;;;;;;;;;;;34986:146;35023:2;35072:45;35087:4;35093:2;35097:19;35072:14;:45::i;:::-;12272:8;35044:73;34986:18;:146::i;:::-;34957:17;:26;34975:7;34957:26;;;;;;;;;;;:175;;;;35303:1;12272:8;35252:19;:47;:52;35248:627;;35325:19;35357:1;35347:7;:11;35325:33;;35514:1;35480:17;:30;35498:11;35480:30;;;;;;;;;;;;:35;35476:384;;35618:13;;35603:11;:28;35599:242;;35798:19;35765:17;:30;35783:11;35765:30;;;;;;;;;;;:52;;;;35599:242;35476:384;35306:569;35248:627;35988:16;12674:14;36023:2;36007:20;;:39;35988:58;;36387:7;36351:8;36317:4;36259:25;36204:1;36147;36124:299;36460:1;36448:8;:13;36444:58;;36463:39;36471:30;;;36463:7;:39::i;:::-;36444:58;36515:42;36536:4;36542:2;36546:7;36555:1;36515:20;:42::i;:::-;33173:3392;;;;33042:3523;;;:::o;100297:852::-;100395:18;100416:21;100424:12;:10;:12::i;:::-;100416:7;:21::i;:::-;100395:42;;;;100448:12;100490;:10;:12::i;:::-;100473:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;100463:41;;;;;;100448:56;;100538:20;100525:33;;;;;;;;:::i;:::-;;:9;;;;;;;;;;;:33;;;;;;;;:::i;:::-;;;100517:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;100619:39;100638:5;;100619:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;100645:6;;100653:4;100619:18;:39::i;:::-;100611:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;100709:1;100695:10;:15;100687:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;100806:9;;;;;;;;;;;100781:34;;100794:8;100781:10;:21;;;;:::i;:::-;:34;;100773:102;;;;;;;;;;;;:::i;:::-;;;;;;;;;100922:12;;100910:8;100894:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:40;;100886:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;100996:8;100988:5;;:16;;;;:::i;:::-;100975:9;:29;;100967:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;101045:52;101053:12;:10;:12::i;:::-;101087:8;101074:10;:21;;;;:::i;:::-;101045:7;:52::i;:::-;101108:33;101118:12;:10;:12::i;:::-;101132:8;101108:9;:33::i;:::-;100374:775;;100297:852;;;:::o;89835:357::-;89914:4;89973:1;89935:40;;89943:17;;;;;;;;;;;89935:40;;;89931:229;;89999:17;;;;;;;;;;;:39;;;90057:17;;;;;;;;;;;:45;;;90111:4;90057:60;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:80;;;90139:8;89999:149;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;89992:156;;;;89931:229;90179:5;90172:12;;89835:357;;;;:::o;99339:30::-;;;;;;;;;;;;;:::o;103731:94::-;96410:13;:11;:13::i;:::-;103812:5:::1;103800:9;;:17;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;103731:94:::0;:::o;104272:169::-;96410:13;:11;:13::i;:::-;104323:12:::1;104341:7;:5;:7::i;:::-;:12;;104361:21;104341:46;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104322:65;;;104406:7;104398:35;;;;;;;;;;;;:::i;:::-;;;;;;;;;104311:130;104272:169::o:0;101157:766::-;101255:18;101276:21;101284:12;:10;:12::i;:::-;101276:7;:21::i;:::-;101255:42;;;;101308:12;101350;:10;:12::i;:::-;101333:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;101323:41;;;;;;101308:56;;101398:20;101385:33;;;;;;;;:::i;:::-;;:9;;;;;;;;;;;:33;;;;;;;;:::i;:::-;;;101377:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;101479:39;101498:5;;101479:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101505:6;;101513:4;101479:18;:39::i;:::-;101471:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;101580:9;;;;;;;;;;;101555:34;;101568:8;101555:10;:21;;;;:::i;:::-;:34;;101547:102;;;;;;;;;;;;:::i;:::-;;;;;;;;;101696:12;;101684:8;101668:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:40;;101660:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;101770:8;101762:5;;:16;;;;:::i;:::-;101749:9;:29;;101741:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;101819:52;101827:12;:10;:12::i;:::-;101861:8;101848:10;:21;;;;:::i;:::-;101819:7;:52::i;:::-;101882:33;101892:12;:10;:12::i;:::-;101906:8;101882:9;:33::i;:::-;101234:689;;101157:766;;;:::o;36661:193::-;36807:39;36824:4;36830:2;36834:7;36807:39;;;;;;;;;;;;:16;:39::i;:::-;36661:193;;;:::o;102914:111::-;102975:7;103002:15;103010:6;103002:7;:15::i;:::-;102995:22;;;;102914:111;;;:::o;88722:358::-;88787:16;88858:1;88820:40;;88828:17;;;;;;;;;;;88820:40;;;88816:221;;88884:17;;;;;;;;;;;:41;;;88944:17;;;;;;;;;;;:45;;;88998:4;88944:60;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:80;;;88884:141;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;88877:148;;;;88816:221;89070:1;89056:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89049:23;;88722:358;;:::o;104168:96::-;96410:13;:11;:13::i;:::-;104249:7:::1;104239;:17;;;;;;:::i;:::-;;104168:96:::0;:::o;83397:66::-;83461:1;83397:66;:::o;99193:33::-;;;;:::o;85446:727::-;85635:31;:29;:31::i;:::-;85679:40;85722:22;:20;:22::i;:::-;85679:65;;85789:1;85759:32;;85767:9;85759:32;;;85755:117;;85815:45;;;;;;;;;;;;;;85755:117;85884:9;:46;;;85939:4;85946:5;85884:68;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85963:9;:42;;;86014:4;86021:19;85963:78;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86052:9;:59;;;86120:4;86127:37;86052:113;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85624:549;85446:727;;;:::o;22932:152::-;23004:7;23047:27;23066:7;23047:18;:27::i;:::-;23024:52;;22932:152;;;:::o;99376:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;83837:464::-;83901:31;:29;:31::i;:::-;83943:48;83241:42;83943:20;:48::i;:::-;83241:42;84002:95;;;84106:4;83364:26;84002:143;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83241:42;84156:91;;;84256:4;83461:1;84156:137;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83837:464::o;18456:242::-;18528:7;18569:1;18552:19;;:5;:19;;;18548:69;;18573:44;18581:35;;;18573:7;:44::i;:::-;18548:69;11216:13;18635:18;:25;18654:5;18635:25;;;;;;;;;;;;;;;;:55;18628:62;;18456:242;;;:::o;97199:103::-;96410:13;:11;:13::i;:::-;97264:30:::1;97291:1;97264:18;:30::i;:::-;97199:103::o:0;99535:21::-;;;;:::o;96524:87::-;96570:7;96597:6;;;;;;;;;;;96590:13;;96524:87;:::o;99507:21::-;;;;:::o;21706:104::-;21762:13;21795:7;21788:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21706:104;:::o;90364:378::-;90449:4;90508:1;90470:40;;90478:17;;;;;;;;;;;90470:40;;;90466:244;;90534:17;;;;;;;;;;;:45;;;90598:17;;;;;;;;;;;:45;;;90652:4;90598:60;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:89;;;90689:8;90534:164;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90527:171;;;;90466:244;90729:5;90722:12;;90364:378;;;;:::o;99233:33::-;;;;:::o;101931:708::-;102001:18;102022:21;102030:12;:10;:12::i;:::-;102022:7;:21::i;:::-;102001:42;;;;102077:21;102064:34;;;;;;;;:::i;:::-;;:9;;;;;;;;;;;:34;;;;;;;;:::i;:::-;;;102056:88;;;;;;;;;;;;:::i;:::-;;;;;;;;;102175:13;;;;;;;;;;;102163:25;;:8;:25;;102155:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;102235:12;:24;102248:10;102235:24;;;;;;;;;;;;;;;;;;;;;;;;;102234:25;102226:97;;;;;;;;;;;;:::i;:::-;;;;;;;;;102370:12;;102358:8;102342:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:40;;102334:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;102444:8;102436:5;;:16;;;;:::i;:::-;102423:9;:29;;102415:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;102520:4;102493:12;:24;102506:10;102493:24;;;;;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;102535:52;102543:12;:10;:12::i;:::-;102577:8;102564:10;:21;;;;:::i;:::-;102535:7;:52::i;:::-;102598:33;102608:12;:10;:12::i;:::-;102622:8;102598:9;:33::i;:::-;101980:659;101931:708;:::o;29337:234::-;29484:8;29432:18;:39;29451:19;:17;:19::i;:::-;29432:39;;;;;;;;;;;;;;;:49;29472:8;29432:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;29544:8;29508:55;;29523:19;:17;:19::i;:::-;29508:55;;;29554:8;29508:55;;;;;;:::i;:::-;;;;;;;;29337:234;;:::o;86773:818::-;86849:31;:29;:31::i;:::-;86893:29;86979:1;86946:18;:30;;;:34;86943:304;;;87009:18;87001:45;;;87047:48;87001:95;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;86997:239;;;87194:17;87167:44;;87115:112;86997:239;86943:304;87292:1;87262:32;;:18;:32;;;;:61;;;;;87299:24;87298:25;87262:61;87259:152;;;87347:52;;;;;;;;;;;;;;87259:152;87428:72;87461:17;;;;;;;;;;;87481:18;87428:72;;;;;;;:::i;:::-;;;;;;;;87564:18;87513:17;;:70;;;;;;;;;;;;;;;;;;86838:753;86773:818;:::o;103833:113::-;96410:13;:11;:13::i;:::-;103914:2:::1;103905:6;:11;;;;103936:2;103927:6;:11;;;;103833:113:::0;;:::o;37452:416::-;37627:31;37640:4;37646:2;37650:7;37627:12;:31::i;:::-;37691:1;37673:2;:14;;;:19;37669:192;;37712:56;37743:4;37749:2;37753:7;37762:5;37712:30;:56::i;:::-;37707:154;;37789:56;37797:47;;;37789:7;:56::i;:::-;37707:154;37669:192;37452:416;;;;:::o;88060:455::-;88119:31;;:::i;:::-;88205:1;88167:40;;88175:17;;;;;;;;;;;88167:40;;;88163:140;;88231:17;;;;;;;;;;;:45;;;88285:4;88231:60;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;88224:67;;;;88163:140;88322:185;;;;;;;;88385:27;88322:185;;;;;;;;:::i;:::-;;;;;;88448:1;88322:185;;;;;;88494:1;88322:185;;;;;88315:192;;88060:455;;:::o;99404:37::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;103266:431::-;103364:13;103403:16;103411:7;103403;:16::i;:::-;103395:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;103495:28;103526:10;:8;:10::i;:::-;103495:41;;103585:1;103560:14;103554:28;:32;:133;;;;;;;;;;;;;;;;;103622:14;103638:18;103648:7;103638:9;:18::i;:::-;103658:13;103605:67;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;103554:133;103547:140;;;103266:431;;;:::o;89290:379::-;89361:16;89432:1;89394:40;;89402:17;;;;;;;;;;;89394:40;;;89390:236;;89458:17;;;;;;;;;;;:47;;;89524:17;;;;;;;;;;;:45;;;89578:4;89524:60;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:89;;;89458:156;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;89451:163;;;;89390:236;89659:1;89645:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89638:23;;89290:379;;:::o;99156:30::-;;;;:::o;99273:26::-;;;;;;;;;;;;;:::o;99306:::-;;;;;;;;;;;;;:::o;100101:188::-;96410:13;:11;:13::i;:::-;100216:9:::1;;100204:8;100188:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:37;;100180:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;100258:23;100268:2;100272:8;100258:9;:23::i;:::-;100101:188:::0;;:::o;29728:164::-;29825:4;29849:18;:25;29868:5;29849:25;;;;;;;;;;;;;;;:35;29875:8;29849:35;;;;;;;;;;;;;;;;;;;;;;;;;29842:42;;29728:164;;;;:::o;97457:220::-;96410:13;:11;:13::i;:::-;97562:1:::1;97542:22;;:8;:22;;::::0;97538:93:::1;;97616:1;97588:31;;;;;;;;;;;:::i;:::-;;;;;;;;97538:93;97641:28;97660:8;97641:18;:28::i;:::-;97457:220:::0;:::o;103954:202::-;96410:13;:11;:13::i;:::-;104048:9:::1;;104033:12;:24;104025:88;;;;;;;;;;;;:::i;:::-;;;;;;;;;104136:12;104124:9;:24;;;;103954:202:::0;:::o;84504:749::-;84734:31;:29;:31::i;:::-;84778;84799:9;84778:20;:31::i;:::-;84853:9;84822:92;;;84923:4;84930:5;84822:114;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84980:9;84949:88;;;85046:4;85053:19;84949:124;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85117:9;85086:105;;;85200:4;85207:37;85086:159;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84504:749;;;;:::o;20628:639::-;20713:4;21052:10;21037:25;;:11;:25;;;;:102;;;;21129:10;21114:25;;:11;:25;;;;21037:102;:179;;;;21206:10;21191:25;;:11;:25;;;;21037:179;21017:199;;20628:639;;;:::o;30150:475::-;30215:11;30262:7;30243:15;:13;:15::i;:::-;:26;30239:379;;30300:17;:15;:17::i;:::-;30290:7;:27;30286:90;;;30326:50;30349:17;:26;30367:7;30349:26;;;;;;;;;;;;30326:22;:50::i;:::-;30319:57;;;;30286:90;30407:13;;30397:7;:23;30393:214;;;30441:14;30474:60;30522:1;30491:17;:26;30509:7;30491:26;;;;;;;;;;;;30482:35;;;30481:42;30474:60;;30525:9;;;;:::i;:::-;;;30474:60;;;30590:1;11992:8;30562:6;:24;:29;30553:38;;30422:185;30393:214;30239:379;30150:475;;;;:::o;60659:165::-;60760:13;60754:4;60747:27;60801:4;60795;60788:18;52074:474;52203:13;52219:16;52227:7;52219;:16::i;:::-;52203:32;;52252:13;:45;;;;;52292:5;52269:28;;:19;:17;:19::i;:::-;:28;;;;52252:45;52248:201;;;52317:44;52334:5;52341:19;:17;:19::i;:::-;52317:16;:44::i;:::-;52312:137;;52382:51;52390:42;;;52382:7;:51::i;:::-;52312:137;52248:201;52494:2;52461:15;:24;52477:7;52461:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;52532:7;52528:2;52512:28;;52521:5;52512:28;;;;;;;;;;;;52192:356;52074:474;;;:::o;103153:101::-;103218:7;103245:1;103238:8;;103153:101;:::o;16230:110::-;16288:7;16315:17;16308:24;;16230:110;:::o;24417:2213::-;24484:14;24534:7;24515:15;:13;:15::i;:::-;:26;24511:2054;;24567:17;:26;24585:7;24567:26;;;;;;;;;;;;24558:35;;24624:17;:15;:17::i;:::-;24614:7;:27;24610:183;;;24666:30;24689:6;24666:22;:30::i;:::-;24698:13;24662:49;24730:47;24738:38;;;24730:7;:47::i;:::-;24610:183;24904:1;24894:6;:11;24890:1292;;24941:13;;24930:7;:24;24926:77;;24956:47;24964:38;;;24956:7;:47::i;:::-;24926:77;25560:607;25638:17;:28;25656:9;;;;;;;25638:28;;;;;;;;;;;;25629:37;;25726:1;25716:6;:11;25712:25;25729:8;25712:25;25792:1;11992:8;25764:6;:24;:29;25760:48;25795:13;25760:48;26100:47;26108:38;;;26100:7;:47::i;:::-;25560:607;;;24890:1292;26537:1;11992:8;26509:6;:24;:29;26505:48;26540:13;26505:48;24511:2054;26575:47;26583:38;;;26575:7;:47::i;:::-;24417:2213;;;;:::o;31937:485::-;32039:27;32068:23;32109:38;32150:15;:24;32166:7;32150:24;;;;;;;;;;;32109:65;;32327:18;32304:41;;32384:19;32378:26;32359:45;;32289:126;31937:485;;;:::o;94731:116::-;94800:7;94827:12;:10;:12::i;:::-;94820:19;;94731:116;:::o;31165:659::-;31314:11;31479:16;31472:5;31468:28;31459:37;;31639:16;31628:9;31624:32;31611:45;;31789:15;31778:9;31775:30;31767:5;31756:9;31753:20;31750:56;31740:66;;31165:659;;;;;:::o;93900:359::-;94082:9;94077:175;94101:8;94097:1;:12;94077:175;;;94127:51;94151:4;94157:2;94176:1;94161:12;:16;;;;:::i;:::-;94127:23;:51::i;:::-;94222:3;;;;;94077:175;;;;93900:359;;;;:::o;57949:311::-;58084:7;58104:16;12396:3;58130:19;:41;;58104:68;;12396:3;58198:31;58209:4;58215:2;58219:9;58198:10;:31::i;:::-;58190:40;;:62;;58183:69;;;57949:311;;;;;:::o;27178:450::-;27258:14;27426:16;27419:5;27415:28;27406:37;;27603:5;27589:11;27564:23;27560:41;27557:52;27550:5;27547:63;27537:73;;27178:450;;;;:::o;94366:357::-;94547:9;94542:174;94566:8;94562:1;:12;94542:174;;;94592:50;94615:4;94621:2;94640:1;94625:12;:16;;;;:::i;:::-;94592:22;:50::i;:::-;94686:3;;;;;94542:174;;;;94366:357;;;;:::o;77619:98::-;77672:7;77699:10;77692:17;;77619:98;:::o;19352:137::-;19407:6;11590:3;19440:18;:25;19459:5;19440:25;;;;;;;;;;;;;;;;:40;;19426:55;;19352:137;;;:::o;68226:156::-;68317:4;68370;68341:25;68354:5;68361:4;68341:12;:25::i;:::-;:33;68334:40;;68226:156;;;;;:::o;19677:404::-;19749:14;19766:18;:25;19785:5;19766:25;;;;;;;;;;;;;;;;19749:42;;19802:17;19932:3;19919:16;;11590:3;20003:9;:24;;11735:14;19966:6;:32;19965:63;19956:72;;20067:6;20039:18;:25;20058:5;20039:25;;;;;;;;;;;;;;;:34;;;;19738:343;;19677:404;;:::o;47268:112::-;47345:27;47355:2;47359:8;47345:27;;;;;;;;;;;;:9;:27::i;:::-;47268:112;;:::o;96689:166::-;96760:12;:10;:12::i;:::-;96749:23;;:7;:5;:7::i;:::-;:23;;;96745:103;;96823:12;:10;:12::i;:::-;96796:40;;;;;;;;;;;:::i;:::-;;;;;;;;96745:103;96689:166::o;102816:65::-;:::o;97837:191::-;97911:16;97930:6;;;;;;;;;;;97911:25;;97956:8;97947:6;;:17;;;;;;;;;;;;;;;;;;98011:8;97980:40;;98001:8;97980:40;;;;;;;;;;;;97900:128;97837:191;:::o;39952:691::-;40115:4;40161:2;40136:45;;;40182:19;:17;:19::i;:::-;40203:4;40209:7;40218:5;40136:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;40132:504;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40436:1;40419:6;:13;:18;40415:115;;40458:56;40466:47;;;40458:7;:56::i;:::-;40415:115;40602:6;40596:13;40587:6;40583:2;40579:15;40572:38;40132:504;40305:54;;;40295:64;;;:6;:64;;;;40288:71;;;39952:691;;;;;;:::o;103037:108::-;103097:13;103130:7;103123:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;103037:108;:::o;58847:1745::-;58912:17;59346:4;59339;59333:11;59329:22;59438:1;59432:4;59425:15;59513:4;59510:1;59506:12;59499:19;;59595:1;59590:3;59583:14;59699:3;59938:5;59920:428;59946:1;59920:428;;;59986:1;59981:3;59977:11;59970:18;;60157:2;60151:4;60147:13;60143:2;60139:22;60134:3;60126:36;60251:2;60245:4;60241:13;60233:21;;60318:4;59920:428;60308:25;59920:428;59924:21;60387:3;60382;60378:13;60502:4;60497:3;60493:14;60486:21;;60567:6;60562:3;60555:19;58951:1634;;;58847:1745;;;:::o;30721:335::-;30791:11;31021:15;31013:6;31009:28;30990:16;30982:6;30978:29;30975:63;30965:73;;30721:335;;;:::o;78657:623::-;78761:20;78800:1;78784:18;;:4;:18;;;78761:41;;78813:18;78848:1;78834:16;;:2;:16;;;78813:37;;78866:15;:32;;;;;78885:13;78866:32;78863:410;;;78922:28;;;;;;;;;;;;;;78863:410;78971:15;78968:305;;;79003:54;79020:12;:10;:12::i;:::-;79034:2;79038:7;79047:9;79003:16;:54::i;:::-;78968:305;;;79078:13;79075:198;;;79108:56;79125:12;:10;:12::i;:::-;79139:4;79145:7;79154:9;79108:16;:56::i;:::-;79075:198;;;79197:64;79218:12;:10;:12::i;:::-;79232:4;79238:2;79242:7;79251:9;79197:20;:64::i;:::-;79075:198;78968:305;78750:530;;78657:623;;;:::o;57650:147::-;57787:6;57650:147;;;;;:::o;79413:625::-;79516:20;79555:1;79539:18;;:4;:18;;;79516:41;;79568:18;79603:1;79589:16;;:2;:16;;;79568:37;;79621:15;:32;;;;;79640:13;79621:32;79618:413;;;79677:28;;;;;;;;;;;;;;79618:413;79726:15;79723:308;;;79758:55;79776:12;:10;:12::i;:::-;79790:2;79794:7;79803:9;79758:17;:55::i;:::-;79723:308;;;79834:13;79831:200;;;79864:57;79882:12;:10;:12::i;:::-;79896:4;79902:7;79911:9;79864:17;:57::i;:::-;79831:200;;;79954:65;79976:12;:10;:12::i;:::-;79990:4;79996:2;80000:7;80009:9;79954:21;:65::i;:::-;79831:200;79723:308;79505:533;;79413:625;;;:::o;68945:296::-;69028:7;69048:20;69071:4;69048:27;;69091:9;69086:118;69110:5;:12;69106:1;:16;69086:118;;;69159:33;69169:12;69183:5;69189:1;69183:8;;;;;;;;:::i;:::-;;;;;;;;69159:9;:33::i;:::-;69144:48;;69124:3;;;;;;;69086:118;;;;69221:12;69214:19;;;68945:296;;;;:::o;46397:787::-;46528:19;46534:2;46538:8;46528:5;:19::i;:::-;46607:1;46589:2;:14;;;:19;46585:581;;46629:11;46643:13;;46629:27;;46675:13;46697:8;46691:3;:14;46675:30;;46724:242;46755:62;46794:1;46798:2;46802:7;;;;;;46811:5;46755:30;:62::i;:::-;46750:176;;46846:56;46854:47;;;46846:7;:56::i;:::-;46750:176;46961:3;46953:5;:11;46724:242;;47137:3;47120:13;;:20;47116:34;;47142:8;;;47116:34;46610:556;;46585:581;46397:787;;;:::o;80110:105::-;;;;;:::o;80464:107::-;;;;;:::o;92580:344::-;92821:1;92783:40;;92791:17;;;;;;;;;;;92783:40;;;92779:138;;92840:17;;;;;;;;;;;:47;;;92888:6;92896:4;92902:2;92840:65;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92779:138;92580:344;;;;;:::o;80286:106::-;;;;;:::o;80642:108::-;;;;;:::o;81024:124::-;;;;;;:::o;76375:149::-;76438:7;76469:1;76465;:5;:51;;76496:20;76511:1;76514;76496:14;:20::i;:::-;76465:51;;;76473:20;76488:1;76491;76473:14;:20::i;:::-;76465:51;76458:58;;76375:149;;;;:::o;41105:2399::-;41178:20;41201:13;;41178:36;;41241:1;41229:8;:13;41225:53;;41244:34;41252:25;;;41244:7;:34::i;:::-;41225:53;41291:61;41321:1;41325:2;41329:12;41343:8;41291:21;:61::i;:::-;41825:139;41862:2;41916:33;41939:1;41943:2;41947:1;41916:14;:33::i;:::-;41883:30;41904:8;41883:20;:30::i;:::-;:66;41825:18;:139::i;:::-;41791:17;:31;41809:12;41791:31;;;;;;;;;;;:173;;;;42251:1;11354:2;42221:1;:26;;42220:32;42208:8;:45;42182:18;:22;42201:2;42182:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;42364:16;12674:14;42399:2;42383:20;;:39;42364:58;;42455:1;42443:8;:13;42439:54;;42458:35;42466:26;;;42458:7;:35::i;:::-;42439:54;42510:11;42539:8;42524:12;:23;42510:37;;42562:15;42580:12;42562:30;;42623:17;:15;:17::i;:::-;42619:1;42613:3;:7;:27;42609:77;;;42642:44;42650:35;;;42642:7;:44::i;:::-;42609:77;42703:676;43122:7;43078:8;43033:1;42967:25;42904:1;42839;42808:358;43374:3;43361:9;;;;;;:16;42703:676;;43411:3;43395:13;:19;;;;41540:1886;;;43436:60;43465:1;43469:2;43473:12;43487:8;43436:20;:60::i;:::-;41167:2337;41105:2399;;:::o;76649:268::-;76717:13;76824:1;76818:4;76811:15;76853:1;76847:4;76840:15;76894:4;76888;76878:21;76869:30;;76649:268;;;;:::o;27730:324::-;27800:14;28033:1;28023:8;28020:15;27994:24;27990:46;27980:56;;27730:324;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;:::o;7:126:1:-;44:7;84:42;77:5;73:54;62:65;;7:126;;;:::o;139:96::-;176:7;205:24;223:5;205:24;:::i;:::-;194:35;;139:96;;;:::o;241:118::-;328:24;346:5;328:24;:::i;:::-;323:3;316:37;241:118;;:::o;365:222::-;458:4;496:2;485:9;481:18;473:26;;509:71;577:1;566:9;562:17;553:6;509:71;:::i;:::-;365:222;;;;:::o;593:75::-;626:6;659:2;653:9;643:19;;593:75;:::o;674:117::-;783:1;780;773:12;797:117;906:1;903;896:12;920:149;956:7;996:66;989:5;985:78;974:89;;920:149;;;:::o;1075:120::-;1147:23;1164:5;1147:23;:::i;:::-;1140:5;1137:34;1127:62;;1185:1;1182;1175:12;1127:62;1075:120;:::o;1201:137::-;1246:5;1284:6;1271:20;1262:29;;1300:32;1326:5;1300:32;:::i;:::-;1201:137;;;;:::o;1344:327::-;1402:6;1451:2;1439:9;1430:7;1426:23;1422:32;1419:119;;;1457:79;;:::i;:::-;1419:119;1577:1;1602:52;1646:7;1637:6;1626:9;1622:22;1602:52;:::i;:::-;1592:62;;1548:116;1344:327;;;;:::o;1677:90::-;1711:7;1754:5;1747:13;1740:21;1729:32;;1677:90;;;:::o;1773:109::-;1854:21;1869:5;1854:21;:::i;:::-;1849:3;1842:34;1773:109;;:::o;1888:210::-;1975:4;2013:2;2002:9;1998:18;1990:26;;2026:65;2088:1;2077:9;2073:17;2064:6;2026:65;:::i;:::-;1888:210;;;;:::o;2104:99::-;2156:6;2190:5;2184:12;2174:22;;2104:99;;;:::o;2209:169::-;2293:11;2327:6;2322:3;2315:19;2367:4;2362:3;2358:14;2343:29;;2209:169;;;;:::o;2384:139::-;2473:6;2468:3;2463;2457:23;2514:1;2505:6;2500:3;2496:16;2489:27;2384:139;;;:::o;2529:102::-;2570:6;2621:2;2617:7;2612:2;2605:5;2601:14;2597:28;2587:38;;2529:102;;;:::o;2637:377::-;2725:3;2753:39;2786:5;2753:39;:::i;:::-;2808:71;2872:6;2867:3;2808:71;:::i;:::-;2801:78;;2888:65;2946:6;2941:3;2934:4;2927:5;2923:16;2888:65;:::i;:::-;2978:29;3000:6;2978:29;:::i;:::-;2973:3;2969:39;2962:46;;2729:285;2637:377;;;;:::o;3020:313::-;3133:4;3171:2;3160:9;3156:18;3148:26;;3220:9;3214:4;3210:20;3206:1;3195:9;3191:17;3184:47;3248:78;3321:4;3312:6;3248:78;:::i;:::-;3240:86;;3020:313;;;;:::o;3339:77::-;3376:7;3405:5;3394:16;;3339:77;;;:::o;3422:122::-;3495:24;3513:5;3495:24;:::i;:::-;3488:5;3485:35;3475:63;;3534:1;3531;3524:12;3475:63;3422:122;:::o;3550:139::-;3596:5;3634:6;3621:20;3612:29;;3650:33;3677:5;3650:33;:::i;:::-;3550:139;;;;:::o;3695:329::-;3754:6;3803:2;3791:9;3782:7;3778:23;3774:32;3771:119;;;3809:79;;:::i;:::-;3771:119;3929:1;3954:53;3999:7;3990:6;3979:9;3975:22;3954:53;:::i;:::-;3944:63;;3900:117;3695:329;;;;:::o;4030:122::-;4103:24;4121:5;4103:24;:::i;:::-;4096:5;4093:35;4083:63;;4142:1;4139;4132:12;4083:63;4030:122;:::o;4158:139::-;4204:5;4242:6;4229:20;4220:29;;4258:33;4285:5;4258:33;:::i;:::-;4158:139;;;;:::o;4303:474::-;4371:6;4379;4428:2;4416:9;4407:7;4403:23;4399:32;4396:119;;;4434:79;;:::i;:::-;4396:119;4554:1;4579:53;4624:7;4615:6;4604:9;4600:22;4579:53;:::i;:::-;4569:63;;4525:117;4681:2;4707:53;4752:7;4743:6;4732:9;4728:22;4707:53;:::i;:::-;4697:63;;4652:118;4303:474;;;;;:::o;4783:60::-;4811:3;4832:5;4825:12;;4783:60;;;:::o;4849:142::-;4899:9;4932:53;4950:34;4959:24;4977:5;4959:24;:::i;:::-;4950:34;:::i;:::-;4932:53;:::i;:::-;4919:66;;4849:142;;;:::o;4997:126::-;5047:9;5080:37;5111:5;5080:37;:::i;:::-;5067:50;;4997:126;;;:::o;5129:165::-;5218:9;5251:37;5282:5;5251:37;:::i;:::-;5238:50;;5129:165;;;:::o;5300:209::-;5426:76;5496:5;5426:76;:::i;:::-;5421:3;5414:89;5300:209;;:::o;5515:300::-;5647:4;5685:2;5674:9;5670:18;5662:26;;5698:110;5805:1;5794:9;5790:17;5781:6;5698:110;:::i;:::-;5515:300;;;;:::o;5821:329::-;5880:6;5929:2;5917:9;5908:7;5904:23;5900:32;5897:119;;;5935:79;;:::i;:::-;5897:119;6055:1;6080:53;6125:7;6116:6;6105:9;6101:22;6080:53;:::i;:::-;6070:63;;6026:117;5821:329;;;;:::o;6156:180::-;6204:77;6201:1;6194:88;6301:4;6298:1;6291:15;6325:4;6322:1;6315:15;6342:119;6429:1;6422:5;6419:12;6409:46;;6435:18;;:::i;:::-;6409:46;6342:119;:::o;6467:139::-;6518:7;6547:5;6536:16;;6553:47;6594:5;6553:47;:::i;:::-;6467:139;;;:::o;6612:::-;6674:9;6707:38;6739:5;6707:38;:::i;:::-;6694:51;;6612:139;;;:::o;6757:155::-;6856:49;6899:5;6856:49;:::i;:::-;6851:3;6844:62;6757:155;;:::o;6918:246::-;7023:4;7061:2;7050:9;7046:18;7038:26;;7074:83;7154:1;7143:9;7139:17;7130:6;7074:83;:::i;:::-;6918:246;;;;:::o;7170:118::-;7257:24;7275:5;7257:24;:::i;:::-;7252:3;7245:37;7170:118;;:::o;7294:222::-;7387:4;7425:2;7414:9;7410:18;7402:26;;7438:71;7506:1;7495:9;7491:17;7482:6;7438:71;:::i;:::-;7294:222;;;;:::o;7522:619::-;7599:6;7607;7615;7664:2;7652:9;7643:7;7639:23;7635:32;7632:119;;;7670:79;;:::i;:::-;7632:119;7790:1;7815:53;7860:7;7851:6;7840:9;7836:22;7815:53;:::i;:::-;7805:63;;7761:117;7917:2;7943:53;7988:7;7979:6;7968:9;7964:22;7943:53;:::i;:::-;7933:63;;7888:118;8045:2;8071:53;8116:7;8107:6;8096:9;8092:22;8071:53;:::i;:::-;8061:63;;8016:118;7522:619;;;;;:::o;8147:132::-;8247:1;8240:5;8237:12;8227:46;;8253:18;;:::i;:::-;8227:46;8147:132;:::o;8285:165::-;8349:7;8378:5;8367:16;;8384:60;8438:5;8384:60;:::i;:::-;8285:165;;;:::o;8456:::-;8531:9;8564:51;8609:5;8564:51;:::i;:::-;8551:64;;8456:165;;;:::o;8627:181::-;8739:62;8795:5;8739:62;:::i;:::-;8734:3;8727:75;8627:181;;:::o;8814:272::-;8932:4;8970:2;8959:9;8955:18;8947:26;;8983:96;9076:1;9065:9;9061:17;9052:6;8983:96;:::i;:::-;8814:272;;;;:::o;9092:619::-;9169:6;9177;9185;9234:2;9222:9;9213:7;9209:23;9205:32;9202:119;;;9240:79;;:::i;:::-;9202:119;9360:1;9385:53;9430:7;9421:6;9410:9;9406:22;9385:53;:::i;:::-;9375:63;;9331:117;9487:2;9513:53;9558:7;9549:6;9538:9;9534:22;9513:53;:::i;:::-;9503:63;;9458:118;9615:2;9641:53;9686:7;9677:6;9666:9;9662:22;9641:53;:::i;:::-;9631:63;;9586:118;9092:619;;;;;:::o;9717:117::-;9826:1;9823;9816:12;9840:117;9949:1;9946;9939:12;9963:117;10072:1;10069;10062:12;10103:568;10176:8;10186:6;10236:3;10229:4;10221:6;10217:17;10213:27;10203:122;;10244:79;;:::i;:::-;10203:122;10357:6;10344:20;10334:30;;10387:18;10379:6;10376:30;10373:117;;;10409:79;;:::i;:::-;10373:117;10523:4;10515:6;10511:17;10499:29;;10577:3;10569:4;10561:6;10557:17;10547:8;10543:32;10540:41;10537:128;;;10584:79;;:::i;:::-;10537:128;10103:568;;;;;:::o;10677:704::-;10772:6;10780;10788;10837:2;10825:9;10816:7;10812:23;10808:32;10805:119;;;10843:79;;:::i;:::-;10805:119;10963:1;10988:53;11033:7;11024:6;11013:9;11009:22;10988:53;:::i;:::-;10978:63;;10934:117;11118:2;11107:9;11103:18;11090:32;11149:18;11141:6;11138:30;11135:117;;;11171:79;;:::i;:::-;11135:117;11284:80;11356:7;11347:6;11336:9;11332:22;11284:80;:::i;:::-;11266:98;;;;11061:313;10677:704;;;;;:::o;11387:86::-;11422:7;11462:4;11455:5;11451:16;11440:27;;11387:86;;;:::o;11479:112::-;11562:22;11578:5;11562:22;:::i;:::-;11557:3;11550:35;11479:112;;:::o;11597:214::-;11686:4;11724:2;11713:9;11709:18;11701:26;;11737:67;11801:1;11790:9;11786:17;11777:6;11737:67;:::i;:::-;11597:214;;;;:::o;11817:113::-;11904:1;11897:5;11894:12;11884:40;;11920:1;11917;11910:12;11884:40;11817:113;:::o;11936:167::-;11996:5;12034:6;12021:20;12012:29;;12050:47;12091:5;12050:47;:::i;:::-;11936:167;;;;:::o;12109:357::-;12182:6;12231:2;12219:9;12210:7;12206:23;12202:32;12199:119;;;12237:79;;:::i;:::-;12199:119;12357:1;12382:67;12441:7;12432:6;12421:9;12417:22;12382:67;:::i;:::-;12372:77;;12328:131;12109:357;;;;:::o;12472:114::-;12539:6;12573:5;12567:12;12557:22;;12472:114;;;:::o;12592:184::-;12691:11;12725:6;12720:3;12713:19;12765:4;12760:3;12756:14;12741:29;;12592:184;;;;:::o;12782:132::-;12849:4;12872:3;12864:11;;12902:4;12897:3;12893:14;12885:22;;12782:132;;;:::o;12920:108::-;12997:24;13015:5;12997:24;:::i;:::-;12992:3;12985:37;12920:108;;:::o;13034:179::-;13103:10;13124:46;13166:3;13158:6;13124:46;:::i;:::-;13202:4;13197:3;13193:14;13179:28;;13034:179;;;;:::o;13219:113::-;13289:4;13321;13316:3;13312:14;13304:22;;13219:113;;;:::o;13368:732::-;13487:3;13516:54;13564:5;13516:54;:::i;:::-;13586:86;13665:6;13660:3;13586:86;:::i;:::-;13579:93;;13696:56;13746:5;13696:56;:::i;:::-;13775:7;13806:1;13791:284;13816:6;13813:1;13810:13;13791:284;;;13892:6;13886:13;13919:63;13978:3;13963:13;13919:63;:::i;:::-;13912:70;;14005:60;14058:6;14005:60;:::i;:::-;13995:70;;13851:224;13838:1;13835;13831:9;13826:14;;13791:284;;;13795:14;14091:3;14084:10;;13492:608;;;13368:732;;;;:::o;14106:373::-;14249:4;14287:2;14276:9;14272:18;14264:26;;14336:9;14330:4;14326:20;14322:1;14311:9;14307:17;14300:47;14364:108;14467:4;14458:6;14364:108;:::i;:::-;14356:116;;14106:373;;;;:::o;14485:117::-;14594:1;14591;14584:12;14608:180;14656:77;14653:1;14646:88;14753:4;14750:1;14743:15;14777:4;14774:1;14767:15;14794:281;14877:27;14899:4;14877:27;:::i;:::-;14869:6;14865:40;15007:6;14995:10;14992:22;14971:18;14959:10;14956:34;14953:62;14950:88;;;15018:18;;:::i;:::-;14950:88;15058:10;15054:2;15047:22;14837:238;14794:281;;:::o;15081:129::-;15115:6;15142:20;;:::i;:::-;15132:30;;15171:33;15199:4;15191:6;15171:33;:::i;:::-;15081:129;;;:::o;15216:308::-;15278:4;15368:18;15360:6;15357:30;15354:56;;;15390:18;;:::i;:::-;15354:56;15428:29;15450:6;15428:29;:::i;:::-;15420:37;;15512:4;15506;15502:15;15494:23;;15216:308;;;:::o;15530:148::-;15628:6;15623:3;15618;15605:30;15669:1;15660:6;15655:3;15651:16;15644:27;15530:148;;;:::o;15684:425::-;15762:5;15787:66;15803:49;15845:6;15803:49;:::i;:::-;15787:66;:::i;:::-;15778:75;;15876:6;15869:5;15862:21;15914:4;15907:5;15903:16;15952:3;15943:6;15938:3;15934:16;15931:25;15928:112;;;15959:79;;:::i;:::-;15928:112;16049:54;16096:6;16091:3;16086;16049:54;:::i;:::-;15768:341;15684:425;;;;;:::o;16129:340::-;16185:5;16234:3;16227:4;16219:6;16215:17;16211:27;16201:122;;16242:79;;:::i;:::-;16201:122;16359:6;16346:20;16384:79;16459:3;16451:6;16444:4;16436:6;16432:17;16384:79;:::i;:::-;16375:88;;16191:278;16129:340;;;;:::o;16475:509::-;16544:6;16593:2;16581:9;16572:7;16568:23;16564:32;16561:119;;;16599:79;;:::i;:::-;16561:119;16747:1;16736:9;16732:17;16719:31;16777:18;16769:6;16766:30;16763:117;;;16799:79;;:::i;:::-;16763:117;16904:63;16959:7;16950:6;16939:9;16935:22;16904:63;:::i;:::-;16894:73;;16690:287;16475:509;;;;:::o;16990:116::-;17027:7;17067:32;17060:5;17056:44;17045:55;;16990:116;;;:::o;17112:118::-;17199:24;17217:5;17199:24;:::i;:::-;17194:3;17187:37;17112:118;;:::o;17236:222::-;17329:4;17367:2;17356:9;17352:18;17344:26;;17380:71;17448:1;17437:9;17433:17;17424:6;17380:71;:::i;:::-;17236:222;;;;:::o;17464:126::-;17564:1;17557:5;17554:12;17544:40;;17580:1;17577;17570:12;17544:40;17464:126;:::o;17596:193::-;17669:5;17707:6;17694:20;17685:29;;17723:60;17777:5;17723:60;:::i;:::-;17596:193;;;;:::o;17795:122::-;17868:24;17886:5;17868:24;:::i;:::-;17861:5;17858:35;17848:63;;17907:1;17904;17897:12;17848:63;17795:122;:::o;17923:139::-;17969:5;18007:6;17994:20;17985:29;;18023:33;18050:5;18023:33;:::i;:::-;17923:139;;;;:::o;18068:673::-;18172:6;18180;18188;18237:2;18225:9;18216:7;18212:23;18208:32;18205:119;;;18243:79;;:::i;:::-;18205:119;18363:1;18388:80;18460:7;18451:6;18440:9;18436:22;18388:80;:::i;:::-;18378:90;;18334:144;18517:2;18543:53;18588:7;18579:6;18568:9;18564:22;18543:53;:::i;:::-;18533:63;;18488:118;18645:2;18671:53;18716:7;18707:6;18696:9;18692:22;18671:53;:::i;:::-;18661:63;;18616:118;18068:673;;;;;:::o;18747:77::-;18784:7;18813:5;18802:16;;18747:77;;;:::o;18830:118::-;18917:24;18935:5;18917:24;:::i;:::-;18912:3;18905:37;18830:118;;:::o;18954:222::-;19047:4;19085:2;19074:9;19070:18;19062:26;;19098:71;19166:1;19155:9;19151:17;19142:6;19098:71;:::i;:::-;18954:222;;;;:::o;19182:116::-;19252:21;19267:5;19252:21;:::i;:::-;19245:5;19242:32;19232:60;;19288:1;19285;19278:12;19232:60;19182:116;:::o;19304:133::-;19347:5;19385:6;19372:20;19363:29;;19401:30;19425:5;19401:30;:::i;:::-;19304:133;;;;:::o;19443:468::-;19508:6;19516;19565:2;19553:9;19544:7;19540:23;19536:32;19533:119;;;19571:79;;:::i;:::-;19533:119;19691:1;19716:53;19761:7;19752:6;19741:9;19737:22;19716:53;:::i;:::-;19706:63;;19662:117;19818:2;19844:50;19886:7;19877:6;19866:9;19862:22;19844:50;:::i;:::-;19834:60;;19789:115;19443:468;;;;;:::o;19917:122::-;19990:24;20008:5;19990:24;:::i;:::-;19983:5;19980:35;19970:63;;20029:1;20026;20019:12;19970:63;19917:122;:::o;20045:139::-;20091:5;20129:6;20116:20;20107:29;;20145:33;20172:5;20145:33;:::i;:::-;20045:139;;;;:::o;20190:474::-;20258:6;20266;20315:2;20303:9;20294:7;20290:23;20286:32;20283:119;;;20321:79;;:::i;:::-;20283:119;20441:1;20466:53;20511:7;20502:6;20491:9;20487:22;20466:53;:::i;:::-;20456:63;;20412:117;20568:2;20594:53;20639:7;20630:6;20619:9;20615:22;20594:53;:::i;:::-;20584:63;;20539:118;20190:474;;;;;:::o;20670:307::-;20731:4;20821:18;20813:6;20810:30;20807:56;;;20843:18;;:::i;:::-;20807:56;20881:29;20903:6;20881:29;:::i;:::-;20873:37;;20965:4;20959;20955:15;20947:23;;20670:307;;;:::o;20983:423::-;21060:5;21085:65;21101:48;21142:6;21101:48;:::i;:::-;21085:65;:::i;:::-;21076:74;;21173:6;21166:5;21159:21;21211:4;21204:5;21200:16;21249:3;21240:6;21235:3;21231:16;21228:25;21225:112;;;21256:79;;:::i;:::-;21225:112;21346:54;21393:6;21388:3;21383;21346:54;:::i;:::-;21066:340;20983:423;;;;;:::o;21425:338::-;21480:5;21529:3;21522:4;21514:6;21510:17;21506:27;21496:122;;21537:79;;:::i;:::-;21496:122;21654:6;21641:20;21679:78;21753:3;21745:6;21738:4;21730:6;21726:17;21679:78;:::i;:::-;21670:87;;21486:277;21425:338;;;;:::o;21769:943::-;21864:6;21872;21880;21888;21937:3;21925:9;21916:7;21912:23;21908:33;21905:120;;;21944:79;;:::i;:::-;21905:120;22064:1;22089:53;22134:7;22125:6;22114:9;22110:22;22089:53;:::i;:::-;22079:63;;22035:117;22191:2;22217:53;22262:7;22253:6;22242:9;22238:22;22217:53;:::i;:::-;22207:63;;22162:118;22319:2;22345:53;22390:7;22381:6;22370:9;22366:22;22345:53;:::i;:::-;22335:63;;22290:118;22475:2;22464:9;22460:18;22447:32;22506:18;22498:6;22495:30;22492:117;;;22528:79;;:::i;:::-;22492:117;22633:62;22687:7;22678:6;22667:9;22663:22;22633:62;:::i;:::-;22623:72;;22418:287;21769:943;;;;;;;:::o;22718:171::-;22820:62;22876:5;22820:62;:::i;:::-;22815:3;22808:75;22718:171;;:::o;22895:108::-;22972:24;22990:5;22972:24;:::i;:::-;22967:3;22960:37;22895:108;;:::o;23083:796::-;23264:4;23259:3;23255:14;23368:4;23361:5;23357:16;23351:23;23387:88;23469:4;23464:3;23460:14;23446:12;23387:88;:::i;:::-;23279:206;23582:4;23575:5;23571:16;23565:23;23601:63;23658:4;23653:3;23649:14;23635:12;23601:63;:::i;:::-;23495:179;23780:4;23773:5;23769:16;23763:23;23799:63;23856:4;23851:3;23847:14;23833:12;23799:63;:::i;:::-;23684:188;23233:646;23083:796;;:::o;23885:390::-;24062:4;24100:2;24089:9;24085:18;24077:26;;24113:155;24265:1;24254:9;24250:17;24241:6;24113:155;:::i;:::-;23885:390;;;;:::o;24281:474::-;24349:6;24357;24406:2;24394:9;24385:7;24381:23;24377:32;24374:119;;;24412:79;;:::i;:::-;24374:119;24532:1;24557:53;24602:7;24593:6;24582:9;24578:22;24557:53;:::i;:::-;24547:63;;24503:117;24659:2;24685:53;24730:7;24721:6;24710:9;24706:22;24685:53;:::i;:::-;24675:63;;24630:118;24281:474;;;;;:::o;24761:819::-;24874:6;24882;24890;24898;24947:3;24935:9;24926:7;24922:23;24918:33;24915:120;;;24954:79;;:::i;:::-;24915:120;25074:1;25099:53;25144:7;25135:6;25124:9;25120:22;25099:53;:::i;:::-;25089:63;;25045:117;25201:2;25227:80;25299:7;25290:6;25279:9;25275:22;25227:80;:::i;:::-;25217:90;;25172:145;25356:2;25382:53;25427:7;25418:6;25407:9;25403:22;25382:53;:::i;:::-;25372:63;;25327:118;25484:2;25510:53;25555:7;25546:6;25535:9;25531:22;25510:53;:::i;:::-;25500:63;;25455:118;24761:819;;;;;;;:::o;25586:180::-;25634:77;25631:1;25624:88;25731:4;25728:1;25721:15;25755:4;25752:1;25745:15;25772:320;25816:6;25853:1;25847:4;25843:12;25833:22;;25900:1;25894:4;25890:12;25921:18;25911:81;;25977:4;25969:6;25965:17;25955:27;;25911:81;26039:2;26031:6;26028:14;26008:18;26005:38;26002:84;;26058:18;;:::i;:::-;26002:84;25823:269;25772:320;;;:::o;26098:442::-;26247:4;26285:2;26274:9;26270:18;26262:26;;26298:71;26366:1;26355:9;26351:17;26342:6;26298:71;:::i;:::-;26379:72;26447:2;26436:9;26432:18;26423:6;26379:72;:::i;:::-;26461;26529:2;26518:9;26514:18;26505:6;26461:72;:::i;:::-;26098:442;;;;;;:::o;26546:94::-;26579:8;26627:5;26623:2;26619:14;26598:35;;26546:94;;;:::o;26646:::-;26685:7;26714:20;26728:5;26714:20;:::i;:::-;26703:31;;26646:94;;;:::o;26746:100::-;26785:7;26814:26;26834:5;26814:26;:::i;:::-;26803:37;;26746:100;;;:::o;26852:157::-;26957:45;26977:24;26995:5;26977:24;:::i;:::-;26957:45;:::i;:::-;26952:3;26945:58;26852:157;;:::o;27015:256::-;27127:3;27142:75;27213:3;27204:6;27142:75;:::i;:::-;27242:2;27237:3;27233:12;27226:19;;27262:3;27255:10;;27015:256;;;;:::o;27277:224::-;27417:34;27413:1;27405:6;27401:14;27394:58;27486:7;27481:2;27473:6;27469:15;27462:32;27277:224;:::o;27507:366::-;27649:3;27670:67;27734:2;27729:3;27670:67;:::i;:::-;27663:74;;27746:93;27835:3;27746:93;:::i;:::-;27864:2;27859:3;27855:12;27848:19;;27507:366;;;:::o;27879:419::-;28045:4;28083:2;28072:9;28068:18;28060:26;;28132:9;28126:4;28122:20;28118:1;28107:9;28103:17;28096:47;28160:131;28286:4;28160:131;:::i;:::-;28152:139;;27879:419;;;:::o;28304:163::-;28444:15;28440:1;28432:6;28428:14;28421:39;28304:163;:::o;28473:366::-;28615:3;28636:67;28700:2;28695:3;28636:67;:::i;:::-;28629:74;;28712:93;28801:3;28712:93;:::i;:::-;28830:2;28825:3;28821:12;28814:19;;28473:366;;;:::o;28845:419::-;29011:4;29049:2;29038:9;29034:18;29026:26;;29098:9;29092:4;29088:20;29084:1;29073:9;29069:17;29062:47;29126:131;29252:4;29126:131;:::i;:::-;29118:139;;28845:419;;;:::o;29270:234::-;29410:34;29406:1;29398:6;29394:14;29387:58;29479:17;29474:2;29466:6;29462:15;29455:42;29270:234;:::o;29510:366::-;29652:3;29673:67;29737:2;29732:3;29673:67;:::i;:::-;29666:74;;29749:93;29838:3;29749:93;:::i;:::-;29867:2;29862:3;29858:12;29851:19;;29510:366;;;:::o;29882:419::-;30048:4;30086:2;30075:9;30071:18;30063:26;;30135:9;30129:4;30125:20;30121:1;30110:9;30106:17;30099:47;30163:131;30289:4;30163:131;:::i;:::-;30155:139;;29882:419;;;:::o;30307:180::-;30355:77;30352:1;30345:88;30452:4;30449:1;30442:15;30476:4;30473:1;30466:15;30493:191;30533:3;30552:20;30570:1;30552:20;:::i;:::-;30547:25;;30586:20;30604:1;30586:20;:::i;:::-;30581:25;;30629:1;30626;30622:9;30615:16;;30650:3;30647:1;30644:10;30641:36;;;30657:18;;:::i;:::-;30641:36;30493:191;;;;:::o;30690:242::-;30830:34;30826:1;30818:6;30814:14;30807:58;30899:25;30894:2;30886:6;30882:15;30875:50;30690:242;:::o;30938:366::-;31080:3;31101:67;31165:2;31160:3;31101:67;:::i;:::-;31094:74;;31177:93;31266:3;31177:93;:::i;:::-;31295:2;31290:3;31286:12;31279:19;;30938:366;;;:::o;31310:419::-;31476:4;31514:2;31503:9;31499:18;31491:26;;31563:9;31557:4;31553:20;31549:1;31538:9;31534:17;31527:47;31591:131;31717:4;31591:131;:::i;:::-;31583:139;;31310:419;;;:::o;31735:167::-;31875:19;31871:1;31863:6;31859:14;31852:43;31735:167;:::o;31908:366::-;32050:3;32071:67;32135:2;32130:3;32071:67;:::i;:::-;32064:74;;32147:93;32236:3;32147:93;:::i;:::-;32265:2;32260:3;32256:12;32249:19;;31908:366;;;:::o;32280:419::-;32446:4;32484:2;32473:9;32469:18;32461:26;;32533:9;32527:4;32523:20;32519:1;32508:9;32504:17;32497:47;32561:131;32687:4;32561:131;:::i;:::-;32553:139;;32280:419;;;:::o;32705:410::-;32745:7;32768:20;32786:1;32768:20;:::i;:::-;32763:25;;32802:20;32820:1;32802:20;:::i;:::-;32797:25;;32857:1;32854;32850:9;32879:30;32897:11;32879:30;:::i;:::-;32868:41;;33058:1;33049:7;33045:15;33042:1;33039:22;33019:1;33012:9;32992:83;32969:139;;33088:18;;:::i;:::-;32969:139;32753:362;32705:410;;;;:::o;33121:173::-;33261:25;33257:1;33249:6;33245:14;33238:49;33121:173;:::o;33300:366::-;33442:3;33463:67;33527:2;33522:3;33463:67;:::i;:::-;33456:74;;33539:93;33628:3;33539:93;:::i;:::-;33657:2;33652:3;33648:12;33641:19;;33300:366;;;:::o;33672:419::-;33838:4;33876:2;33865:9;33861:18;33853:26;;33925:9;33919:4;33915:20;33911:1;33900:9;33896:17;33889:47;33953:131;34079:4;33953:131;:::i;:::-;33945:139;;33672:419;;;:::o;34097:117::-;34206:1;34203;34196:12;34343:197;34427:5;34458:6;34452:13;34443:22;;34474:60;34528:5;34474:60;:::i;:::-;34343:197;;;;:::o;34546:143::-;34603:5;34634:6;34628:13;34619:22;;34650:33;34677:5;34650:33;:::i;:::-;34546:143;;;;:::o;34734:879::-;34836:5;34880:4;34868:9;34863:3;34859:19;34855:30;34852:117;;;34888:79;;:::i;:::-;34852:117;34987:21;35003:4;34987:21;:::i;:::-;34978:30;;35084:1;35124:87;35207:3;35198:6;35187:9;35183:22;35124:87;:::i;:::-;35117:4;35110:5;35106:16;35099:113;35018:205;35297:2;35338:60;35394:3;35385:6;35374:9;35370:22;35338:60;:::i;:::-;35331:4;35324:5;35320:16;35313:86;35233:177;35493:2;35534:60;35590:3;35581:6;35570:9;35566:22;35534:60;:::i;:::-;35527:4;35520:5;35516:16;35509:86;35420:186;34734:879;;;;:::o;35619:435::-;35731:6;35780:2;35768:9;35759:7;35755:23;35751:32;35748:119;;;35786:79;;:::i;:::-;35748:119;35906:1;35931:106;36029:7;36020:6;36009:9;36005:22;35931:106;:::i;:::-;35921:116;;35877:170;35619:435;;;;:::o;36060:332::-;36181:4;36219:2;36208:9;36204:18;36196:26;;36232:71;36300:1;36289:9;36285:17;36276:6;36232:71;:::i;:::-;36313:72;36381:2;36370:9;36366:18;36357:6;36313:72;:::i;:::-;36060:332;;;;;:::o;36398:137::-;36452:5;36483:6;36477:13;36468:22;;36499:30;36523:5;36499:30;:::i;:::-;36398:137;;;;:::o;36541:345::-;36608:6;36657:2;36645:9;36636:7;36632:23;36628:32;36625:119;;;36663:79;;:::i;:::-;36625:119;36783:1;36808:61;36861:7;36852:6;36841:9;36837:22;36808:61;:::i;:::-;36798:71;;36754:125;36541:345;;;;:::o;36892:147::-;36993:11;37030:3;37015:18;;36892:147;;;;:::o;37045:114::-;;:::o;37165:398::-;37324:3;37345:83;37426:1;37421:3;37345:83;:::i;:::-;37338:90;;37437:93;37526:3;37437:93;:::i;:::-;37555:1;37550:3;37546:11;37539:18;;37165:398;;;:::o;37569:379::-;37753:3;37775:147;37918:3;37775:147;:::i;:::-;37768:154;;37939:3;37932:10;;37569:379;;;:::o;37954:165::-;38094:17;38090:1;38082:6;38078:14;38071:41;37954:165;:::o;38125:366::-;38267:3;38288:67;38352:2;38347:3;38288:67;:::i;:::-;38281:74;;38364:93;38453:3;38364:93;:::i;:::-;38482:2;38477:3;38473:12;38466:19;;38125:366;;;:::o;38497:419::-;38663:4;38701:2;38690:9;38686:18;38678:26;;38750:9;38744:4;38740:20;38736:1;38725:9;38721:17;38714:47;38778:131;38904:4;38778:131;:::i;:::-;38770:139;;38497:419;;;:::o;38922:224::-;39062:34;39058:1;39050:6;39046:14;39039:58;39131:7;39126:2;39118:6;39114:15;39107:32;38922:224;:::o;39152:366::-;39294:3;39315:67;39379:2;39374:3;39315:67;:::i;:::-;39308:74;;39391:93;39480:3;39391:93;:::i;:::-;39509:2;39504:3;39500:12;39493:19;;39152:366;;;:::o;39524:419::-;39690:4;39728:2;39717:9;39713:18;39705:26;;39777:9;39771:4;39767:20;39763:1;39752:9;39748:17;39741:47;39805:131;39931:4;39805:131;:::i;:::-;39797:139;;39524:419;;;:::o;39949:242::-;40089:34;40085:1;40077:6;40073:14;40066:58;40158:25;40153:2;40145:6;40141:15;40134:50;39949:242;:::o;40197:366::-;40339:3;40360:67;40424:2;40419:3;40360:67;:::i;:::-;40353:74;;40436:93;40525:3;40436:93;:::i;:::-;40554:2;40549:3;40545:12;40538:19;;40197:366;;;:::o;40569:419::-;40735:4;40773:2;40762:9;40758:18;40750:26;;40822:9;40816:4;40812:20;40808:1;40797:9;40793:17;40786:47;40850:131;40976:4;40850:131;:::i;:::-;40842:139;;40569:419;;;:::o;40994:311::-;41071:4;41161:18;41153:6;41150:30;41147:56;;;41183:18;;:::i;:::-;41147:56;41233:4;41225:6;41221:17;41213:25;;41293:4;41287;41283:15;41275:23;;40994:311;;;:::o;41311:143::-;41368:5;41399:6;41393:13;41384:22;;41415:33;41442:5;41415:33;:::i;:::-;41311:143;;;;:::o;41477:732::-;41584:5;41609:81;41625:64;41682:6;41625:64;:::i;:::-;41609:81;:::i;:::-;41600:90;;41710:5;41739:6;41732:5;41725:21;41773:4;41766:5;41762:16;41755:23;;41826:4;41818:6;41814:17;41806:6;41802:30;41855:3;41847:6;41844:15;41841:122;;;41874:79;;:::i;:::-;41841:122;41989:6;41972:231;42006:6;42001:3;41998:15;41972:231;;;42081:3;42110:48;42154:3;42142:10;42110:48;:::i;:::-;42105:3;42098:61;42188:4;42183:3;42179:14;42172:21;;42048:155;42032:4;42027:3;42023:14;42016:21;;41972:231;;;41976:21;41590:619;;41477:732;;;;;:::o;42232:385::-;42314:5;42363:3;42356:4;42348:6;42344:17;42340:27;42330:122;;42371:79;;:::i;:::-;42330:122;42481:6;42475:13;42506:105;42607:3;42599:6;42592:4;42584:6;42580:17;42506:105;:::i;:::-;42497:114;;42320:297;42232:385;;;;:::o;42623:554::-;42718:6;42767:2;42755:9;42746:7;42742:23;42738:32;42735:119;;;42773:79;;:::i;:::-;42735:119;42914:1;42903:9;42899:17;42893:24;42944:18;42936:6;42933:30;42930:117;;;42966:79;;:::i;:::-;42930:117;43071:89;43152:7;43143:6;43132:9;43128:22;43071:89;:::i;:::-;43061:99;;42864:306;42623:554;;;;:::o;43183:141::-;43232:4;43255:3;43247:11;;43278:3;43275:1;43268:14;43312:4;43309:1;43299:18;43291:26;;43183:141;;;:::o;43330:93::-;43367:6;43414:2;43409;43402:5;43398:14;43394:23;43384:33;;43330:93;;;:::o;43429:107::-;43473:8;43523:5;43517:4;43513:16;43492:37;;43429:107;;;;:::o;43542:393::-;43611:6;43661:1;43649:10;43645:18;43684:97;43714:66;43703:9;43684:97;:::i;:::-;43802:39;43832:8;43821:9;43802:39;:::i;:::-;43790:51;;43874:4;43870:9;43863:5;43859:21;43850:30;;43923:4;43913:8;43909:19;43902:5;43899:30;43889:40;;43618:317;;43542:393;;;;;:::o;43941:142::-;43991:9;44024:53;44042:34;44051:24;44069:5;44051:24;:::i;:::-;44042:34;:::i;:::-;44024:53;:::i;:::-;44011:66;;43941:142;;;:::o;44089:75::-;44132:3;44153:5;44146:12;;44089:75;;;:::o;44170:269::-;44280:39;44311:7;44280:39;:::i;:::-;44341:91;44390:41;44414:16;44390:41;:::i;:::-;44382:6;44375:4;44369:11;44341:91;:::i;:::-;44335:4;44328:105;44246:193;44170:269;;;:::o;44445:73::-;44490:3;44445:73;:::o;44524:189::-;44601:32;;:::i;:::-;44642:65;44700:6;44692;44686:4;44642:65;:::i;:::-;44577:136;44524:189;;:::o;44719:186::-;44779:120;44796:3;44789:5;44786:14;44779:120;;;44850:39;44887:1;44880:5;44850:39;:::i;:::-;44823:1;44816:5;44812:13;44803:22;;44779:120;;;44719:186;;:::o;44911:543::-;45012:2;45007:3;45004:11;45001:446;;;45046:38;45078:5;45046:38;:::i;:::-;45130:29;45148:10;45130:29;:::i;:::-;45120:8;45116:44;45313:2;45301:10;45298:18;45295:49;;;45334:8;45319:23;;45295:49;45357:80;45413:22;45431:3;45413:22;:::i;:::-;45403:8;45399:37;45386:11;45357:80;:::i;:::-;45016:431;;45001:446;44911:543;;;:::o;45460:117::-;45514:8;45564:5;45558:4;45554:16;45533:37;;45460:117;;;;:::o;45583:169::-;45627:6;45660:51;45708:1;45704:6;45696:5;45693:1;45689:13;45660:51;:::i;:::-;45656:56;45741:4;45735;45731:15;45721:25;;45634:118;45583:169;;;;:::o;45757:295::-;45833:4;45979:29;46004:3;45998:4;45979:29;:::i;:::-;45971:37;;46041:3;46038:1;46034:11;46028:4;46025:21;46017:29;;45757:295;;;;:::o;46057:1395::-;46174:37;46207:3;46174:37;:::i;:::-;46276:18;46268:6;46265:30;46262:56;;;46298:18;;:::i;:::-;46262:56;46342:38;46374:4;46368:11;46342:38;:::i;:::-;46427:67;46487:6;46479;46473:4;46427:67;:::i;:::-;46521:1;46545:4;46532:17;;46577:2;46569:6;46566:14;46594:1;46589:618;;;;47251:1;47268:6;47265:77;;;47317:9;47312:3;47308:19;47302:26;47293:35;;47265:77;47368:67;47428:6;47421:5;47368:67;:::i;:::-;47362:4;47355:81;47224:222;46559:887;;46589:618;46641:4;46637:9;46629:6;46625:22;46675:37;46707:4;46675:37;:::i;:::-;46734:1;46748:208;46762:7;46759:1;46756:14;46748:208;;;46841:9;46836:3;46832:19;46826:26;46818:6;46811:42;46892:1;46884:6;46880:14;46870:24;;46939:2;46928:9;46924:18;46911:31;;46785:4;46782:1;46778:12;46773:17;;46748:208;;;46984:6;46975:7;46972:19;46969:179;;;47042:9;47037:3;47033:19;47027:26;47085:48;47127:4;47119:6;47115:17;47104:9;47085:48;:::i;:::-;47077:6;47070:64;46992:156;46969:179;47194:1;47190;47182:6;47178:14;47174:22;47168:4;47161:36;46596:611;;;46559:887;;46149:1303;;;46057:1395;;:::o;47458:382::-;47604:4;47642:2;47631:9;47627:18;47619:26;;47655:71;47723:1;47712:9;47708:17;47699:6;47655:71;:::i;:::-;47736:97;47829:2;47818:9;47814:18;47805:6;47736:97;:::i;:::-;47458:382;;;;;:::o;47846:332::-;47967:4;48005:2;47994:9;47990:18;47982:26;;48018:71;48086:1;48075:9;48071:17;48062:6;48018:71;:::i;:::-;48099:72;48167:2;48156:9;48152:18;48143:6;48099:72;:::i;:::-;47846:332;;;;;:::o;48184:228::-;48324:34;48320:1;48312:6;48308:14;48301:58;48393:11;48388:2;48380:6;48376:15;48369:36;48184:228;:::o;48418:366::-;48560:3;48581:67;48645:2;48640:3;48581:67;:::i;:::-;48574:74;;48657:93;48746:3;48657:93;:::i;:::-;48775:2;48770:3;48766:12;48759:19;;48418:366;;;:::o;48790:419::-;48956:4;48994:2;48983:9;48979:18;48971:26;;49043:9;49037:4;49033:20;49029:1;49018:9;49014:17;49007:47;49071:131;49197:4;49071:131;:::i;:::-;49063:139;;48790:419;;;:::o;49215:172::-;49355:24;49351:1;49343:6;49339:14;49332:48;49215:172;:::o;49393:366::-;49535:3;49556:67;49620:2;49615:3;49556:67;:::i;:::-;49549:74;;49632:93;49721:3;49632:93;:::i;:::-;49750:2;49745:3;49741:12;49734:19;;49393:366;;;:::o;49765:419::-;49931:4;49969:2;49958:9;49954:18;49946:26;;50018:9;50012:4;50008:20;50004:1;49993:9;49989:17;49982:47;50046:131;50172:4;50046:131;:::i;:::-;50038:139;;49765:419;;;:::o;50190:246::-;50330:34;50326:1;50318:6;50314:14;50307:58;50399:29;50394:2;50386:6;50382:15;50375:54;50190:246;:::o;50442:366::-;50584:3;50605:67;50669:2;50664:3;50605:67;:::i;:::-;50598:74;;50681:93;50770:3;50681:93;:::i;:::-;50799:2;50794:3;50790:12;50783:19;;50442:366;;;:::o;50814:419::-;50980:4;51018:2;51007:9;51003:18;50995:26;;51067:9;51061:4;51057:20;51053:1;51042:9;51038:17;51031:47;51095:131;51221:4;51095:131;:::i;:::-;51087:139;;50814:419;;;:::o;51239:115::-;51324:23;51341:5;51324:23;:::i;:::-;51319:3;51312:36;51239:115;;:::o;51360:218::-;51451:4;51489:2;51478:9;51474:18;51466:26;;51502:69;51568:1;51557:9;51553:17;51544:6;51502:69;:::i;:::-;51360:218;;;;:::o;51584:332::-;51705:4;51743:2;51732:9;51728:18;51720:26;;51756:71;51824:1;51813:9;51809:17;51800:6;51756:71;:::i;:::-;51837:72;51905:2;51894:9;51890:18;51881:6;51837:72;:::i;:::-;51584:332;;;;;:::o;51922:234::-;52062:34;52058:1;52050:6;52046:14;52039:58;52131:17;52126:2;52118:6;52114:15;52107:42;51922:234;:::o;52162:366::-;52304:3;52325:67;52389:2;52384:3;52325:67;:::i;:::-;52318:74;;52401:93;52490:3;52401:93;:::i;:::-;52519:2;52514:3;52510:12;52503:19;;52162:366;;;:::o;52534:419::-;52700:4;52738:2;52727:9;52723:18;52715:26;;52787:9;52781:4;52777:20;52773:1;52762:9;52758:17;52751:47;52815:131;52941:4;52815:131;:::i;:::-;52807:139;;52534:419;;;:::o;52959:148::-;53061:11;53098:3;53083:18;;52959:148;;;;:::o;53113:390::-;53219:3;53247:39;53280:5;53247:39;:::i;:::-;53302:89;53384:6;53379:3;53302:89;:::i;:::-;53295:96;;53400:65;53458:6;53453:3;53446:4;53439:5;53435:16;53400:65;:::i;:::-;53490:6;53485:3;53481:16;53474:23;;53223:280;53113:390;;;;:::o;53533:874::-;53636:3;53673:5;53667:12;53702:36;53728:9;53702:36;:::i;:::-;53754:89;53836:6;53831:3;53754:89;:::i;:::-;53747:96;;53874:1;53863:9;53859:17;53890:1;53885:166;;;;54065:1;54060:341;;;;53852:549;;53885:166;53969:4;53965:9;53954;53950:25;53945:3;53938:38;54031:6;54024:14;54017:22;54009:6;54005:35;54000:3;53996:45;53989:52;;53885:166;;54060:341;54127:38;54159:5;54127:38;:::i;:::-;54187:1;54201:154;54215:6;54212:1;54209:13;54201:154;;;54289:7;54283:14;54279:1;54274:3;54270:11;54263:35;54339:1;54330:7;54326:15;54315:26;;54237:4;54234:1;54230:12;54225:17;;54201:154;;;54384:6;54379:3;54375:16;54368:23;;54067:334;;53852:549;;53640:767;;53533:874;;;;:::o;54413:589::-;54638:3;54660:95;54751:3;54742:6;54660:95;:::i;:::-;54653:102;;54772:95;54863:3;54854:6;54772:95;:::i;:::-;54765:102;;54884:92;54972:3;54963:6;54884:92;:::i;:::-;54877:99;;54993:3;54986:10;;54413:589;;;;;;:::o;55008:238::-;55148:34;55144:1;55136:6;55132:14;55125:58;55217:21;55212:2;55204:6;55200:15;55193:46;55008:238;:::o;55252:366::-;55394:3;55415:67;55479:2;55474:3;55415:67;:::i;:::-;55408:74;;55491:93;55580:3;55491:93;:::i;:::-;55609:2;55604:3;55600:12;55593:19;;55252:366;;;:::o;55624:419::-;55790:4;55828:2;55817:9;55813:18;55805:26;;55877:9;55871:4;55867:20;55863:1;55852:9;55848:17;55841:47;55905:131;56031:4;55905:131;:::i;:::-;55897:139;;55624:419;;;:::o;56049:171::-;56088:3;56111:24;56129:5;56111:24;:::i;:::-;56102:33;;56157:4;56150:5;56147:15;56144:41;;56165:18;;:::i;:::-;56144:41;56212:1;56205:5;56201:13;56194:20;;56049:171;;;:::o;56226:98::-;56277:6;56311:5;56305:12;56295:22;;56226:98;;;:::o;56330:168::-;56413:11;56447:6;56442:3;56435:19;56487:4;56482:3;56478:14;56463:29;;56330:168;;;;:::o;56504:373::-;56590:3;56618:38;56650:5;56618:38;:::i;:::-;56672:70;56735:6;56730:3;56672:70;:::i;:::-;56665:77;;56751:65;56809:6;56804:3;56797:4;56790:5;56786:16;56751:65;:::i;:::-;56841:29;56863:6;56841:29;:::i;:::-;56836:3;56832:39;56825:46;;56594:283;56504:373;;;;:::o;56883:640::-;57078:4;57116:3;57105:9;57101:19;57093:27;;57130:71;57198:1;57187:9;57183:17;57174:6;57130:71;:::i;:::-;57211:72;57279:2;57268:9;57264:18;57255:6;57211:72;:::i;:::-;57293;57361:2;57350:9;57346:18;57337:6;57293:72;:::i;:::-;57412:9;57406:4;57402:20;57397:2;57386:9;57382:18;57375:48;57440:76;57511:4;57502:6;57440:76;:::i;:::-;57432:84;;56883:640;;;;;;;:::o;57529:141::-;57585:5;57616:6;57610:13;57601:22;;57632:32;57658:5;57632:32;:::i;:::-;57529:141;;;;:::o;57676:349::-;57745:6;57794:2;57782:9;57773:7;57769:23;57765:32;57762:119;;;57800:79;;:::i;:::-;57762:119;57920:1;57945:63;58000:7;57991:6;57980:9;57976:22;57945:63;:::i;:::-;57935:73;;57891:127;57676:349;;;;:::o;58031:180::-;58079:77;58076:1;58069:88;58176:4;58173:1;58166:15;58200:4;58197:1;58190:15

Swarm Source

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