ETH Price: $3,057.26 (-7.46%)
Gas: 18 Gwei

Token

ArtaxiaNFT (ARTAX)
 

Overview

Max Total Supply

1,143 ARTAX

Holders

923

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 ARTAX
0x4d36e4bc1e43840bbe79f7fed6b959f3365186b0
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:
ArtaxiaNFT

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 1 of 14: Artaxia.sol
// SPDX-License-Identifier: MIT

import {DefaultOperatorFilterer} from "./DefaultOperatorFilterer.sol";

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 *
 * 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.
 */
library MerkleProof {
    /**
     * @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 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.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = _efficientHash(computedHash, proofElement);
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = _efficientHash(proofElement, computedHash);
            }
        }
        return computedHash;
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

abstract contract ReentrancyGuard { 
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }
    modifier nonReentrant() {
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
   _status = _ENTERED;

        _;
        _status = _NOT_ENTERED;
    }
}

library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
 
    function toString(uint256 value) internal pure returns (string memory) { 
        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }
 
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }
 
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}
 
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}
 
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
 
    constructor() {
        _transferOwnership(_msgSender());
    }
 
    function owner() public view virtual returns (address) {
        return _owner;
    } 
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }
 
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }
 
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }
 
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
 
library Address { 
    function isContract(address account) internal view returns (bool) { 
        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    } 
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }
 
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    } 
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }
 
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }
 
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    } 
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }
 
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }
 
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }
 
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }
 
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else { 
            if (returndata.length > 0) { 

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}
 
interface IERC721Receiver { 
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}
 
interface IERC165 { 
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
 
abstract contract ERC165 is IERC165 { 
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
} 
interface IERC721 is IERC165 { 
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); 
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); 
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved); 
    function balanceOf(address owner) external view returns (uint256 balance); 
    function ownerOf(uint256 tokenId) external view returns (address owner); 
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external; 
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external; 
    function approve(address to, uint256 tokenId) external;
 
    function getApproved(uint256 tokenId) external view returns (address operator); 
    function setApprovalForAll(address operator, bool _approved) external; 
    function isApprovedForAll(address owner, address operator) external view returns (bool); 
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
} 
interface IERC721Enumerable is IERC721 { 
    function totalSupply() external view returns (uint256); 
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); 
    function tokenByIndex(uint256 index) external view returns (uint256);
}  
interface IERC721Metadata is IERC721 { 
    function name() external view returns (string memory); 
    function symbol() external view returns (string memory); 
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

error ApprovalCallerNotOwnerNorApproved();
error ApprovalQueryForNonexistentToken();
error ApproveToCaller();
error ApprovalToCurrentOwner();
error BalanceQueryForZeroAddress();
error MintToZeroAddress();
error MintZeroQuantity();
error OwnerQueryForNonexistentToken();
error TransferCallerNotOwnerNorApproved();
error TransferFromIncorrectOwner();
error TransferToNonERC721ReceiverImplementer();
error TransferToZeroAddress();
error URIQueryForNonexistentToken();

contract ERC721A is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Compiler will pack this into a single 256bit word.
    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
    }

    // Compiler will pack this into a single 256bit word.
    struct AddressData {
        // Realistically, 2**64-1 is more than enough.
        uint64 balance;
        // Keeps track of mint count with minimal overhead for tokenomics.
        uint64 numberMinted;
        // Keeps track of burn count with minimal overhead for tokenomics.
        uint64 numberBurned;
        // For miscellaneous variable(s) pertaining to the address
        // (e.g. number of whitelist mint slots used).
        // If there are multiple variables, please pack them into a uint64.
        uint64 aux;
    }

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

    // The number of tokens burned.
    uint256 internal _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 _ownershipOf implementation for details.
    mapping(uint256 => TokenOwnership) internal _ownerships;

    // Mapping owner address to address data
    mapping(address => AddressData) private _addressData;

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

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

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

    /**
     * To change the starting tokenId, please override this function.
     */
    function _startTokenId() internal view virtual returns (uint256) {
        return 1;
    }

    /**
     * @dev Burned tokens are calculated here, use _totalMinted() if you want to count just minted tokens.
     */
    function totalSupply() public view returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than _currentIndex - _startTokenId() times
        unchecked {
            return _currentIndex - _burnCounter - _startTokenId();
        }
    }

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

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

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

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        return uint256(_addressData[owner].numberMinted);
    }

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

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

    /**
     * Sets the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     * If there are multiple variables, please pack them into a uint64.
     */
    function _setAux(address owner, uint64 aux) internal {
        _addressData[owner].aux = aux;
    }

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

        unchecked {
            if (_startTokenId() <= curr && curr < _currentIndex) {
                TokenOwnership memory ownership = _ownerships[curr];
                if (!ownership.burned) {
                    if (ownership.addr != address(0)) {
                        return ownership;
                    }
                    // Invariant:
                    // There will always be an ownership that has an address and is not burned
                    // before an ownership that does not have an address and is not burned.
                    // Hence, curr will not underflow.
                    while (true) {
                        curr--;
                        ownership = _ownerships[curr];
                        if (ownership.addr != address(0)) {
                            return ownership;
                        }
                    }
                }
            }
        }
        revert OwnerQueryForNonexistentToken();
    }

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

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

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

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

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

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

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

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

        _approve(to, tokenId, owner);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

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

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

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

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

    function _safeMint(address to, uint256 quantity) internal {
        _safeMint(to, quantity, '');
    }

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

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

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

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            _addressData[to].balance += uint64(quantity);
            _addressData[to].numberMinted += uint64(quantity);

            _ownerships[startTokenId].addr = to;
            _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);

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

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

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

        if (prevOwnership.addr != from) revert TransferFromIncorrectOwner();

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

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

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId, from);

        // 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 {
            _addressData[from].balance -= 1;
            _addressData[to].balance += 1;

            TokenOwnership storage currSlot = _ownerships[tokenId];
            currSlot.addr = to;
            currSlot.startTimestamp = uint64(block.timestamp);

            // If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it.
            // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
            uint256 nextTokenId = tokenId + 1;
            TokenOwnership storage nextSlot = _ownerships[nextTokenId];
            if (nextSlot.addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId != _currentIndex) {
                    nextSlot.addr = from;
                    nextSlot.startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

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

    /**
     * @dev This is 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 {
        TokenOwnership memory prevOwnership = _ownershipOf(tokenId);

        address from = prevOwnership.addr;

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

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

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

        // Clear approvals from the previous owner
        _approve(address(0), tokenId, from);

        // 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 {
            AddressData storage addressData = _addressData[from];
            addressData.balance -= 1;
            addressData.numberBurned += 1;

            // Keep track of who burned the token, and the timestamp of burning.
            TokenOwnership storage currSlot = _ownerships[tokenId];
            currSlot.addr = from;
            currSlot.startTimestamp = uint64(block.timestamp);
            currSlot.burned = true;

            // If the ownership slot of tokenId+1 is not explicitly set, that means the burn initiator owns it.
            // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
            uint256 nextTokenId = tokenId + 1;
            TokenOwnership storage nextSlot = _ownerships[nextTokenId];
            if (nextSlot.addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId != _currentIndex) {
                    nextSlot.addr = from;
                    nextSlot.startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

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

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

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(
        address to,
        uint256 tokenId,
        address owner
    ) private {
        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

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

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

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

contract ArtaxiaNFT is Ownable, ERC721A, ReentrancyGuard, DefaultOperatorFilterer {
  using Strings for uint256;


  uint256 public MAX_PER_Transaction = 10; // maximam amount that user can mint/Transaction
  uint256 public MAX_PER_WALLET = 10; // maximam amount that user can mint/Wallet

  uint256 public PRICE = 0.01 ether; 

  uint256 private constant TotalCollectionSize_ = 1143; // total number of nfts
  uint256 private constant MaxMintPerBatch_ = 20; //max mint per transaction
  uint256 public PhaseCollectionSize_ = 1143; // total number of nfts in Phase 1

  uint public status = 0; //0-pause 1-Whitelist 2-Public

  string private _baseTokenURI;
  string private _uriBeforeReveal;
  bool public revealed = false;

  mapping(address => uint256) public publicClaimedBy;

  constructor() ERC721A("ArtaxiaNFT","ARTAX") {

  }

  modifier callerIsUser() {
    require(tx.origin == msg.sender, "The caller is another contract");
    _;
  }
 
  function mint(uint256 quantity) external payable callerIsUser {
    require(status == 2 , "Sale is not Active");
    require(totalSupply() + quantity <= TotalCollectionSize_, "reached max supply");
    require(totalSupply() + quantity <= PhaseCollectionSize_, "reached max phase supply");
    require(quantity <= MAX_PER_Transaction,"can not mint this many");
    require(msg.value >= PRICE * quantity, "Need to send more ETH.");

    publicClaimedBy[msg.sender] += quantity;
    require(publicClaimedBy[msg.sender] <= MAX_PER_WALLET, "Purchase exceeds max allowed");

    _safeMint(msg.sender, quantity);
  }

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

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

   function setURIbeforeReveal(string memory URI) external onlyOwner {
    _uriBeforeReveal = URI;
  }

   function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
       require(_exists(tokenId),"ERC721Metadata: URI query for nonexistent token");

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

        string memory baseURI = _baseURI();
        return
            bytes(baseURI).length > 0
               ? string(abi.encodePacked(baseURI, "/", tokenId.toString(), ".json")) : "";

  }

  function changeRevealStatus() public onlyOwner {
        revealed = true;
  }

  function numberMinted(address owner) public view returns (uint256) {
    return _numberMinted(owner);
  }
  function getOwnershipData(uint256 tokenId)
    external
    view
    returns (TokenOwnership memory)
  {
    return _ownershipOf(tokenId);
  }

  function withdrawMoney() external onlyOwner nonReentrant {
    (bool success, ) = msg.sender.call{value: address(this).balance}("");
    require(success, "Transfer failed.");
  }

  function changePhaseCollectionSize(uint256 _collection)
        external
        onlyOwner
    {
        PhaseCollectionSize_ = _collection;
    }

  function changeMintPrice(uint256 _newPrice) external onlyOwner
  {
      PRICE = _newPrice;
  }

  function changeMAX_PER_Transaction(uint256 q) external onlyOwner
  {
      MAX_PER_Transaction = q;
  }

     function changeMAX_PER_WALLET(uint256 q) external onlyOwner
  {
      MAX_PER_WALLET = q;
  }

  function setStatus(uint256 s)external onlyOwner{
      status = s;
  }

   function getStatus()public view returns(uint){
      return status;
  }
  
  function getPrice(uint256 _quantity) public view returns (uint256) {
       
        return _quantity*PRICE;
    }

  function airdrop(address sendTo, uint quantity)public onlyOwner{
    require(totalSupply() + quantity <= TotalCollectionSize_, "reached max supply");
    _safeMint(sendTo, quantity);
  }

      // Whitelist Sale //

    uint256 public whiteListPerWallet = 4;
    uint256 public MAX_PER_WL_TRANSACTION = 4; // maximam amount that user can mint/Wallet
    bytes32 public whitelistMerkleRoot;
    uint256 public itemPriceWhiteList = 0 ether;
    uint256 private TotalWLavailable = 1143; // total number of nfts
    mapping(address => uint256) public whiteListClaimedBy; // mapping list


    function setWhitelistMerkleRoot(bytes32 _whitelistMerkleRoot) external onlyOwner {
        whitelistMerkleRoot = _whitelistMerkleRoot;
    }

    function getWhitelistPrice(uint256 _quantity) public view returns (uint256) {
       
           return _quantity*itemPriceWhiteList;
    }

    function inWhitelist(bytes32[] memory _proof, address _owner) public view returns (bool) {
        return MerkleProof.verify(_proof, whitelistMerkleRoot, keccak256(abi.encodePacked(_owner)));
    }
     
    function purchaseWhiteListTokens(uint256 _howMany, bytes32[] calldata _proof) external payable {
        require(status == 1 , "Sale is not active ");
        require(totalSupply()+_howMany<=TotalWLavailable,"Quantity must be lesser then MaxSupply");
        require(inWhitelist(_proof, msg.sender), "You are not in presale");
        require(msg.value >= _howMany * itemPriceWhiteList, "Try to send more ETH");
        require(_howMany <= MAX_PER_WL_TRANSACTION , "can not mint this many");

        whiteListClaimedBy[msg.sender] += _howMany;
        require(whiteListClaimedBy[msg.sender] <= whiteListPerWallet, "Purchase exceeds max allowed");
  
        _safeMint(msg.sender, _howMany);
    }

    function setWhiteListPerWallet(uint256 _whiteListPerWallet) external onlyOwner {
        whiteListPerWallet = _whiteListPerWallet;
    }

     function setWLavailable(uint256 _whiteListCollection) external onlyOwner {
        TotalWLavailable = _whiteListCollection;
    }

    function setPriceWhiteList(uint256 _itemPriceWhiteList) external onlyOwner {
        itemPriceWhiteList = _itemPriceWhiteList;
    }

    function changeMAX_PER_WL_TRANSACTION(uint256 q) external onlyOwner { 
      MAX_PER_WL_TRANSACTION = q;
    }

    // ---------- CREATOR FEES CODE -------- //


     function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {
        super.setApprovalForAll(operator, approved);
    }

    function approve(address operator, uint256 tokenId) public override onlyAllowedOperatorApproval(operator) {
        super.approve(operator, tokenId);
    }

    function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) {
        super.transferFrom(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) {
        super.safeTransferFrom(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data)
        public
        override
        onlyAllowedOperator(from)
    {
        super.safeTransferFrom(from, to, tokenId, data);
    }
}

File 2 of 14: Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

File 3 of 14: DefaultOperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {OperatorFilterer} from "./OperatorFilterer.sol";

/**
 * @title  DefaultOperatorFilterer
 * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription.
 */
abstract contract DefaultOperatorFilterer is OperatorFilterer {
    address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

    constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {}
}

File 4 of 14: EnumerableSet.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 *
 * [WARNING]
 * ====
 * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
 * unusable.
 * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
 * array of EnumerableSet.
 * ====
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                bytes32 lastValue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastValue;
                // Update the index for the moved value
                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value)
        private
        view
        returns (bool)
    {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index)
        private
        view
        returns (bytes32)
    {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value)
        internal
        returns (bool)
    {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value)
        internal
        returns (bool)
    {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value)
        internal
        view
        returns (bool)
    {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index)
        internal
        view
        returns (bytes32)
    {
        return _at(set._inner, index);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set)
        internal
        view
        returns (bytes32[] memory)
    {
        bytes32[] memory store = _values(set._inner);
        bytes32[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value)
        internal
        returns (bool)
    {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value)
        internal
        returns (bool)
    {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value)
        internal
        view
        returns (bool)
    {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index)
        internal
        view
        returns (address)
    {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set)
        internal
        view
        returns (address[] memory)
    {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value)
        internal
        returns (bool)
    {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value)
        internal
        view
        returns (bool)
    {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index)
        internal
        view
        returns (uint256)
    {
        return uint256(_at(set._inner, index));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set)
        internal
        view
        returns (uint256[] memory)
    {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }
}

File 5 of 14: IOperatorFilterRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    function isOperatorAllowed(address registrant, address operator) external view returns (bool);
    function register(address registrant) external;
    function registerAndSubscribe(address registrant, address subscription) external;
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;
    function unregister(address addr) external;
    function updateOperator(address registrant, address operator, bool filtered) external;
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;
    function subscribe(address registrant, address registrantToSubscribe) external;
    function unsubscribe(address registrant, bool copyExistingEntries) external;
    function subscriptionOf(address addr) external returns (address registrant);
    function subscribers(address registrant) external returns (address[] memory);
    function subscriberAt(address registrant, uint256 index) external returns (address);
    function copyEntriesOf(address registrant, address registrantToCopy) external;
    function isOperatorFiltered(address registrant, address operator) external returns (bool);
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);
    function filteredOperators(address addr) external returns (address[] memory);
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);
    function isRegistered(address addr) external returns (bool);
    function codeHashOf(address addr) external returns (bytes32);
}

File 6 of 14: OperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol";

/**
 * @title  OperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry.
 * @dev    This smart contract is meant to be inherited by token contracts so they can use the following:
 *         - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
 *         - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
 */
abstract contract OperatorFilterer {
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

    constructor(address subscriptionOrRegistrantToCopy, bool subscribe) {
        // If an inheriting token contract is deployed to a network without the registry deployed, the modifier
        // will not revert, but the contract will need to be registered with the registry once it is deployed in
        // order for the modifier to filter addresses.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            if (subscribe) {
                OPERATOR_FILTER_REGISTRY.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
            } else {
                if (subscriptionOrRegistrantToCopy != address(0)) {
                    OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
                } else {
                    OPERATOR_FILTER_REGISTRY.register(address(this));
                }
            }
        }
    }

    modifier onlyAllowedOperator(address from) virtual {
        // Allow spending tokens from addresses with balance
        // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
        // from an EOA.
        if (from != msg.sender) {
            _checkFilterOperator(msg.sender);
        }
        _;
    }

    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    function _checkFilterOperator(address operator) internal view virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) {
                revert OperatorNotAllowed(operator);
            }
        }
    }
}

File 7 of 14: OperatorFilterRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol";
import {Ownable} from "./Ownable.sol";
import {EnumerableSet} from "./EnumerableSet.sol";
import {OperatorFilterRegistryErrorsAndEvents} from "./OperatorFilterRegistryErrorsAndEvents.sol";

/**
 * @title  OperatorFilterRegistry
 * @notice Borrows heavily from the QQL BlacklistOperatorFilter contract:
 *         https://github.com/qql-art/contracts/blob/main/contracts/BlacklistOperatorFilter.sol
 * @notice This contracts allows tokens or token owners to register specific addresses or codeHashes that may be
 * *       restricted according to the isOperatorAllowed function.
 */
contract OperatorFilterRegistry is IOperatorFilterRegistry, OperatorFilterRegistryErrorsAndEvents {
    using EnumerableSet for EnumerableSet.AddressSet;
    using EnumerableSet for EnumerableSet.Bytes32Set;

    /// @dev initialized accounts have a nonzero codehash (see https://eips.ethereum.org/EIPS/eip-1052)
    /// Note that this will also be a smart contract's codehash when making calls from its constructor.
    bytes32 constant EOA_CODEHASH = keccak256("");

    mapping(address => EnumerableSet.AddressSet) private _filteredOperators;
    mapping(address => EnumerableSet.Bytes32Set) private _filteredCodeHashes;
    mapping(address => address) private _registrations;
    mapping(address => EnumerableSet.AddressSet) private _subscribers;

    /**
     * @notice restricts method caller to the address or EIP-173 "owner()"
     */
    modifier onlyAddressOrOwner(address addr) {
        if (msg.sender != addr) {
            try Ownable(addr).owner() returns (address owner) {
                if (msg.sender != owner) {
                    revert OnlyAddressOrOwner();
                }
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert NotOwnable();
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        }
        _;
    }

    /**
     * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns
     *         true if supplied registrant address is not registered.
     */
    function isOperatorAllowed(address registrant, address operator) external view returns (bool) {
        address registration = _registrations[registrant];
        if (registration != address(0)) {
            EnumerableSet.AddressSet storage filteredOperatorsRef;
            EnumerableSet.Bytes32Set storage filteredCodeHashesRef;

            filteredOperatorsRef = _filteredOperators[registration];
            filteredCodeHashesRef = _filteredCodeHashes[registration];

            if (filteredOperatorsRef.contains(operator)) {
                revert AddressFiltered(operator);
            }
            if (operator.code.length > 0) {
                bytes32 codeHash = operator.codehash;
                if (filteredCodeHashesRef.contains(codeHash)) {
                    revert CodeHashFiltered(operator, codeHash);
                }
            }
        }
        return true;
    }

    //////////////////
    // AUTH METHODS //
    //////////////////

    /**
     * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.
     */
    function register(address registrant) external onlyAddressOrOwner(registrant) {
        if (_registrations[registrant] != address(0)) {
            revert AlreadyRegistered();
        }
        _registrations[registrant] = registrant;
        emit RegistrationUpdated(registrant, true);
    }

    /**
     * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.
     *         Note that this does not remove any filtered addresses or codeHashes.
     *         Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.
     */
    function unregister(address registrant) external onlyAddressOrOwner(registrant) {
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            _subscribers[registration].remove(registrant);
            emit SubscriptionUpdated(registrant, registration, false);
        }
        _registrations[registrant] = address(0);
        emit RegistrationUpdated(registrant, false);
    }

    /**
     * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes.
     */
    function registerAndSubscribe(address registrant, address subscription) external onlyAddressOrOwner(registrant) {
        address registration = _registrations[registrant];
        if (registration != address(0)) {
            revert AlreadyRegistered();
        }
        if (registrant == subscription) {
            revert CannotSubscribeToSelf();
        }
        address subscriptionRegistration = _registrations[subscription];
        if (subscriptionRegistration == address(0)) {
            revert NotRegistered(subscription);
        }
        if (subscriptionRegistration != subscription) {
            revert CannotSubscribeToRegistrantWithSubscription(subscription);
        }

        _registrations[registrant] = subscription;
        _subscribers[subscription].add(registrant);
        emit RegistrationUpdated(registrant, true);
        emit SubscriptionUpdated(registrant, subscription, true);
    }

    /**
     * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another
     *         address without subscribing.
     */
    function registerAndCopyEntries(address registrant, address registrantToCopy)
        external
        onlyAddressOrOwner(registrant)
    {
        if (registrantToCopy == registrant) {
            revert CannotCopyFromSelf();
        }
        address registration = _registrations[registrant];
        if (registration != address(0)) {
            revert AlreadyRegistered();
        }
        address registrantRegistration = _registrations[registrantToCopy];
        if (registrantRegistration == address(0)) {
            revert NotRegistered(registrantToCopy);
        }
        _registrations[registrant] = registrant;
        emit RegistrationUpdated(registrant, true);
        _copyEntries(registrant, registrantToCopy);
    }

    /**
     * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.
     */
    function updateOperator(address registrant, address operator, bool filtered)
        external
        onlyAddressOrOwner(registrant)
    {
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            revert CannotUpdateWhileSubscribed(registration);
        }
        EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant];

        if (!filtered) {
            bool removed = filteredOperatorsRef.remove(operator);
            if (!removed) {
                revert AddressNotFiltered(operator);
            }
        } else {
            bool added = filteredOperatorsRef.add(operator);
            if (!added) {
                revert AddressAlreadyFiltered(operator);
            }
        }
        emit OperatorUpdated(registrant, operator, filtered);
    }

    /**
     * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.
     */
    function updateCodeHash(address registrant, bytes32 codeHash, bool filtered)
        external
        onlyAddressOrOwner(registrant)
    {
        if (codeHash == EOA_CODEHASH) {
            revert CannotFilterEOAs();
        }
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            revert CannotUpdateWhileSubscribed(registration);
        }
        EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant];

        if (!filtered) {
            bool removed = filteredCodeHashesRef.remove(codeHash);
            if (!removed) {
                revert CodeHashNotFiltered(codeHash);
            }
        } else {
            bool added = filteredCodeHashesRef.add(codeHash);
            if (!added) {
                revert CodeHashAlreadyFiltered(codeHash);
            }
        }
        emit CodeHashUpdated(registrant, codeHash, filtered);
    }

    /**
     * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.
     */
    function updateOperators(address registrant, address[] calldata operators, bool filtered)
        external
        onlyAddressOrOwner(registrant)
    {
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            revert CannotUpdateWhileSubscribed(registration);
        }
        EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant];
        uint256 operatorsLength = operators.length;
        unchecked {
            if (!filtered) {
                for (uint256 i = 0; i < operatorsLength; ++i) {
                    address operator = operators[i];
                    bool removed = filteredOperatorsRef.remove(operator);
                    if (!removed) {
                        revert AddressNotFiltered(operator);
                    }
                }
            } else {
                for (uint256 i = 0; i < operatorsLength; ++i) {
                    address operator = operators[i];
                    bool added = filteredOperatorsRef.add(operator);
                    if (!added) {
                        revert AddressAlreadyFiltered(operator);
                    }
                }
            }
        }
        emit OperatorsUpdated(registrant, operators, filtered);
    }

    /**
     * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.
     */
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered)
        external
        onlyAddressOrOwner(registrant)
    {
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            revert CannotUpdateWhileSubscribed(registration);
        }
        EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant];
        uint256 codeHashesLength = codeHashes.length;
        unchecked {
            if (!filtered) {
                for (uint256 i = 0; i < codeHashesLength; ++i) {
                    bytes32 codeHash = codeHashes[i];
                    bool removed = filteredCodeHashesRef.remove(codeHash);
                    if (!removed) {
                        revert CodeHashNotFiltered(codeHash);
                    }
                }
            } else {
                for (uint256 i = 0; i < codeHashesLength; ++i) {
                    bytes32 codeHash = codeHashes[i];
                    if (codeHash == EOA_CODEHASH) {
                        revert CannotFilterEOAs();
                    }
                    bool added = filteredCodeHashesRef.add(codeHash);
                    if (!added) {
                        revert CodeHashAlreadyFiltered(codeHash);
                    }
                }
            }
        }
        emit CodeHashesUpdated(registrant, codeHashes, filtered);
    }

    /**
     * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous
     *         subscription if present.
     *         Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,
     *         subscriptions will not be forwarded. Instead the former subscription's existing entries will still be
     *         used.
     */
    function subscribe(address registrant, address newSubscription) external onlyAddressOrOwner(registrant) {
        if (registrant == newSubscription) {
            revert CannotSubscribeToSelf();
        }
        if (newSubscription == address(0)) {
            revert CannotSubscribeToZeroAddress();
        }
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration == newSubscription) {
            revert AlreadySubscribed(newSubscription);
        }
        address newSubscriptionRegistration = _registrations[newSubscription];
        if (newSubscriptionRegistration == address(0)) {
            revert NotRegistered(newSubscription);
        }
        if (newSubscriptionRegistration != newSubscription) {
            revert CannotSubscribeToRegistrantWithSubscription(newSubscription);
        }

        if (registration != registrant) {
            _subscribers[registration].remove(registrant);
            emit SubscriptionUpdated(registrant, registration, false);
        }
        _registrations[registrant] = newSubscription;
        _subscribers[newSubscription].add(registrant);
        emit SubscriptionUpdated(registrant, newSubscription, true);
    }

    /**
     * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.
     */
    function unsubscribe(address registrant, bool copyExistingEntries) external onlyAddressOrOwner(registrant) {
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration == registrant) {
            revert NotSubscribed();
        }
        _subscribers[registration].remove(registrant);
        _registrations[registrant] = registrant;
        emit SubscriptionUpdated(registrant, registration, false);
        if (copyExistingEntries) {
            _copyEntries(registrant, registration);
        }
    }

    /**
     * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.
     */
    function copyEntriesOf(address registrant, address registrantToCopy) external onlyAddressOrOwner(registrant) {
        if (registrant == registrantToCopy) {
            revert CannotCopyFromSelf();
        }
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            revert CannotUpdateWhileSubscribed(registration);
        }
        address registrantRegistration = _registrations[registrantToCopy];
        if (registrantRegistration == address(0)) {
            revert NotRegistered(registrantToCopy);
        }
        _copyEntries(registrant, registrantToCopy);
    }

    /// @dev helper to copy entries from registrantToCopy to registrant and emit events
    function _copyEntries(address registrant, address registrantToCopy) private {
        EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrantToCopy];
        EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrantToCopy];
        uint256 filteredOperatorsLength = filteredOperatorsRef.length();
        uint256 filteredCodeHashesLength = filteredCodeHashesRef.length();
        unchecked {
            for (uint256 i = 0; i < filteredOperatorsLength; ++i) {
                address operator = filteredOperatorsRef.at(i);
                bool added = _filteredOperators[registrant].add(operator);
                if (added) {
                    emit OperatorUpdated(registrant, operator, true);
                }
            }
            for (uint256 i = 0; i < filteredCodeHashesLength; ++i) {
                bytes32 codehash = filteredCodeHashesRef.at(i);
                bool added = _filteredCodeHashes[registrant].add(codehash);
                if (added) {
                    emit CodeHashUpdated(registrant, codehash, true);
                }
            }
        }
    }

    //////////////////
    // VIEW METHODS //
    //////////////////

    /**
     * @notice Get the subscription address of a given registrant, if any.
     */
    function subscriptionOf(address registrant) external view returns (address subscription) {
        subscription = _registrations[registrant];
        if (subscription == address(0)) {
            revert NotRegistered(registrant);
        } else if (subscription == registrant) {
            subscription = address(0);
        }
    }

    /**
     * @notice Get the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscribers(address registrant) external view returns (address[] memory) {
        return _subscribers[registrant].values();
    }

    /**
     * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscriberAt(address registrant, uint256 index) external view returns (address) {
        return _subscribers[registrant].at(index);
    }

    /**
     * @notice Returns true if operator is filtered by a given address or its subscription.
     */
    function isOperatorFiltered(address registrant, address operator) external view returns (bool) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredOperators[registration].contains(operator);
        }
        return _filteredOperators[registrant].contains(operator);
    }

    /**
     * @notice Returns true if a codeHash is filtered by a given address or its subscription.
     */
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external view returns (bool) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredCodeHashes[registration].contains(codeHash);
        }
        return _filteredCodeHashes[registrant].contains(codeHash);
    }

    /**
     * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.
     */
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external view returns (bool) {
        bytes32 codeHash = operatorWithCode.codehash;
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredCodeHashes[registration].contains(codeHash);
        }
        return _filteredCodeHashes[registrant].contains(codeHash);
    }

    /**
     * @notice Returns true if an address has registered
     */
    function isRegistered(address registrant) external view returns (bool) {
        return _registrations[registrant] != address(0);
    }

    /**
     * @notice Returns a list of filtered operators for a given address or its subscription.
     */
    function filteredOperators(address registrant) external view returns (address[] memory) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredOperators[registration].values();
        }
        return _filteredOperators[registrant].values();
    }

    /**
     * @notice Returns the set of filtered codeHashes for a given address or its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashes(address registrant) external view returns (bytes32[] memory) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredCodeHashes[registration].values();
        }
        return _filteredCodeHashes[registrant].values();
    }

    /**
     * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredOperatorAt(address registrant, uint256 index) external view returns (address) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredOperators[registration].at(index);
        }
        return _filteredOperators[registrant].at(index);
    }

    /**
     * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashAt(address registrant, uint256 index) external view returns (bytes32) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredCodeHashes[registration].at(index);
        }
        return _filteredCodeHashes[registrant].at(index);
    }

    /// @dev Convenience method to compute the code hash of an arbitrary contract
    function codeHashOf(address a) external view returns (bytes32) {
        return a.codehash;
    }
}

File 8 of 14: OperatorFilterRegistryErrorsAndEvents.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

contract OperatorFilterRegistryErrorsAndEvents {
    error CannotFilterEOAs();
    error AddressAlreadyFiltered(address operator);
    error AddressNotFiltered(address operator);
    error CodeHashAlreadyFiltered(bytes32 codeHash);
    error CodeHashNotFiltered(bytes32 codeHash);
    error OnlyAddressOrOwner();
    error NotRegistered(address registrant);
    error AlreadyRegistered();
    error AlreadySubscribed(address subscription);
    error NotSubscribed();
    error CannotUpdateWhileSubscribed(address subscription);
    error CannotSubscribeToSelf();
    error CannotSubscribeToZeroAddress();
    error NotOwnable();
    error AddressFiltered(address filtered);
    error CodeHashFiltered(address account, bytes32 codeHash);
    error CannotSubscribeToRegistrantWithSubscription(address registrant);
    error CannotCopyFromSelf();

    event RegistrationUpdated(address indexed registrant, bool indexed registered);
    event OperatorUpdated(address indexed registrant, address indexed operator, bool indexed filtered);
    event OperatorsUpdated(address indexed registrant, address[] operators, bool indexed filtered);
    event CodeHashUpdated(address indexed registrant, bytes32 indexed codeHash, bool indexed filtered);
    event CodeHashesUpdated(address indexed registrant, bytes32[] codeHashes, bool indexed filtered);
    event SubscriptionUpdated(address indexed registrant, address indexed subscription, bool indexed subscribed);
}

File 9 of 14: Ownable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {Context} from "./Context.sol";

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

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

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

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

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

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

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

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

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

File 10 of 14: Ownable2Step.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./Ownable.sol";

/**
 * @dev Contract module which provides access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership} and {acceptOwnership}.
 *
 * This module is used through inheritance. It will make available all functions
 * from parent (Ownable).
 */
abstract contract Ownable2Step is Ownable {
    address private _pendingOwner;

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

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

    /**
     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner)
        public
        virtual
        override
        onlyOwner
    {
        _pendingOwner = newOwner;
        emit OwnershipTransferStarted(owner(), newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual override {
        delete _pendingOwner;
        super._transferOwnership(newOwner);
    }

    /**
     * @dev The new owner accepts the ownership transfer.
     */
    function acceptOwnership() external {
        address sender = _msgSender();
        require(
            pendingOwner() == sender,
            "Ownable2Step: caller is not the new owner"
        );
        _transferOwnership(sender);
    }
}

File 11 of 14: OwnedRegistrant.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol";
import {Ownable2Step} from "./Ownable2Step.sol";
/**
 * @title  OwnedRegistrant
 * @notice Ownable contract that registers itself with the OperatorFilterRegistry and administers its own entries,
 *         to facilitate a subscription whose ownership can be transferred.
 */
contract OwnedRegistrant is Ownable2Step {
    address constant registry = 0x000000000000AAeB6D7670E522A718067333cd4E;

    constructor(address _owner) {
        IOperatorFilterRegistry(registry).register(address(this));
        transferOwnership(_owner);
    }
}

File 12 of 14: RevokableDefaultOperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {RevokableOperatorFilterer} from "./RevokableOperatorFilterer.sol";

/**
 * @title  RevokableDefaultOperatorFilterer
 * @notice Inherits from RevokableOperatorFilterer and automatically subscribes to the default OpenSea subscription.
 *         Note that OpenSea will disable creator fee enforcement if filtered operators begin fulfilling orders
 *         on-chain, eg, if the registry is revoked or bypassed.
 */
abstract contract RevokableDefaultOperatorFilterer is RevokableOperatorFilterer {
    address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

    constructor() RevokableOperatorFilterer(0x000000000000AAeB6D7670E522A718067333cd4E, DEFAULT_SUBSCRIPTION, true) {}
}

File 13 of 14: RevokableOperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {UpdatableOperatorFilterer} from "./UpdatableOperatorFilterer.sol";
import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol";

/**
 * @title  RevokableOperatorFilterer
 * @notice This contract is meant to allow contracts to permanently skip OperatorFilterRegistry checks if desired. The
 *         Registry itself has an "unregister" function, but if the contract is ownable, the owner can re-register at
 *         any point. As implemented, this abstract contract allows the contract owner to permanently skip the
 *         OperatorFilterRegistry checks by calling revokeOperatorFilterRegistry. Once done, the registry
 *         address cannot be further updated.
 *         Note that OpenSea will still disable creator fee enforcement if filtered operators begin fulfilling orders
 *         on-chain, eg, if the registry is revoked or bypassed.
 */
abstract contract RevokableOperatorFilterer is UpdatableOperatorFilterer {
    error RegistryHasBeenRevoked();
    error InitialRegistryAddressCannotBeZeroAddress();

    bool public isOperatorFilterRegistryRevoked;

    constructor(address _registry, address subscriptionOrRegistrantToCopy, bool subscribe)
        UpdatableOperatorFilterer(_registry, subscriptionOrRegistrantToCopy, subscribe)
    {
        // don't allow creating a contract with a permanently revoked registry
        if (_registry == address(0)) {
            revert InitialRegistryAddressCannotBeZeroAddress();
        }
    }

    function _checkFilterOperator(address operator) internal view virtual override {
        if (address(operatorFilterRegistry) != address(0)) {
            super._checkFilterOperator(operator);
        }
    }

    /**
     * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero
     *         address, checks will be permanently bypassed, and the address cannot be updated again. OnlyOwner.
     */
    function updateOperatorFilterRegistryAddress(address newRegistry) public override {
        if (msg.sender != owner()) {
            revert OnlyOwner();
        }
        // if registry has been revoked, do not allow further updates
        if (isOperatorFilterRegistryRevoked) {
            revert RegistryHasBeenRevoked();
        }

        operatorFilterRegistry = IOperatorFilterRegistry(newRegistry);
    }

    /**
     * @notice Revoke the OperatorFilterRegistry address, permanently bypassing checks. OnlyOwner.
     */
    function revokeOperatorFilterRegistry() public {
        if (msg.sender != owner()) {
            revert OnlyOwner();
        }
        // if registry has been revoked, do not allow further updates
        if (isOperatorFilterRegistryRevoked) {
            revert RegistryHasBeenRevoked();
        }

        // set to zero address to bypass checks
        operatorFilterRegistry = IOperatorFilterRegistry(address(0));
        isOperatorFilterRegistryRevoked = true;
    }
}

File 14 of 14: UpdatableOperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol";

/**
 * @title  UpdatableOperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry. This contract allows the Owner to update the
 *         OperatorFilterRegistry address via updateOperatorFilterRegistryAddress, including to the zero address,
 *         which will bypass registry checks.
 *         Note that OpenSea will still disable creator fee enforcement if filtered operators begin fulfilling orders
 *         on-chain, eg, if the registry is revoked or bypassed.
 * @dev    This smart contract is meant to be inherited by token contracts so they can use the following:
 *         - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
 *         - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
 */
abstract contract UpdatableOperatorFilterer {
    error OperatorNotAllowed(address operator);
    error OnlyOwner();

    IOperatorFilterRegistry public operatorFilterRegistry;

    constructor(address _registry, address subscriptionOrRegistrantToCopy, bool subscribe) {
        IOperatorFilterRegistry registry = IOperatorFilterRegistry(_registry);
        operatorFilterRegistry = registry;
        // If an inheriting token contract is deployed to a network without the registry deployed, the modifier
        // will not revert, but the contract will need to be registered with the registry once it is deployed in
        // order for the modifier to filter addresses.
        if (address(registry).code.length > 0) {
            if (subscribe) {
                registry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
            } else {
                if (subscriptionOrRegistrantToCopy != address(0)) {
                    registry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
                } else {
                    registry.register(address(this));
                }
            }
        }
    }

    modifier onlyAllowedOperator(address from) virtual {
        // Allow spending tokens from addresses with balance
        // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
        // from an EOA.
        if (from != msg.sender) {
            _checkFilterOperator(msg.sender);
        }
        _;
    }

    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    /**
     * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero
     *         address, checks will be bypassed. OnlyOwner.
     */
    function updateOperatorFilterRegistryAddress(address newRegistry) public virtual {
        if (msg.sender != owner()) {
            revert OnlyOwner();
        }
        operatorFilterRegistry = IOperatorFilterRegistry(newRegistry);
    }

    /**
     * @dev assume the contract has an owner, but leave specific Ownable implementation up to inheriting contract
     */
    function owner() public view virtual returns (address);

    function _checkFilterOperator(address operator) internal view virtual {
        IOperatorFilterRegistry registry = operatorFilterRegistry;
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(registry) != address(0) && address(registry).code.length > 0) {
            if (!registry.isOperatorAllowed(address(this), operator)) {
                revert OperatorNotAllowed(operator);
            }
        }
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_PER_Transaction","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PER_WALLET","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PER_WL_TRANSACTION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PhaseCollectionSize_","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sendTo","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"q","type":"uint256"}],"name":"changeMAX_PER_Transaction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"q","type":"uint256"}],"name":"changeMAX_PER_WALLET","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"q","type":"uint256"}],"name":"changeMAX_PER_WL_TRANSACTION","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"changeMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_collection","type":"uint256"}],"name":"changePhaseCollectionSize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"changeRevealStatus","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":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getOwnershipData","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"}],"internalType":"struct ERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStatus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"getWhitelistPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"address","name":"_owner","type":"address"}],"name":"inWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"itemPriceWhiteList","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":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"publicClaimedBy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_howMany","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"purchaseWhiteListTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_itemPriceWhiteList","type":"uint256"}],"name":"setPriceWhiteList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"s","type":"uint256"}],"name":"setStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"URI","type":"string"}],"name":"setURIbeforeReveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_whiteListCollection","type":"uint256"}],"name":"setWLavailable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_whiteListPerWallet","type":"uint256"}],"name":"setWhiteListPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_whitelistMerkleRoot","type":"bytes32"}],"name":"setWhitelistMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"status","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whiteListClaimedBy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whiteListPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawMoney","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052600a8055600a600b55662386f26fc10000600c55610477600d556000600e556000601160006101000a81548160ff0219169083151502179055506004601355600460145560006016556104776017553480156200006057600080fd5b50733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600a81526020017f417274617869614e4654000000000000000000000000000000000000000000008152506040518060400160405280600581526020017f415254415800000000000000000000000000000000000000000000000000000081525062000104620000f86200034560201b60201c565b6200034d60201b60201c565b816003908162000115919062000694565b50806004908162000127919062000694565b50620001386200041160201b60201c565b6001819055505050600160098190555060006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156200033d57801562000203576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b8152600401620001c9929190620007c0565b600060405180830381600087803b158015620001e457600080fd5b505af1158015620001f9573d6000803e3d6000fd5b505050506200033c565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614620002bd576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b815260040162000283929190620007c0565b600060405180830381600087803b1580156200029e57600080fd5b505af1158015620002b3573d6000803e3d6000fd5b505050506200033b565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b8152600401620003069190620007ed565b600060405180830381600087803b1580156200032157600080fd5b505af115801562000336573d6000803e3d6000fd5b505050505b5b5b50506200080a565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006001905090565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200049c57607f821691505b602082108103620004b257620004b162000454565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026200051c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620004dd565b620005288683620004dd565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620005756200056f620005698462000540565b6200054a565b62000540565b9050919050565b6000819050919050565b620005918362000554565b620005a9620005a0826200057c565b848454620004ea565b825550505050565b600090565b620005c0620005b1565b620005cd81848462000586565b505050565b5b81811015620005f557620005e9600082620005b6565b600181019050620005d3565b5050565b601f82111562000644576200060e81620004b8565b6200061984620004cd565b8101602085101562000629578190505b620006416200063885620004cd565b830182620005d2565b50505b505050565b600082821c905092915050565b6000620006696000198460080262000649565b1980831691505092915050565b600062000684838362000656565b9150826002028217905092915050565b6200069f826200041a565b67ffffffffffffffff811115620006bb57620006ba62000425565b5b620006c7825462000483565b620006d4828285620005f9565b600060209050601f8311600181146200070c5760008415620006f7578287015190505b62000703858262000676565b86555062000773565b601f1984166200071c86620004b8565b60005b8281101562000746578489015182556001820191506020850194506020810190506200071f565b8683101562000766578489015162000762601f89168262000656565b8355505b6001600288020188555050505b505050505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620007a8826200077b565b9050919050565b620007ba816200079b565b82525050565b6000604082019050620007d76000830185620007af565b620007e66020830184620007af565b9392505050565b6000602082019050620008046000830184620007af565b92915050565b615441806200081a6000396000f3fe60806040526004361061031a5760003560e01c8063852cbaee116101ab578063aebceff4116100f7578063dc33e68111610095578063e7d61da81161006f578063e7d61da814610bb6578063e8006bb014610be1578063e985e9c514610c0a578063f2fde38b14610c475761031a565b8063dc33e68114610aff578063e5ec56a014610b3c578063e757223014610b795761031a565b8063bd32fb66116100d1578063bd32fb6614610a47578063c49e806214610a70578063c7b8fca714610a99578063c87b56dd14610ac25761031a565b8063aebceff4146109b6578063b333ca91146109f3578063b88d4fde14610a1e5761031a565b806395d89b4111610164578063a40ece7a1161013e578063a40ece7a14610922578063a5cdae2d1461094b578063aa98e0c614610974578063ac4460021461099f5761031a565b806395d89b41146108b2578063a0712d68146108dd578063a22cb465146108f95761031a565b8063852cbaee146107a25780638825b014146107cd5780638ba4cc3c146107f65780638d859f3e1461081f5780638da5cb5b1461084a5780639231ab2a146108755761031a565b80633461ea431161026a57806351d7ff931161022357806369ba1a75116101fd57806369ba1a75146106e857806370a0823114610711578063715018a61461074e57806375236143146107655761031a565b806351d7ff931461065757806355f804b3146106825780636352211e146106ab5761031a565b80633461ea431461055b5780633fd173661461058457806341f43434146105ad57806342842e0e146105d85780634e69d56014610601578063518302271461062c5761031a565b806318160ddd116102d757806323b872dd116102b157806323b872dd146104c75780632632d5f8146104f05780632ba2865b1461051b5780632d5b005d146105445761031a565b806318160ddd146104345780631984b2861461045f578063200d2ed21461049c5761031a565b806301ffc9a71461031f57806306fdde031461035c578063081812fc14610387578063095ea7b3146103c45780630f2cdd6c146103ed57806310157fc314610418575b600080fd5b34801561032b57600080fd5b5061034660048036038101906103419190613b63565b610c70565b6040516103539190613bab565b60405180910390f35b34801561036857600080fd5b50610371610d52565b60405161037e9190613c56565b60405180910390f35b34801561039357600080fd5b506103ae60048036038101906103a99190613cae565b610de4565b6040516103bb9190613d1c565b60405180910390f35b3480156103d057600080fd5b506103eb60048036038101906103e69190613d63565b610e60565b005b3480156103f957600080fd5b50610402610e79565b60405161040f9190613db2565b60405180910390f35b610432600480360381019061042d9190613e32565b610e7f565b005b34801561044057600080fd5b50610449611123565b6040516104569190613db2565b60405180910390f35b34801561046b57600080fd5b5061048660048036038101906104819190613e92565b61113a565b6040516104939190613db2565b60405180910390f35b3480156104a857600080fd5b506104b1611152565b6040516104be9190613db2565b60405180910390f35b3480156104d357600080fd5b506104ee60048036038101906104e99190613ebf565b611158565b005b3480156104fc57600080fd5b506105056111a7565b6040516105129190613db2565b60405180910390f35b34801561052757600080fd5b50610542600480360381019061053d9190613cae565b6111ad565b005b34801561055057600080fd5b50610559611233565b005b34801561056757600080fd5b50610582600480360381019061057d9190613cae565b6112cc565b005b34801561059057600080fd5b506105ab60048036038101906105a69190613cae565b611352565b005b3480156105b957600080fd5b506105c26113d8565b6040516105cf9190613f71565b60405180910390f35b3480156105e457600080fd5b506105ff60048036038101906105fa9190613ebf565b6113ea565b005b34801561060d57600080fd5b50610616611439565b6040516106239190613db2565b60405180910390f35b34801561063857600080fd5b50610641611443565b60405161064e9190613bab565b60405180910390f35b34801561066357600080fd5b5061066c611456565b6040516106799190613db2565b60405180910390f35b34801561068e57600080fd5b506106a960048036038101906106a491906140bc565b61145c565b005b3480156106b757600080fd5b506106d260048036038101906106cd9190613cae565b6114eb565b6040516106df9190613d1c565b60405180910390f35b3480156106f457600080fd5b5061070f600480360381019061070a9190613cae565b611501565b005b34801561071d57600080fd5b5061073860048036038101906107339190613e92565b611587565b6040516107459190613db2565b60405180910390f35b34801561075a57600080fd5b50610763611656565b005b34801561077157600080fd5b5061078c60048036038101906107879190613e92565b6116de565b6040516107999190613db2565b60405180910390f35b3480156107ae57600080fd5b506107b76116f6565b6040516107c49190613db2565b60405180910390f35b3480156107d957600080fd5b506107f460048036038101906107ef9190613cae565b6116fc565b005b34801561080257600080fd5b5061081d60048036038101906108189190613d63565b611782565b005b34801561082b57600080fd5b50610834611863565b6040516108419190613db2565b60405180910390f35b34801561085657600080fd5b5061085f611869565b60405161086c9190613d1c565b60405180910390f35b34801561088157600080fd5b5061089c60048036038101906108979190613cae565b611892565b6040516108a99190614188565b60405180910390f35b3480156108be57600080fd5b506108c76118aa565b6040516108d49190613c56565b60405180910390f35b6108f760048036038101906108f29190613cae565b61193c565b005b34801561090557600080fd5b50610920600480360381019061091b91906141cf565b611c19565b005b34801561092e57600080fd5b5061094960048036038101906109449190613cae565b611c32565b005b34801561095757600080fd5b50610972600480360381019061096d9190613cae565b611cb8565b005b34801561098057600080fd5b50610989611d3e565b6040516109969190614228565b60405180910390f35b3480156109ab57600080fd5b506109b4611d44565b005b3480156109c257600080fd5b506109dd60048036038101906109d89190613cae565b611ec4565b6040516109ea9190613db2565b60405180910390f35b3480156109ff57600080fd5b50610a08611edb565b604051610a159190613db2565b60405180910390f35b348015610a2a57600080fd5b50610a456004803603810190610a4091906142e4565b611ee1565b005b348015610a5357600080fd5b50610a6e6004803603810190610a699190614393565b611f32565b005b348015610a7c57600080fd5b50610a976004803603810190610a929190613cae565b611fb8565b005b348015610aa557600080fd5b50610ac06004803603810190610abb91906140bc565b61203e565b005b348015610ace57600080fd5b50610ae96004803603810190610ae49190613cae565b6120cd565b604051610af69190613c56565b60405180910390f35b348015610b0b57600080fd5b50610b266004803603810190610b219190613e92565b612222565b604051610b339190613db2565b60405180910390f35b348015610b4857600080fd5b50610b636004803603810190610b5e9190614483565b612234565b604051610b709190613bab565b60405180910390f35b348015610b8557600080fd5b50610ba06004803603810190610b9b9190613cae565b612271565b604051610bad9190613db2565b60405180910390f35b348015610bc257600080fd5b50610bcb612288565b604051610bd89190613db2565b60405180910390f35b348015610bed57600080fd5b50610c086004803603810190610c039190613cae565b61228e565b005b348015610c1657600080fd5b50610c316004803603810190610c2c91906144df565b612314565b604051610c3e9190613bab565b60405180910390f35b348015610c5357600080fd5b50610c6e6004803603810190610c699190613e92565b6123a8565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610d3b57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610d4b5750610d4a8261249f565b5b9050919050565b606060038054610d619061454e565b80601f0160208091040260200160405190810160405280929190818152602001828054610d8d9061454e565b8015610dda5780601f10610daf57610100808354040283529160200191610dda565b820191906000526020600020905b815481529060010190602001808311610dbd57829003601f168201915b5050505050905090565b6000610def82612509565b610e25576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610e6a81612557565b610e748383612654565b505050565b600b5481565b6001600e5414610ec4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ebb906145cb565b60405180910390fd5b60175483610ed0611123565b610eda919061461a565b1115610f1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f12906146c0565b60405180910390fd5b610f66828280806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505033612234565b610fa5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f9c9061472c565b60405180910390fd5b60165483610fb3919061474c565b341015610ff5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fec906147da565b60405180910390fd5b60145483111561103a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103190614846565b60405180910390fd5b82601860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611089919061461a565b92505081905550601354601860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115611114576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110b906148b2565b60405180910390fd5b61111e338461275e565b505050565b600061112d61277c565b6002546001540303905090565b60186020528060005260406000206000915090505481565b600e5481565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146111965761119533612557565b5b6111a1848484612785565b50505050565b60165481565b6111b5612795565b73ffffffffffffffffffffffffffffffffffffffff166111d3611869565b73ffffffffffffffffffffffffffffffffffffffff1614611229576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112209061491e565b60405180910390fd5b80600b8190555050565b61123b612795565b73ffffffffffffffffffffffffffffffffffffffff16611259611869565b73ffffffffffffffffffffffffffffffffffffffff16146112af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112a69061491e565b60405180910390fd5b6001601160006101000a81548160ff021916908315150217905550565b6112d4612795565b73ffffffffffffffffffffffffffffffffffffffff166112f2611869565b73ffffffffffffffffffffffffffffffffffffffff1614611348576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133f9061491e565b60405180910390fd5b80600d8190555050565b61135a612795565b73ffffffffffffffffffffffffffffffffffffffff16611378611869565b73ffffffffffffffffffffffffffffffffffffffff16146113ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113c59061491e565b60405180910390fd5b80600c8190555050565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146114285761142733612557565b5b61143384848461279d565b50505050565b6000600e54905090565b601160009054906101000a900460ff1681565b600a5481565b611464612795565b73ffffffffffffffffffffffffffffffffffffffff16611482611869565b73ffffffffffffffffffffffffffffffffffffffff16146114d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114cf9061491e565b60405180910390fd5b80600f90816114e79190614ae0565b5050565b60006114f6826127bd565b600001519050919050565b611509612795565b73ffffffffffffffffffffffffffffffffffffffff16611527611869565b73ffffffffffffffffffffffffffffffffffffffff161461157d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115749061491e565b60405180910390fd5b80600e8190555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036115ee576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900467ffffffffffffffff1667ffffffffffffffff169050919050565b61165e612795565b73ffffffffffffffffffffffffffffffffffffffff1661167c611869565b73ffffffffffffffffffffffffffffffffffffffff16146116d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116c99061491e565b60405180910390fd5b6116dc6000612a4c565b565b60126020528060005260406000206000915090505481565b60135481565b611704612795565b73ffffffffffffffffffffffffffffffffffffffff16611722611869565b73ffffffffffffffffffffffffffffffffffffffff1614611778576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161176f9061491e565b60405180910390fd5b8060168190555050565b61178a612795565b73ffffffffffffffffffffffffffffffffffffffff166117a8611869565b73ffffffffffffffffffffffffffffffffffffffff16146117fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117f59061491e565b60405180910390fd5b6104778161180a611123565b611814919061461a565b1115611855576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161184c90614bfe565b60405180910390fd5b61185f828261275e565b5050565b600c5481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61189a613ab4565b6118a3826127bd565b9050919050565b6060600480546118b99061454e565b80601f01602080910402602001604051908101604052809291908181526020018280546118e59061454e565b80156119325780601f1061190757610100808354040283529160200191611932565b820191906000526020600020905b81548152906001019060200180831161191557829003601f168201915b5050505050905090565b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16146119aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a190614c6a565b60405180910390fd5b6002600e54146119ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e690614cd6565b60405180910390fd5b610477816119fb611123565b611a05919061461a565b1115611a46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a3d90614bfe565b60405180910390fd5b600d5481611a52611123565b611a5c919061461a565b1115611a9d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a9490614d42565b60405180910390fd5b600a54811115611ae2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ad990614846565b60405180910390fd5b80600c54611af0919061474c565b341015611b32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b2990614dae565b60405180910390fd5b80601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611b81919061461a565b92505081905550600b54601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115611c0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c03906148b2565b60405180910390fd5b611c16338261275e565b50565b81611c2381612557565b611c2d8383612b10565b505050565b611c3a612795565b73ffffffffffffffffffffffffffffffffffffffff16611c58611869565b73ffffffffffffffffffffffffffffffffffffffff1614611cae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ca59061491e565b60405180910390fd5b80600a8190555050565b611cc0612795565b73ffffffffffffffffffffffffffffffffffffffff16611cde611869565b73ffffffffffffffffffffffffffffffffffffffff1614611d34576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d2b9061491e565b60405180910390fd5b8060138190555050565b60155481565b611d4c612795565b73ffffffffffffffffffffffffffffffffffffffff16611d6a611869565b73ffffffffffffffffffffffffffffffffffffffff1614611dc0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611db79061491e565b60405180910390fd5b600260095403611e05576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dfc90614e1a565b60405180910390fd5b600260098190555060003373ffffffffffffffffffffffffffffffffffffffff1647604051611e3390614e6b565b60006040518083038185875af1925050503d8060008114611e70576040519150601f19603f3d011682016040523d82523d6000602084013e611e75565b606091505b5050905080611eb9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eb090614ecc565b60405180910390fd5b506001600981905550565b600060165482611ed4919061474c565b9050919050565b600d5481565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611f1f57611f1e33612557565b5b611f2b85858585612c87565b5050505050565b611f3a612795565b73ffffffffffffffffffffffffffffffffffffffff16611f58611869565b73ffffffffffffffffffffffffffffffffffffffff1614611fae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa59061491e565b60405180910390fd5b8060158190555050565b611fc0612795565b73ffffffffffffffffffffffffffffffffffffffff16611fde611869565b73ffffffffffffffffffffffffffffffffffffffff1614612034576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161202b9061491e565b60405180910390fd5b8060148190555050565b612046612795565b73ffffffffffffffffffffffffffffffffffffffff16612064611869565b73ffffffffffffffffffffffffffffffffffffffff16146120ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120b19061491e565b60405180910390fd5b80601090816120c99190614ae0565b5050565b60606120d882612509565b612117576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161210e90614f5e565b60405180910390fd5b60001515601160009054906101000a900460ff161515036121c4576010805461213f9061454e565b80601f016020809104026020016040519081016040528092919081815260200182805461216b9061454e565b80156121b85780601f1061218d576101008083540402835291602001916121b8565b820191906000526020600020905b81548152906001019060200180831161219b57829003601f168201915b5050505050905061221d565b60006121ce612d03565b905060008151116121ee5760405180602001604052806000815250612219565b806121f884612d95565b604051602001612209929190615052565b6040516020818303038152906040525b9150505b919050565b600061222d82612ef5565b9050919050565b6000612269836015548460405160200161224e91906150d4565b60405160208183030381529060405280519060200120612f5f565b905092915050565b6000600c5482612281919061474c565b9050919050565b60145481565b612296612795565b73ffffffffffffffffffffffffffffffffffffffff166122b4611869565b73ffffffffffffffffffffffffffffffffffffffff161461230a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123019061491e565b60405180910390fd5b8060178190555050565b6000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6123b0612795565b73ffffffffffffffffffffffffffffffffffffffff166123ce611869565b73ffffffffffffffffffffffffffffffffffffffff1614612424576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161241b9061491e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612493576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161248a90615161565b60405180910390fd5b61249c81612a4c565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008161251461277c565b11158015612523575060015482105b8015612550575060056000838152602001908152602001600020600001601c9054906101000a900460ff16155b9050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115612651576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016125ce929190615181565b602060405180830381865afa1580156125eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260f91906151bf565b61265057806040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016126479190613d1c565b60405180910390fd5b5b50565b600061265f826114eb565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036126c6576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166126e5612795565b73ffffffffffffffffffffffffffffffffffffffff1614158015612717575061271581612710612795565b612314565b155b1561274e576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612759838383612f76565b505050565b612778828260405180602001604052806000815250613028565b5050565b60006001905090565b61279083838361303a565b505050565b600033905090565b6127b883838360405180602001604052806000815250611ee1565b505050565b6127c5613ab4565b6000829050806127d361277c565b111580156127e2575060015481105b15612a15576000600560008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff16151515158152505090508060400151612a1357600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff16146128f7578092505050612a47565b5b600115612a1257818060019003925050600560008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff1615151515815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614612a0d578092505050612a47565b6128f8565b5b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b612b18612795565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612b7c576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060086000612b89612795565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612c36612795565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612c7b9190613bab565b60405180910390a35050565b612c9284848461303a565b612cb18373ffffffffffffffffffffffffffffffffffffffff166134ee565b8015612cc65750612cc484848484613501565b155b15612cfd576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6060600f8054612d129061454e565b80601f0160208091040260200160405190810160405280929190818152602001828054612d3e9061454e565b8015612d8b5780601f10612d6057610100808354040283529160200191612d8b565b820191906000526020600020905b815481529060010190602001808311612d6e57829003601f168201915b5050505050905090565b606060008203612ddc576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612ef0565b600082905060005b60008214612e0e578080612df7906151ec565b915050600a82612e079190615263565b9150612de4565b60008167ffffffffffffffff811115612e2a57612e29613f91565b5b6040519080825280601f01601f191660200182016040528015612e5c5781602001600182028036833780820191505090505b5090505b60008514612ee957600182612e759190615294565b9150600a85612e8491906152c8565b6030612e90919061461a565b60f81b818381518110612ea657612ea56152f9565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612ee29190615263565b9450612e60565b8093505050505b919050565b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160089054906101000a900467ffffffffffffffff1667ffffffffffffffff169050919050565b600082612f6c8584613651565b1490509392505050565b826007600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b61303583838360016136c6565b505050565b6000613045826127bd565b90508373ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff16146130b0576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff166130d1612795565b73ffffffffffffffffffffffffffffffffffffffff16148061310057506130ff856130fa612795565b612314565b5b80613145575061310e612795565b73ffffffffffffffffffffffffffffffffffffffff1661312d84610de4565b73ffffffffffffffffffffffffffffffffffffffff16145b90508061317e576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036131e4576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6131f18585856001613a91565b6131fd60008487612f76565b6001600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160392506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506001600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000600560008581526020019081526020016000209050848160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550428160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060006001850190506000600560008381526020019081526020016000209050600073ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361347c57600154821461347b57878160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084602001518160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b5b505050828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46134e78585856001613a97565b5050505050565b600080823b905060008111915050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613527612795565b8786866040518563ffffffff1660e01b8152600401613549949392919061537d565b6020604051808303816000875af192505050801561358557506040513d601f19601f8201168201806040525081019061358291906153de565b60015b6135fe573d80600081146135b5576040519150601f19603f3d011682016040523d82523d6000602084013e6135ba565b606091505b5060008151036135f6576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60008082905060005b84518110156136bb576000858281518110613678576136776152f9565b5b6020026020010151905080831161369a576136938382613a9d565b92506136a7565b6136a48184613a9d565b92505b5080806136b3906151ec565b91505061365a565b508091505092915050565b60006001549050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603613733576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000840361376d576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61377a6000868387613a91565b83600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555083600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160088282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550846005600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426005600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060008190506000858201905083801561394457506139438773ffffffffffffffffffffffffffffffffffffffff166134ee565b5b15613a09575b818773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46139b96000888480600101955088613501565b6139ef576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80820361394a578260015414613a0457600080fd5b613a74565b5b818060010192508773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4808203613a0a575b816001819055505050613a8a6000868387613a97565b5050505050565b50505050565b50505050565b600082600052816020526040600020905092915050565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff1681526020016000151581525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613b4081613b0b565b8114613b4b57600080fd5b50565b600081359050613b5d81613b37565b92915050565b600060208284031215613b7957613b78613b01565b5b6000613b8784828501613b4e565b91505092915050565b60008115159050919050565b613ba581613b90565b82525050565b6000602082019050613bc06000830184613b9c565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613c00578082015181840152602081019050613be5565b60008484015250505050565b6000601f19601f8301169050919050565b6000613c2882613bc6565b613c328185613bd1565b9350613c42818560208601613be2565b613c4b81613c0c565b840191505092915050565b60006020820190508181036000830152613c708184613c1d565b905092915050565b6000819050919050565b613c8b81613c78565b8114613c9657600080fd5b50565b600081359050613ca881613c82565b92915050565b600060208284031215613cc457613cc3613b01565b5b6000613cd284828501613c99565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613d0682613cdb565b9050919050565b613d1681613cfb565b82525050565b6000602082019050613d316000830184613d0d565b92915050565b613d4081613cfb565b8114613d4b57600080fd5b50565b600081359050613d5d81613d37565b92915050565b60008060408385031215613d7a57613d79613b01565b5b6000613d8885828601613d4e565b9250506020613d9985828601613c99565b9150509250929050565b613dac81613c78565b82525050565b6000602082019050613dc76000830184613da3565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112613df257613df1613dcd565b5b8235905067ffffffffffffffff811115613e0f57613e0e613dd2565b5b602083019150836020820283011115613e2b57613e2a613dd7565b5b9250929050565b600080600060408486031215613e4b57613e4a613b01565b5b6000613e5986828701613c99565b935050602084013567ffffffffffffffff811115613e7a57613e79613b06565b5b613e8686828701613ddc565b92509250509250925092565b600060208284031215613ea857613ea7613b01565b5b6000613eb684828501613d4e565b91505092915050565b600080600060608486031215613ed857613ed7613b01565b5b6000613ee686828701613d4e565b9350506020613ef786828701613d4e565b9250506040613f0886828701613c99565b9150509250925092565b6000819050919050565b6000613f37613f32613f2d84613cdb565b613f12565b613cdb565b9050919050565b6000613f4982613f1c565b9050919050565b6000613f5b82613f3e565b9050919050565b613f6b81613f50565b82525050565b6000602082019050613f866000830184613f62565b92915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613fc982613c0c565b810181811067ffffffffffffffff82111715613fe857613fe7613f91565b5b80604052505050565b6000613ffb613af7565b90506140078282613fc0565b919050565b600067ffffffffffffffff82111561402757614026613f91565b5b61403082613c0c565b9050602081019050919050565b82818337600083830152505050565b600061405f61405a8461400c565b613ff1565b90508281526020810184848401111561407b5761407a613f8c565b5b61408684828561403d565b509392505050565b600082601f8301126140a3576140a2613dcd565b5b81356140b384826020860161404c565b91505092915050565b6000602082840312156140d2576140d1613b01565b5b600082013567ffffffffffffffff8111156140f0576140ef613b06565b5b6140fc8482850161408e565b91505092915050565b61410e81613cfb565b82525050565b600067ffffffffffffffff82169050919050565b61413181614114565b82525050565b61414081613b90565b82525050565b60608201600082015161415c6000850182614105565b50602082015161416f6020850182614128565b5060408201516141826040850182614137565b50505050565b600060608201905061419d6000830184614146565b92915050565b6141ac81613b90565b81146141b757600080fd5b50565b6000813590506141c9816141a3565b92915050565b600080604083850312156141e6576141e5613b01565b5b60006141f485828601613d4e565b9250506020614205858286016141ba565b9150509250929050565b6000819050919050565b6142228161420f565b82525050565b600060208201905061423d6000830184614219565b92915050565b600067ffffffffffffffff82111561425e5761425d613f91565b5b61426782613c0c565b9050602081019050919050565b600061428761428284614243565b613ff1565b9050828152602081018484840111156142a3576142a2613f8c565b5b6142ae84828561403d565b509392505050565b600082601f8301126142cb576142ca613dcd565b5b81356142db848260208601614274565b91505092915050565b600080600080608085870312156142fe576142fd613b01565b5b600061430c87828801613d4e565b945050602061431d87828801613d4e565b935050604061432e87828801613c99565b925050606085013567ffffffffffffffff81111561434f5761434e613b06565b5b61435b878288016142b6565b91505092959194509250565b6143708161420f565b811461437b57600080fd5b50565b60008135905061438d81614367565b92915050565b6000602082840312156143a9576143a8613b01565b5b60006143b78482850161437e565b91505092915050565b600067ffffffffffffffff8211156143db576143da613f91565b5b602082029050602081019050919050565b60006143ff6143fa846143c0565b613ff1565b9050808382526020820190506020840283018581111561442257614421613dd7565b5b835b8181101561444b5780614437888261437e565b845260208401935050602081019050614424565b5050509392505050565b600082601f83011261446a57614469613dcd565b5b813561447a8482602086016143ec565b91505092915050565b6000806040838503121561449a57614499613b01565b5b600083013567ffffffffffffffff8111156144b8576144b7613b06565b5b6144c485828601614455565b92505060206144d585828601613d4e565b9150509250929050565b600080604083850312156144f6576144f5613b01565b5b600061450485828601613d4e565b925050602061451585828601613d4e565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061456657607f821691505b6020821081036145795761457861451f565b5b50919050565b7f53616c65206973206e6f74206163746976652000000000000000000000000000600082015250565b60006145b5601383613bd1565b91506145c08261457f565b602082019050919050565b600060208201905081810360008301526145e4816145a8565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061462582613c78565b915061463083613c78565b9250828201905080821115614648576146476145eb565b5b92915050565b7f5175616e74697479206d757374206265206c6573736572207468656e204d617860008201527f537570706c790000000000000000000000000000000000000000000000000000602082015250565b60006146aa602683613bd1565b91506146b58261464e565b604082019050919050565b600060208201905081810360008301526146d98161469d565b9050919050565b7f596f7520617265206e6f7420696e2070726573616c6500000000000000000000600082015250565b6000614716601683613bd1565b9150614721826146e0565b602082019050919050565b6000602082019050818103600083015261474581614709565b9050919050565b600061475782613c78565b915061476283613c78565b925082820261477081613c78565b91508282048414831517614787576147866145eb565b5b5092915050565b7f54727920746f2073656e64206d6f726520455448000000000000000000000000600082015250565b60006147c4601483613bd1565b91506147cf8261478e565b602082019050919050565b600060208201905081810360008301526147f3816147b7565b9050919050565b7f63616e206e6f74206d696e742074686973206d616e7900000000000000000000600082015250565b6000614830601683613bd1565b915061483b826147fa565b602082019050919050565b6000602082019050818103600083015261485f81614823565b9050919050565b7f50757263686173652065786365656473206d617820616c6c6f77656400000000600082015250565b600061489c601c83613bd1565b91506148a782614866565b602082019050919050565b600060208201905081810360008301526148cb8161488f565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614908602083613bd1565b9150614913826148d2565b602082019050919050565b60006020820190508181036000830152614937816148fb565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026149a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614963565b6149aa8683614963565b95508019841693508086168417925050509392505050565b60006149dd6149d86149d384613c78565b613f12565b613c78565b9050919050565b6000819050919050565b6149f7836149c2565b614a0b614a03826149e4565b848454614970565b825550505050565b600090565b614a20614a13565b614a2b8184846149ee565b505050565b5b81811015614a4f57614a44600082614a18565b600181019050614a31565b5050565b601f821115614a9457614a658161493e565b614a6e84614953565b81016020851015614a7d578190505b614a91614a8985614953565b830182614a30565b50505b505050565b600082821c905092915050565b6000614ab760001984600802614a99565b1980831691505092915050565b6000614ad08383614aa6565b9150826002028217905092915050565b614ae982613bc6565b67ffffffffffffffff811115614b0257614b01613f91565b5b614b0c825461454e565b614b17828285614a53565b600060209050601f831160018114614b4a5760008415614b38578287015190505b614b428582614ac4565b865550614baa565b601f198416614b588661493e565b60005b82811015614b8057848901518255600182019150602085019450602081019050614b5b565b86831015614b9d5784890151614b99601f891682614aa6565b8355505b6001600288020188555050505b505050505050565b7f72656163686564206d617820737570706c790000000000000000000000000000600082015250565b6000614be8601283613bd1565b9150614bf382614bb2565b602082019050919050565b60006020820190508181036000830152614c1781614bdb565b9050919050565b7f5468652063616c6c657220697320616e6f7468657220636f6e74726163740000600082015250565b6000614c54601e83613bd1565b9150614c5f82614c1e565b602082019050919050565b60006020820190508181036000830152614c8381614c47565b9050919050565b7f53616c65206973206e6f74204163746976650000000000000000000000000000600082015250565b6000614cc0601283613bd1565b9150614ccb82614c8a565b602082019050919050565b60006020820190508181036000830152614cef81614cb3565b9050919050565b7f72656163686564206d617820706861736520737570706c790000000000000000600082015250565b6000614d2c601883613bd1565b9150614d3782614cf6565b602082019050919050565b60006020820190508181036000830152614d5b81614d1f565b9050919050565b7f4e65656420746f2073656e64206d6f7265204554482e00000000000000000000600082015250565b6000614d98601683613bd1565b9150614da382614d62565b602082019050919050565b60006020820190508181036000830152614dc781614d8b565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000614e04601f83613bd1565b9150614e0f82614dce565b602082019050919050565b60006020820190508181036000830152614e3381614df7565b9050919050565b600081905092915050565b50565b6000614e55600083614e3a565b9150614e6082614e45565b600082019050919050565b6000614e7682614e48565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b6000614eb6601083613bd1565b9150614ec182614e80565b602082019050919050565b60006020820190508181036000830152614ee581614ea9565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000614f48602f83613bd1565b9150614f5382614eec565b604082019050919050565b60006020820190508181036000830152614f7781614f3b565b9050919050565b600081905092915050565b6000614f9482613bc6565b614f9e8185614f7e565b9350614fae818560208601613be2565b80840191505092915050565b7f2f00000000000000000000000000000000000000000000000000000000000000600082015250565b6000614ff0600183614f7e565b9150614ffb82614fba565b600182019050919050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b600061503c600583614f7e565b915061504782615006565b600582019050919050565b600061505e8285614f89565b915061506982614fe3565b91506150758284614f89565b91506150808261502f565b91508190509392505050565b60008160601b9050919050565b60006150a48261508c565b9050919050565b60006150b682615099565b9050919050565b6150ce6150c982613cfb565b6150ab565b82525050565b60006150e082846150bd565b60148201915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061514b602683613bd1565b9150615156826150ef565b604082019050919050565b6000602082019050818103600083015261517a8161513e565b9050919050565b60006040820190506151966000830185613d0d565b6151a36020830184613d0d565b9392505050565b6000815190506151b9816141a3565b92915050565b6000602082840312156151d5576151d4613b01565b5b60006151e3848285016151aa565b91505092915050565b60006151f782613c78565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615229576152286145eb565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061526e82613c78565b915061527983613c78565b92508261528957615288615234565b5b828204905092915050565b600061529f82613c78565b91506152aa83613c78565b92508282039050818111156152c2576152c16145eb565b5b92915050565b60006152d382613c78565b91506152de83613c78565b9250826152ee576152ed615234565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b600061534f82615328565b6153598185615333565b9350615369818560208601613be2565b61537281613c0c565b840191505092915050565b60006080820190506153926000830187613d0d565b61539f6020830186613d0d565b6153ac6040830185613da3565b81810360608301526153be8184615344565b905095945050505050565b6000815190506153d881613b37565b92915050565b6000602082840312156153f4576153f3613b01565b5b6000615402848285016153c9565b9150509291505056fea2646970667358221220bceb55f998e348df021fba1db25e4ec4507608624eb6f78480c920ac9b8abf4864736f6c63430008110033

Deployed Bytecode

0x60806040526004361061031a5760003560e01c8063852cbaee116101ab578063aebceff4116100f7578063dc33e68111610095578063e7d61da81161006f578063e7d61da814610bb6578063e8006bb014610be1578063e985e9c514610c0a578063f2fde38b14610c475761031a565b8063dc33e68114610aff578063e5ec56a014610b3c578063e757223014610b795761031a565b8063bd32fb66116100d1578063bd32fb6614610a47578063c49e806214610a70578063c7b8fca714610a99578063c87b56dd14610ac25761031a565b8063aebceff4146109b6578063b333ca91146109f3578063b88d4fde14610a1e5761031a565b806395d89b4111610164578063a40ece7a1161013e578063a40ece7a14610922578063a5cdae2d1461094b578063aa98e0c614610974578063ac4460021461099f5761031a565b806395d89b41146108b2578063a0712d68146108dd578063a22cb465146108f95761031a565b8063852cbaee146107a25780638825b014146107cd5780638ba4cc3c146107f65780638d859f3e1461081f5780638da5cb5b1461084a5780639231ab2a146108755761031a565b80633461ea431161026a57806351d7ff931161022357806369ba1a75116101fd57806369ba1a75146106e857806370a0823114610711578063715018a61461074e57806375236143146107655761031a565b806351d7ff931461065757806355f804b3146106825780636352211e146106ab5761031a565b80633461ea431461055b5780633fd173661461058457806341f43434146105ad57806342842e0e146105d85780634e69d56014610601578063518302271461062c5761031a565b806318160ddd116102d757806323b872dd116102b157806323b872dd146104c75780632632d5f8146104f05780632ba2865b1461051b5780632d5b005d146105445761031a565b806318160ddd146104345780631984b2861461045f578063200d2ed21461049c5761031a565b806301ffc9a71461031f57806306fdde031461035c578063081812fc14610387578063095ea7b3146103c45780630f2cdd6c146103ed57806310157fc314610418575b600080fd5b34801561032b57600080fd5b5061034660048036038101906103419190613b63565b610c70565b6040516103539190613bab565b60405180910390f35b34801561036857600080fd5b50610371610d52565b60405161037e9190613c56565b60405180910390f35b34801561039357600080fd5b506103ae60048036038101906103a99190613cae565b610de4565b6040516103bb9190613d1c565b60405180910390f35b3480156103d057600080fd5b506103eb60048036038101906103e69190613d63565b610e60565b005b3480156103f957600080fd5b50610402610e79565b60405161040f9190613db2565b60405180910390f35b610432600480360381019061042d9190613e32565b610e7f565b005b34801561044057600080fd5b50610449611123565b6040516104569190613db2565b60405180910390f35b34801561046b57600080fd5b5061048660048036038101906104819190613e92565b61113a565b6040516104939190613db2565b60405180910390f35b3480156104a857600080fd5b506104b1611152565b6040516104be9190613db2565b60405180910390f35b3480156104d357600080fd5b506104ee60048036038101906104e99190613ebf565b611158565b005b3480156104fc57600080fd5b506105056111a7565b6040516105129190613db2565b60405180910390f35b34801561052757600080fd5b50610542600480360381019061053d9190613cae565b6111ad565b005b34801561055057600080fd5b50610559611233565b005b34801561056757600080fd5b50610582600480360381019061057d9190613cae565b6112cc565b005b34801561059057600080fd5b506105ab60048036038101906105a69190613cae565b611352565b005b3480156105b957600080fd5b506105c26113d8565b6040516105cf9190613f71565b60405180910390f35b3480156105e457600080fd5b506105ff60048036038101906105fa9190613ebf565b6113ea565b005b34801561060d57600080fd5b50610616611439565b6040516106239190613db2565b60405180910390f35b34801561063857600080fd5b50610641611443565b60405161064e9190613bab565b60405180910390f35b34801561066357600080fd5b5061066c611456565b6040516106799190613db2565b60405180910390f35b34801561068e57600080fd5b506106a960048036038101906106a491906140bc565b61145c565b005b3480156106b757600080fd5b506106d260048036038101906106cd9190613cae565b6114eb565b6040516106df9190613d1c565b60405180910390f35b3480156106f457600080fd5b5061070f600480360381019061070a9190613cae565b611501565b005b34801561071d57600080fd5b5061073860048036038101906107339190613e92565b611587565b6040516107459190613db2565b60405180910390f35b34801561075a57600080fd5b50610763611656565b005b34801561077157600080fd5b5061078c60048036038101906107879190613e92565b6116de565b6040516107999190613db2565b60405180910390f35b3480156107ae57600080fd5b506107b76116f6565b6040516107c49190613db2565b60405180910390f35b3480156107d957600080fd5b506107f460048036038101906107ef9190613cae565b6116fc565b005b34801561080257600080fd5b5061081d60048036038101906108189190613d63565b611782565b005b34801561082b57600080fd5b50610834611863565b6040516108419190613db2565b60405180910390f35b34801561085657600080fd5b5061085f611869565b60405161086c9190613d1c565b60405180910390f35b34801561088157600080fd5b5061089c60048036038101906108979190613cae565b611892565b6040516108a99190614188565b60405180910390f35b3480156108be57600080fd5b506108c76118aa565b6040516108d49190613c56565b60405180910390f35b6108f760048036038101906108f29190613cae565b61193c565b005b34801561090557600080fd5b50610920600480360381019061091b91906141cf565b611c19565b005b34801561092e57600080fd5b5061094960048036038101906109449190613cae565b611c32565b005b34801561095757600080fd5b50610972600480360381019061096d9190613cae565b611cb8565b005b34801561098057600080fd5b50610989611d3e565b6040516109969190614228565b60405180910390f35b3480156109ab57600080fd5b506109b4611d44565b005b3480156109c257600080fd5b506109dd60048036038101906109d89190613cae565b611ec4565b6040516109ea9190613db2565b60405180910390f35b3480156109ff57600080fd5b50610a08611edb565b604051610a159190613db2565b60405180910390f35b348015610a2a57600080fd5b50610a456004803603810190610a4091906142e4565b611ee1565b005b348015610a5357600080fd5b50610a6e6004803603810190610a699190614393565b611f32565b005b348015610a7c57600080fd5b50610a976004803603810190610a929190613cae565b611fb8565b005b348015610aa557600080fd5b50610ac06004803603810190610abb91906140bc565b61203e565b005b348015610ace57600080fd5b50610ae96004803603810190610ae49190613cae565b6120cd565b604051610af69190613c56565b60405180910390f35b348015610b0b57600080fd5b50610b266004803603810190610b219190613e92565b612222565b604051610b339190613db2565b60405180910390f35b348015610b4857600080fd5b50610b636004803603810190610b5e9190614483565b612234565b604051610b709190613bab565b60405180910390f35b348015610b8557600080fd5b50610ba06004803603810190610b9b9190613cae565b612271565b604051610bad9190613db2565b60405180910390f35b348015610bc257600080fd5b50610bcb612288565b604051610bd89190613db2565b60405180910390f35b348015610bed57600080fd5b50610c086004803603810190610c039190613cae565b61228e565b005b348015610c1657600080fd5b50610c316004803603810190610c2c91906144df565b612314565b604051610c3e9190613bab565b60405180910390f35b348015610c5357600080fd5b50610c6e6004803603810190610c699190613e92565b6123a8565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610d3b57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610d4b5750610d4a8261249f565b5b9050919050565b606060038054610d619061454e565b80601f0160208091040260200160405190810160405280929190818152602001828054610d8d9061454e565b8015610dda5780601f10610daf57610100808354040283529160200191610dda565b820191906000526020600020905b815481529060010190602001808311610dbd57829003601f168201915b5050505050905090565b6000610def82612509565b610e25576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610e6a81612557565b610e748383612654565b505050565b600b5481565b6001600e5414610ec4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ebb906145cb565b60405180910390fd5b60175483610ed0611123565b610eda919061461a565b1115610f1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f12906146c0565b60405180910390fd5b610f66828280806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505033612234565b610fa5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f9c9061472c565b60405180910390fd5b60165483610fb3919061474c565b341015610ff5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fec906147da565b60405180910390fd5b60145483111561103a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103190614846565b60405180910390fd5b82601860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611089919061461a565b92505081905550601354601860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115611114576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110b906148b2565b60405180910390fd5b61111e338461275e565b505050565b600061112d61277c565b6002546001540303905090565b60186020528060005260406000206000915090505481565b600e5481565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146111965761119533612557565b5b6111a1848484612785565b50505050565b60165481565b6111b5612795565b73ffffffffffffffffffffffffffffffffffffffff166111d3611869565b73ffffffffffffffffffffffffffffffffffffffff1614611229576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112209061491e565b60405180910390fd5b80600b8190555050565b61123b612795565b73ffffffffffffffffffffffffffffffffffffffff16611259611869565b73ffffffffffffffffffffffffffffffffffffffff16146112af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112a69061491e565b60405180910390fd5b6001601160006101000a81548160ff021916908315150217905550565b6112d4612795565b73ffffffffffffffffffffffffffffffffffffffff166112f2611869565b73ffffffffffffffffffffffffffffffffffffffff1614611348576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133f9061491e565b60405180910390fd5b80600d8190555050565b61135a612795565b73ffffffffffffffffffffffffffffffffffffffff16611378611869565b73ffffffffffffffffffffffffffffffffffffffff16146113ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113c59061491e565b60405180910390fd5b80600c8190555050565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146114285761142733612557565b5b61143384848461279d565b50505050565b6000600e54905090565b601160009054906101000a900460ff1681565b600a5481565b611464612795565b73ffffffffffffffffffffffffffffffffffffffff16611482611869565b73ffffffffffffffffffffffffffffffffffffffff16146114d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114cf9061491e565b60405180910390fd5b80600f90816114e79190614ae0565b5050565b60006114f6826127bd565b600001519050919050565b611509612795565b73ffffffffffffffffffffffffffffffffffffffff16611527611869565b73ffffffffffffffffffffffffffffffffffffffff161461157d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115749061491e565b60405180910390fd5b80600e8190555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036115ee576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900467ffffffffffffffff1667ffffffffffffffff169050919050565b61165e612795565b73ffffffffffffffffffffffffffffffffffffffff1661167c611869565b73ffffffffffffffffffffffffffffffffffffffff16146116d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116c99061491e565b60405180910390fd5b6116dc6000612a4c565b565b60126020528060005260406000206000915090505481565b60135481565b611704612795565b73ffffffffffffffffffffffffffffffffffffffff16611722611869565b73ffffffffffffffffffffffffffffffffffffffff1614611778576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161176f9061491e565b60405180910390fd5b8060168190555050565b61178a612795565b73ffffffffffffffffffffffffffffffffffffffff166117a8611869565b73ffffffffffffffffffffffffffffffffffffffff16146117fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117f59061491e565b60405180910390fd5b6104778161180a611123565b611814919061461a565b1115611855576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161184c90614bfe565b60405180910390fd5b61185f828261275e565b5050565b600c5481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61189a613ab4565b6118a3826127bd565b9050919050565b6060600480546118b99061454e565b80601f01602080910402602001604051908101604052809291908181526020018280546118e59061454e565b80156119325780601f1061190757610100808354040283529160200191611932565b820191906000526020600020905b81548152906001019060200180831161191557829003601f168201915b5050505050905090565b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16146119aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a190614c6a565b60405180910390fd5b6002600e54146119ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e690614cd6565b60405180910390fd5b610477816119fb611123565b611a05919061461a565b1115611a46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a3d90614bfe565b60405180910390fd5b600d5481611a52611123565b611a5c919061461a565b1115611a9d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a9490614d42565b60405180910390fd5b600a54811115611ae2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ad990614846565b60405180910390fd5b80600c54611af0919061474c565b341015611b32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b2990614dae565b60405180910390fd5b80601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611b81919061461a565b92505081905550600b54601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541115611c0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c03906148b2565b60405180910390fd5b611c16338261275e565b50565b81611c2381612557565b611c2d8383612b10565b505050565b611c3a612795565b73ffffffffffffffffffffffffffffffffffffffff16611c58611869565b73ffffffffffffffffffffffffffffffffffffffff1614611cae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ca59061491e565b60405180910390fd5b80600a8190555050565b611cc0612795565b73ffffffffffffffffffffffffffffffffffffffff16611cde611869565b73ffffffffffffffffffffffffffffffffffffffff1614611d34576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d2b9061491e565b60405180910390fd5b8060138190555050565b60155481565b611d4c612795565b73ffffffffffffffffffffffffffffffffffffffff16611d6a611869565b73ffffffffffffffffffffffffffffffffffffffff1614611dc0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611db79061491e565b60405180910390fd5b600260095403611e05576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dfc90614e1a565b60405180910390fd5b600260098190555060003373ffffffffffffffffffffffffffffffffffffffff1647604051611e3390614e6b565b60006040518083038185875af1925050503d8060008114611e70576040519150601f19603f3d011682016040523d82523d6000602084013e611e75565b606091505b5050905080611eb9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eb090614ecc565b60405180910390fd5b506001600981905550565b600060165482611ed4919061474c565b9050919050565b600d5481565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611f1f57611f1e33612557565b5b611f2b85858585612c87565b5050505050565b611f3a612795565b73ffffffffffffffffffffffffffffffffffffffff16611f58611869565b73ffffffffffffffffffffffffffffffffffffffff1614611fae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa59061491e565b60405180910390fd5b8060158190555050565b611fc0612795565b73ffffffffffffffffffffffffffffffffffffffff16611fde611869565b73ffffffffffffffffffffffffffffffffffffffff1614612034576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161202b9061491e565b60405180910390fd5b8060148190555050565b612046612795565b73ffffffffffffffffffffffffffffffffffffffff16612064611869565b73ffffffffffffffffffffffffffffffffffffffff16146120ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120b19061491e565b60405180910390fd5b80601090816120c99190614ae0565b5050565b60606120d882612509565b612117576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161210e90614f5e565b60405180910390fd5b60001515601160009054906101000a900460ff161515036121c4576010805461213f9061454e565b80601f016020809104026020016040519081016040528092919081815260200182805461216b9061454e565b80156121b85780601f1061218d576101008083540402835291602001916121b8565b820191906000526020600020905b81548152906001019060200180831161219b57829003601f168201915b5050505050905061221d565b60006121ce612d03565b905060008151116121ee5760405180602001604052806000815250612219565b806121f884612d95565b604051602001612209929190615052565b6040516020818303038152906040525b9150505b919050565b600061222d82612ef5565b9050919050565b6000612269836015548460405160200161224e91906150d4565b60405160208183030381529060405280519060200120612f5f565b905092915050565b6000600c5482612281919061474c565b9050919050565b60145481565b612296612795565b73ffffffffffffffffffffffffffffffffffffffff166122b4611869565b73ffffffffffffffffffffffffffffffffffffffff161461230a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123019061491e565b60405180910390fd5b8060178190555050565b6000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6123b0612795565b73ffffffffffffffffffffffffffffffffffffffff166123ce611869565b73ffffffffffffffffffffffffffffffffffffffff1614612424576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161241b9061491e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612493576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161248a90615161565b60405180910390fd5b61249c81612a4c565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008161251461277c565b11158015612523575060015482105b8015612550575060056000838152602001908152602001600020600001601c9054906101000a900460ff16155b9050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115612651576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016125ce929190615181565b602060405180830381865afa1580156125eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260f91906151bf565b61265057806040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016126479190613d1c565b60405180910390fd5b5b50565b600061265f826114eb565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036126c6576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166126e5612795565b73ffffffffffffffffffffffffffffffffffffffff1614158015612717575061271581612710612795565b612314565b155b1561274e576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612759838383612f76565b505050565b612778828260405180602001604052806000815250613028565b5050565b60006001905090565b61279083838361303a565b505050565b600033905090565b6127b883838360405180602001604052806000815250611ee1565b505050565b6127c5613ab4565b6000829050806127d361277c565b111580156127e2575060015481105b15612a15576000600560008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff16151515158152505090508060400151612a1357600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff16146128f7578092505050612a47565b5b600115612a1257818060019003925050600560008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff1615151515815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614612a0d578092505050612a47565b6128f8565b5b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b612b18612795565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612b7c576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060086000612b89612795565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612c36612795565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612c7b9190613bab565b60405180910390a35050565b612c9284848461303a565b612cb18373ffffffffffffffffffffffffffffffffffffffff166134ee565b8015612cc65750612cc484848484613501565b155b15612cfd576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6060600f8054612d129061454e565b80601f0160208091040260200160405190810160405280929190818152602001828054612d3e9061454e565b8015612d8b5780601f10612d6057610100808354040283529160200191612d8b565b820191906000526020600020905b815481529060010190602001808311612d6e57829003601f168201915b5050505050905090565b606060008203612ddc576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612ef0565b600082905060005b60008214612e0e578080612df7906151ec565b915050600a82612e079190615263565b9150612de4565b60008167ffffffffffffffff811115612e2a57612e29613f91565b5b6040519080825280601f01601f191660200182016040528015612e5c5781602001600182028036833780820191505090505b5090505b60008514612ee957600182612e759190615294565b9150600a85612e8491906152c8565b6030612e90919061461a565b60f81b818381518110612ea657612ea56152f9565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612ee29190615263565b9450612e60565b8093505050505b919050565b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160089054906101000a900467ffffffffffffffff1667ffffffffffffffff169050919050565b600082612f6c8584613651565b1490509392505050565b826007600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b61303583838360016136c6565b505050565b6000613045826127bd565b90508373ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff16146130b0576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff166130d1612795565b73ffffffffffffffffffffffffffffffffffffffff16148061310057506130ff856130fa612795565b612314565b5b80613145575061310e612795565b73ffffffffffffffffffffffffffffffffffffffff1661312d84610de4565b73ffffffffffffffffffffffffffffffffffffffff16145b90508061317e576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036131e4576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6131f18585856001613a91565b6131fd60008487612f76565b6001600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160392506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506001600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000600560008581526020019081526020016000209050848160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550428160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060006001850190506000600560008381526020019081526020016000209050600073ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361347c57600154821461347b57878160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084602001518160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b5b505050828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46134e78585856001613a97565b5050505050565b600080823b905060008111915050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613527612795565b8786866040518563ffffffff1660e01b8152600401613549949392919061537d565b6020604051808303816000875af192505050801561358557506040513d601f19601f8201168201806040525081019061358291906153de565b60015b6135fe573d80600081146135b5576040519150601f19603f3d011682016040523d82523d6000602084013e6135ba565b606091505b5060008151036135f6576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60008082905060005b84518110156136bb576000858281518110613678576136776152f9565b5b6020026020010151905080831161369a576136938382613a9d565b92506136a7565b6136a48184613a9d565b92505b5080806136b3906151ec565b91505061365a565b508091505092915050565b60006001549050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603613733576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000840361376d576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61377a6000868387613a91565b83600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555083600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160088282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550846005600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426005600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060008190506000858201905083801561394457506139438773ffffffffffffffffffffffffffffffffffffffff166134ee565b5b15613a09575b818773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46139b96000888480600101955088613501565b6139ef576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80820361394a578260015414613a0457600080fd5b613a74565b5b818060010192508773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4808203613a0a575b816001819055505050613a8a6000868387613a97565b5050505050565b50505050565b50505050565b600082600052816020526040600020905092915050565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff1681526020016000151581525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613b4081613b0b565b8114613b4b57600080fd5b50565b600081359050613b5d81613b37565b92915050565b600060208284031215613b7957613b78613b01565b5b6000613b8784828501613b4e565b91505092915050565b60008115159050919050565b613ba581613b90565b82525050565b6000602082019050613bc06000830184613b9c565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613c00578082015181840152602081019050613be5565b60008484015250505050565b6000601f19601f8301169050919050565b6000613c2882613bc6565b613c328185613bd1565b9350613c42818560208601613be2565b613c4b81613c0c565b840191505092915050565b60006020820190508181036000830152613c708184613c1d565b905092915050565b6000819050919050565b613c8b81613c78565b8114613c9657600080fd5b50565b600081359050613ca881613c82565b92915050565b600060208284031215613cc457613cc3613b01565b5b6000613cd284828501613c99565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613d0682613cdb565b9050919050565b613d1681613cfb565b82525050565b6000602082019050613d316000830184613d0d565b92915050565b613d4081613cfb565b8114613d4b57600080fd5b50565b600081359050613d5d81613d37565b92915050565b60008060408385031215613d7a57613d79613b01565b5b6000613d8885828601613d4e565b9250506020613d9985828601613c99565b9150509250929050565b613dac81613c78565b82525050565b6000602082019050613dc76000830184613da3565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112613df257613df1613dcd565b5b8235905067ffffffffffffffff811115613e0f57613e0e613dd2565b5b602083019150836020820283011115613e2b57613e2a613dd7565b5b9250929050565b600080600060408486031215613e4b57613e4a613b01565b5b6000613e5986828701613c99565b935050602084013567ffffffffffffffff811115613e7a57613e79613b06565b5b613e8686828701613ddc565b92509250509250925092565b600060208284031215613ea857613ea7613b01565b5b6000613eb684828501613d4e565b91505092915050565b600080600060608486031215613ed857613ed7613b01565b5b6000613ee686828701613d4e565b9350506020613ef786828701613d4e565b9250506040613f0886828701613c99565b9150509250925092565b6000819050919050565b6000613f37613f32613f2d84613cdb565b613f12565b613cdb565b9050919050565b6000613f4982613f1c565b9050919050565b6000613f5b82613f3e565b9050919050565b613f6b81613f50565b82525050565b6000602082019050613f866000830184613f62565b92915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613fc982613c0c565b810181811067ffffffffffffffff82111715613fe857613fe7613f91565b5b80604052505050565b6000613ffb613af7565b90506140078282613fc0565b919050565b600067ffffffffffffffff82111561402757614026613f91565b5b61403082613c0c565b9050602081019050919050565b82818337600083830152505050565b600061405f61405a8461400c565b613ff1565b90508281526020810184848401111561407b5761407a613f8c565b5b61408684828561403d565b509392505050565b600082601f8301126140a3576140a2613dcd565b5b81356140b384826020860161404c565b91505092915050565b6000602082840312156140d2576140d1613b01565b5b600082013567ffffffffffffffff8111156140f0576140ef613b06565b5b6140fc8482850161408e565b91505092915050565b61410e81613cfb565b82525050565b600067ffffffffffffffff82169050919050565b61413181614114565b82525050565b61414081613b90565b82525050565b60608201600082015161415c6000850182614105565b50602082015161416f6020850182614128565b5060408201516141826040850182614137565b50505050565b600060608201905061419d6000830184614146565b92915050565b6141ac81613b90565b81146141b757600080fd5b50565b6000813590506141c9816141a3565b92915050565b600080604083850312156141e6576141e5613b01565b5b60006141f485828601613d4e565b9250506020614205858286016141ba565b9150509250929050565b6000819050919050565b6142228161420f565b82525050565b600060208201905061423d6000830184614219565b92915050565b600067ffffffffffffffff82111561425e5761425d613f91565b5b61426782613c0c565b9050602081019050919050565b600061428761428284614243565b613ff1565b9050828152602081018484840111156142a3576142a2613f8c565b5b6142ae84828561403d565b509392505050565b600082601f8301126142cb576142ca613dcd565b5b81356142db848260208601614274565b91505092915050565b600080600080608085870312156142fe576142fd613b01565b5b600061430c87828801613d4e565b945050602061431d87828801613d4e565b935050604061432e87828801613c99565b925050606085013567ffffffffffffffff81111561434f5761434e613b06565b5b61435b878288016142b6565b91505092959194509250565b6143708161420f565b811461437b57600080fd5b50565b60008135905061438d81614367565b92915050565b6000602082840312156143a9576143a8613b01565b5b60006143b78482850161437e565b91505092915050565b600067ffffffffffffffff8211156143db576143da613f91565b5b602082029050602081019050919050565b60006143ff6143fa846143c0565b613ff1565b9050808382526020820190506020840283018581111561442257614421613dd7565b5b835b8181101561444b5780614437888261437e565b845260208401935050602081019050614424565b5050509392505050565b600082601f83011261446a57614469613dcd565b5b813561447a8482602086016143ec565b91505092915050565b6000806040838503121561449a57614499613b01565b5b600083013567ffffffffffffffff8111156144b8576144b7613b06565b5b6144c485828601614455565b92505060206144d585828601613d4e565b9150509250929050565b600080604083850312156144f6576144f5613b01565b5b600061450485828601613d4e565b925050602061451585828601613d4e565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061456657607f821691505b6020821081036145795761457861451f565b5b50919050565b7f53616c65206973206e6f74206163746976652000000000000000000000000000600082015250565b60006145b5601383613bd1565b91506145c08261457f565b602082019050919050565b600060208201905081810360008301526145e4816145a8565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061462582613c78565b915061463083613c78565b9250828201905080821115614648576146476145eb565b5b92915050565b7f5175616e74697479206d757374206265206c6573736572207468656e204d617860008201527f537570706c790000000000000000000000000000000000000000000000000000602082015250565b60006146aa602683613bd1565b91506146b58261464e565b604082019050919050565b600060208201905081810360008301526146d98161469d565b9050919050565b7f596f7520617265206e6f7420696e2070726573616c6500000000000000000000600082015250565b6000614716601683613bd1565b9150614721826146e0565b602082019050919050565b6000602082019050818103600083015261474581614709565b9050919050565b600061475782613c78565b915061476283613c78565b925082820261477081613c78565b91508282048414831517614787576147866145eb565b5b5092915050565b7f54727920746f2073656e64206d6f726520455448000000000000000000000000600082015250565b60006147c4601483613bd1565b91506147cf8261478e565b602082019050919050565b600060208201905081810360008301526147f3816147b7565b9050919050565b7f63616e206e6f74206d696e742074686973206d616e7900000000000000000000600082015250565b6000614830601683613bd1565b915061483b826147fa565b602082019050919050565b6000602082019050818103600083015261485f81614823565b9050919050565b7f50757263686173652065786365656473206d617820616c6c6f77656400000000600082015250565b600061489c601c83613bd1565b91506148a782614866565b602082019050919050565b600060208201905081810360008301526148cb8161488f565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614908602083613bd1565b9150614913826148d2565b602082019050919050565b60006020820190508181036000830152614937816148fb565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026149a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614963565b6149aa8683614963565b95508019841693508086168417925050509392505050565b60006149dd6149d86149d384613c78565b613f12565b613c78565b9050919050565b6000819050919050565b6149f7836149c2565b614a0b614a03826149e4565b848454614970565b825550505050565b600090565b614a20614a13565b614a2b8184846149ee565b505050565b5b81811015614a4f57614a44600082614a18565b600181019050614a31565b5050565b601f821115614a9457614a658161493e565b614a6e84614953565b81016020851015614a7d578190505b614a91614a8985614953565b830182614a30565b50505b505050565b600082821c905092915050565b6000614ab760001984600802614a99565b1980831691505092915050565b6000614ad08383614aa6565b9150826002028217905092915050565b614ae982613bc6565b67ffffffffffffffff811115614b0257614b01613f91565b5b614b0c825461454e565b614b17828285614a53565b600060209050601f831160018114614b4a5760008415614b38578287015190505b614b428582614ac4565b865550614baa565b601f198416614b588661493e565b60005b82811015614b8057848901518255600182019150602085019450602081019050614b5b565b86831015614b9d5784890151614b99601f891682614aa6565b8355505b6001600288020188555050505b505050505050565b7f72656163686564206d617820737570706c790000000000000000000000000000600082015250565b6000614be8601283613bd1565b9150614bf382614bb2565b602082019050919050565b60006020820190508181036000830152614c1781614bdb565b9050919050565b7f5468652063616c6c657220697320616e6f7468657220636f6e74726163740000600082015250565b6000614c54601e83613bd1565b9150614c5f82614c1e565b602082019050919050565b60006020820190508181036000830152614c8381614c47565b9050919050565b7f53616c65206973206e6f74204163746976650000000000000000000000000000600082015250565b6000614cc0601283613bd1565b9150614ccb82614c8a565b602082019050919050565b60006020820190508181036000830152614cef81614cb3565b9050919050565b7f72656163686564206d617820706861736520737570706c790000000000000000600082015250565b6000614d2c601883613bd1565b9150614d3782614cf6565b602082019050919050565b60006020820190508181036000830152614d5b81614d1f565b9050919050565b7f4e65656420746f2073656e64206d6f7265204554482e00000000000000000000600082015250565b6000614d98601683613bd1565b9150614da382614d62565b602082019050919050565b60006020820190508181036000830152614dc781614d8b565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000614e04601f83613bd1565b9150614e0f82614dce565b602082019050919050565b60006020820190508181036000830152614e3381614df7565b9050919050565b600081905092915050565b50565b6000614e55600083614e3a565b9150614e6082614e45565b600082019050919050565b6000614e7682614e48565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b6000614eb6601083613bd1565b9150614ec182614e80565b602082019050919050565b60006020820190508181036000830152614ee581614ea9565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000614f48602f83613bd1565b9150614f5382614eec565b604082019050919050565b60006020820190508181036000830152614f7781614f3b565b9050919050565b600081905092915050565b6000614f9482613bc6565b614f9e8185614f7e565b9350614fae818560208601613be2565b80840191505092915050565b7f2f00000000000000000000000000000000000000000000000000000000000000600082015250565b6000614ff0600183614f7e565b9150614ffb82614fba565b600182019050919050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b600061503c600583614f7e565b915061504782615006565b600582019050919050565b600061505e8285614f89565b915061506982614fe3565b91506150758284614f89565b91506150808261502f565b91508190509392505050565b60008160601b9050919050565b60006150a48261508c565b9050919050565b60006150b682615099565b9050919050565b6150ce6150c982613cfb565b6150ab565b82525050565b60006150e082846150bd565b60148201915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061514b602683613bd1565b9150615156826150ef565b604082019050919050565b6000602082019050818103600083015261517a8161513e565b9050919050565b60006040820190506151966000830185613d0d565b6151a36020830184613d0d565b9392505050565b6000815190506151b9816141a3565b92915050565b6000602082840312156151d5576151d4613b01565b5b60006151e3848285016151aa565b91505092915050565b60006151f782613c78565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615229576152286145eb565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061526e82613c78565b915061527983613c78565b92508261528957615288615234565b5b828204905092915050565b600061529f82613c78565b91506152aa83613c78565b92508282039050818111156152c2576152c16145eb565b5b92915050565b60006152d382613c78565b91506152de83613c78565b9250826152ee576152ed615234565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b600061534f82615328565b6153598185615333565b9350615369818560208601613be2565b61537281613c0c565b840191505092915050565b60006080820190506153926000830187613d0d565b61539f6020830186613d0d565b6153ac6040830185613da3565b81810360608301526153be8184615344565b905095945050505050565b6000815190506153d881613b37565b92915050565b6000602082840312156153f4576153f3613b01565b5b6000615402848285016153c9565b9150509291505056fea2646970667358221220bceb55f998e348df021fba1db25e4ec4507608624eb6f78480c920ac9b8abf4864736f6c63430008110033

Deployed Bytecode Sourcemap

31988:6846:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14734:300;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17762:98;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;19226:200;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38107:155;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;32197:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;36641:697;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;14005:297;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;36065:53;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32558:22;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38268:161;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35947:43;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35186:93;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;34310:77;;;;;;;;;;;;;:::i;:::-;;34827:146;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;34977:95;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;737:142:7;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38435:169:0;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35358:71;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32683:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32105:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33551:96;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;17577:123;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35283:70;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;15093:203;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5040:101;;;;;;;;;;;;;:::i;:::-;;32716:50;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35773:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37622:132;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35553:186;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;32280:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4825:85;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34499:142;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17924:102;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32938:609;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;37927:174;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35076:103;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;37344:136;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35907:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34645:178;;;;;;;;;;;;;:::i;:::-;;36288:139;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32476:42;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38610:222;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;36142:140;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;37760:110;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;33762:99;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;33866:440;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34391:105;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;36433:197;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35435:114;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35816:41;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37487:129;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;19841:162;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5148:198;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;14734:300;14836:4;14886:25;14871:40;;;:11;:40;;;;:104;;;;14942:33;14927:48;;;:11;:48;;;;14871:104;:156;;;;14991:36;15015:11;14991:23;:36::i;:::-;14871:156;14852:175;;14734:300;;;:::o;17762:98::-;17816:13;17848:5;17841:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17762:98;:::o;19226:200::-;19294:7;19318:16;19326:7;19318;:16::i;:::-;19313:64;;19343:34;;;;;;;;;;;;;;19313:64;19395:15;:24;19411:7;19395:24;;;;;;;;;;;;;;;;;;;;;19388:31;;19226:200;;;:::o;38107:155::-;38203:8;2227:30:7;2248:8;2227:20;:30::i;:::-;38223:32:0::1;38237:8;38247:7;38223:13;:32::i;:::-;38107:155:::0;;;:::o;32197:34::-;;;;:::o;36641:697::-;36764:1;36754:6;;:11;36746:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;36832:16;;36822:8;36808:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:40;;36800:90;;;;;;;;;;;;:::i;:::-;;;;;;;;;36908:31;36920:6;;36908:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36928:10;36908:11;:31::i;:::-;36900:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;37008:18;;36997:8;:29;;;;:::i;:::-;36984:9;:42;;36976:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;37081:22;;37069:8;:34;;37061:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;37176:8;37142:18;:30;37161:10;37142:30;;;;;;;;;;;;;;;;:42;;;;;;;:::i;:::-;;;;;;;;37236:18;;37202;:30;37221:10;37202:30;;;;;;;;;;;;;;;;:52;;37194:93;;;;;;;;;;;;:::i;:::-;;;;;;;;;37300:31;37310:10;37322:8;37300:9;:31::i;:::-;36641:697;;;:::o;14005:297::-;14049:7;14270:15;:13;:15::i;:::-;14255:12;;14239:13;;:28;:46;14232:53;;14005:297;:::o;36065:53::-;;;;;;;;;;;;;;;;;:::o;32558:22::-;;;;:::o;38268:161::-;38369:4;2062:10:7;2054:18;;:4;:18;;;2050:81;;2088:32;2109:10;2088:20;:32::i;:::-;2050:81;38385:37:0::1;38404:4;38410:2;38414:7;38385:18;:37::i;:::-;38268:161:::0;;;;:::o;35947:43::-;;;;:::o;35186:93::-;4966:12;:10;:12::i;:::-;4955:23;;:7;:5;:7::i;:::-;:23;;;4947:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;35273:1:::1;35256:14;:18;;;;35186:93:::0;:::o;34310:77::-;4966:12;:10;:12::i;:::-;4955:23;;:7;:5;:7::i;:::-;:23;;;4947:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;34378:4:::1;34367:8;;:15;;;;;;;;;;;;;;;;;;34310:77::o:0;34827:146::-;4966:12;:10;:12::i;:::-;4955:23;;:7;:5;:7::i;:::-;:23;;;4947:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;34955:11:::1;34932:20;:34;;;;34827:146:::0;:::o;34977:95::-;4966:12;:10;:12::i;:::-;4955:23;;:7;:5;:7::i;:::-;:23;;;4947:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;35058:9:::1;35050:5;:17;;;;34977:95:::0;:::o;737:142:7:-;836:42;737:142;:::o;38435:169:0:-;38540:4;2062:10:7;2054:18;;:4;:18;;;2050:81;;2088:32;2109:10;2088:20;:32::i;:::-;2050:81;38556:41:0::1;38579:4;38585:2;38589:7;38556:22;:41::i;:::-;38435:169:::0;;;;:::o;35358:71::-;35398:4;35418:6;;35411:13;;35358:71;:::o;32683:28::-;;;;;;;;;;;;;:::o;32105:39::-;;;;:::o;33551:96::-;4966:12;:10;:12::i;:::-;4955:23;;:7;:5;:7::i;:::-;:23;;;4947:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;33635:7:::1;33619:13;:23;;;;;;:::i;:::-;;33551:96:::0;:::o;17577:123::-;17641:7;17667:21;17680:7;17667:12;:21::i;:::-;:26;;;17660:33;;17577:123;;;:::o;35283:70::-;4966:12;:10;:12::i;:::-;4955:23;;:7;:5;:7::i;:::-;:23;;;4947:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;35347:1:::1;35338:6;:10;;;;35283:70:::0;:::o;15093:203::-;15157:7;15197:1;15180:19;;:5;:19;;;15176:60;;15208:28;;;;;;;;;;;;;;15176:60;15261:12;:19;15274:5;15261:19;;;;;;;;;;;;;;;:27;;;;;;;;;;;;15253:36;;15246:43;;15093:203;;;:::o;5040:101::-;4966:12;:10;:12::i;:::-;4955:23;;:7;:5;:7::i;:::-;:23;;;4947:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;5104:30:::1;5131:1;5104:18;:30::i;:::-;5040:101::o:0;32716:50::-;;;;;;;;;;;;;;;;;:::o;35773:37::-;;;;:::o;37622:132::-;4966:12;:10;:12::i;:::-;4955:23;;:7;:5;:7::i;:::-;:23;;;4947:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;37728:19:::1;37707:18;:40;;;;37622:132:::0;:::o;35553:186::-;4966:12;:10;:12::i;:::-;4955:23;;:7;:5;:7::i;:::-;:23;;;4947:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;32367:4:::1;35646:8;35630:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:48;;35622:79;;;;;;;;;;;;:::i;:::-;;;;;;;;;35707:27;35717:6;35725:8;35707:9;:27::i;:::-;35553:186:::0;;:::o;32280:33::-;;;;:::o;4825:85::-;4871:7;4897:6;;;;;;;;;;;4890:13;;4825:85;:::o;34499:142::-;34577:21;;:::i;:::-;34615;34628:7;34615:12;:21::i;:::-;34608:28;;34499:142;;;:::o;17924:102::-;17980:13;18012:7;18005:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17924:102;:::o;32938:609::-;32876:10;32863:23;;:9;:23;;;32855:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;33024:1:::1;33014:6;;:11;33006:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;32367:4;33079:8;33063:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:48;;33055:79;;;;;;;;;;;;:::i;:::-;;;;;;;;;33176:20;;33164:8;33148:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:48;;33140:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;33251:19;;33239:8;:31;;33231:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;33331:8;33323:5;;:16;;;;:::i;:::-;33310:9;:29;;33302:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;33404:8;33373:15;:27;33389:10;33373:27;;;;;;;;;;;;;;;;:39;;;;;;;:::i;:::-;;;;;;;;33457:14;;33426:15;:27;33442:10;33426:27;;;;;;;;;;;;;;;;:45;;33418:86;;;;;;;;;;;;:::i;:::-;;;;;;;;;33511:31;33521:10;33533:8;33511:9;:31::i;:::-;32938:609:::0;:::o;37927:174::-;38031:8;2227:30:7;2248:8;2227:20;:30::i;:::-;38051:43:0::1;38075:8;38085;38051:23;:43::i;:::-;37927:174:::0;;;:::o;35076:103::-;4966:12;:10;:12::i;:::-;4955:23;;:7;:5;:7::i;:::-;:23;;;4947:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;35173:1:::1;35151:19;:23;;;;35076:103:::0;:::o;37344:136::-;4966:12;:10;:12::i;:::-;4955:23;;:7;:5;:7::i;:::-;:23;;;4947:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;37454:19:::1;37433:18;:40;;;;37344:136:::0;:::o;35907:34::-;;;;:::o;34645:178::-;4966:12;:10;:12::i;:::-;4955:23;;:7;:5;:7::i;:::-;:23;;;4947:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;2690:1:::1;2828:7;;:19:::0;2820:63:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;2690:1;2888:7;:18;;;;34709:12:::2;34727:10;:15;;34750:21;34727:49;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34708:68;;;34790:7;34782:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;34702:121;2647:1:::1;2928:7;:22;;;;34645:178::o:0;36288:139::-;36355:7;36402:18;;36392:9;:28;;;;:::i;:::-;36385:35;;36288:139;;;:::o;32476:42::-;;;;:::o;38610:222::-;38758:4;2062:10:7;2054:18;;:4;:18;;;2050:81;;2088:32;2109:10;2088:20;:32::i;:::-;2050:81;38778:47:0::1;38801:4;38807:2;38811:7;38820:4;38778:22;:47::i;:::-;38610:222:::0;;;;;:::o;36142:140::-;4966:12;:10;:12::i;:::-;4955:23;;:7;:5;:7::i;:::-;:23;;;4947:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;36255:20:::1;36233:19;:42;;;;36142:140:::0;:::o;37760:110::-;4966:12;:10;:12::i;:::-;4955:23;;:7;:5;:7::i;:::-;:23;;;4947:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;37862:1:::1;37837:22;:26;;;;37760:110:::0;:::o;33762:99::-;4966:12;:10;:12::i;:::-;4955:23;;:7;:5;:7::i;:::-;:23;;;4947:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;33853:3:::1;33834:16;:22;;;;;;:::i;:::-;;33762:99:::0;:::o;33866:440::-;33939:13;33971:16;33979:7;33971;:16::i;:::-;33963:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;34063:5;34051:17;;:8;;;;;;;;;;;:17;;;34048:64;;34086:16;34079:23;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34048:64;34122:21;34146:10;:8;:10::i;:::-;34122:34;;34209:1;34191:7;34185:21;:25;:115;;;;;;;;;;;;;;;;;34252:7;34266:18;:7;:16;:18::i;:::-;34235:59;;;;;;;;;:::i;:::-;;;;;;;;;;;;;34185:115;34166:134;;;33866:440;;;;:::o;34391:105::-;34449:7;34471:20;34485:5;34471:13;:20::i;:::-;34464:27;;34391:105;;;:::o;36433:197::-;36516:4;36539:84;36558:6;36566:19;;36614:6;36597:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;36587:35;;;;;;36539:18;:84::i;:::-;36532:91;;36433:197;;;;:::o;35435:114::-;35493:7;35537:5;;35527:9;:15;;;;:::i;:::-;35520:22;;35435:114;;;:::o;35816:41::-;;;;:::o;37487:129::-;4966:12;:10;:12::i;:::-;4955:23;;:7;:5;:7::i;:::-;:23;;;4947:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;37589:20:::1;37570:16;:39;;;;37487:129:::0;:::o;19841:162::-;19938:4;19961:18;:25;19980:5;19961:25;;;;;;;;;;;;;;;:35;19987:8;19961:35;;;;;;;;;;;;;;;;;;;;;;;;;19954:42;;19841:162;;;;:::o;5148:198::-;4966:12;:10;:12::i;:::-;4955:23;;:7;:5;:7::i;:::-;:23;;;4947:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;5256:1:::1;5236:22;;:8;:22;;::::0;5228:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;5311:28;5330:8;5311:18;:28::i;:::-;5148:198:::0;:::o;9343:155::-;9428:4;9466:25;9451:40;;;:11;:40;;;;9444:47;;9343:155;;;:::o;21145:172::-;21202:4;21244:7;21225:15;:13;:15::i;:::-;:26;;:53;;;;;21265:13;;21255:7;:23;21225:53;:85;;;;;21283:11;:20;21295:7;21283:20;;;;;;;;;;;:27;;;;;;;;;;;;21282:28;21225:85;21218:92;;21145:172;;;:::o;2281:412:7:-;2518:1;836:42;2470:45;;;:49;2466:221;;;836:42;2540;;;2591:4;2598:8;2540:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2535:142;;2653:8;2634:28;;;;;;;;;;;:::i;:::-;;;;;;;;2535:142;2466:221;2281:412;:::o;18795:370:0:-;18875:13;18891:24;18907:7;18891:15;:24::i;:::-;18875:40;;18935:5;18929:11;;:2;:11;;;18925:48;;18949:24;;;;;;;;;;;;;;18925:48;19004:5;18988:21;;:12;:10;:12::i;:::-;:21;;;;:63;;;;;19014:37;19031:5;19038:12;:10;:12::i;:::-;19014:16;:37::i;:::-;19013:38;18988:63;18984:136;;;19074:35;;;;;;;;;;;;;;18984:136;19130:28;19139:2;19143:7;19152:5;19130:8;:28::i;:::-;18865:300;18795:370;;:::o;21323:102::-;21391:27;21401:2;21405:8;21391:27;;;;;;;;;;;;:9;:27::i;:::-;21323:102;;:::o;13786:90::-;13842:7;13868:1;13861:8;;13786:90;:::o;20065:164::-;20194:28;20204:4;20210:2;20214:7;20194:9;:28::i;:::-;20065:164;;;:::o;4386:96::-;4439:7;4465:10;4458:17;;4386:96;:::o;20295:179::-;20428:39;20445:4;20451:2;20455:7;20428:39;;;;;;;;;;;;:16;:39::i;:::-;20295:179;;;:::o;16436:1084::-;16498:21;;:::i;:::-;16531:12;16546:7;16531:22;;16611:4;16592:15;:13;:15::i;:::-;:23;;:47;;;;;16626:13;;16619:4;:20;16592:47;16588:868;;;16659:31;16693:11;:17;16705:4;16693:17;;;;;;;;;;;16659:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16733:9;:16;;;16728:714;;16803:1;16777:28;;:9;:14;;;:28;;;16773:99;;16840:9;16833:16;;;;;;16773:99;17169:255;17176:4;17169:255;;;17208:6;;;;;;;;17252:11;:17;17264:4;17252:17;;;;;;;;;;;17240:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17325:1;17299:28;;:9;:14;;;:28;;;17295:107;;17366:9;17359:16;;;;;;17295:107;17169:255;;;16728:714;16641:815;16588:868;17482:31;;;;;;;;;;;;;;16436:1084;;;;:::o;5353:187::-;5426:16;5445:6;;;;;;;;;;;5426:25;;5470:8;5461:6;;:17;;;;;;;;;;;;;;;;;;5524:8;5493:40;;5514:8;5493:40;;;;;;;;;;;;5416:124;5353:187;:::o;19493:282::-;19603:12;:10;:12::i;:::-;19591:24;;:8;:24;;;19587:54;;19624:17;;;;;;;;;;;;;;19587:54;19697:8;19652:18;:32;19671:12;:10;:12::i;:::-;19652:32;;;;;;;;;;;;;;;:42;19685:8;19652:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;19749:8;19720:48;;19735:12;:10;:12::i;:::-;19720:48;;;19759:8;19720:48;;;;;;:::i;:::-;;;;;;;;19493:282;;:::o;20540:359::-;20701:28;20711:4;20717:2;20721:7;20701:9;:28::i;:::-;20743:15;:2;:13;;;:15::i;:::-;:76;;;;;20763:56;20794:4;20800:2;20804:7;20813:5;20763:30;:56::i;:::-;20762:57;20743:76;20739:154;;;20842:40;;;;;;;;;;;;;;20739:154;20540:359;;;;:::o;33651:106::-;33711:13;33739;33732:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33651:106;:::o;3049:516::-;3105:13;3144:1;3135:5;:10;3131:51;;3161:10;;;;;;;;;;;;;;;;;;;;;3131:51;3191:12;3206:5;3191:20;;3221:14;3245:75;3260:1;3252:4;:9;3245:75;;3277:8;;;;;:::i;:::-;;;;3307:2;3299:10;;;;;:::i;:::-;;;3245:75;;;3329:19;3361:6;3351:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3329:39;;3378:150;3394:1;3385:5;:10;3378:150;;3421:1;3411:11;;;;;:::i;:::-;;;3487:2;3479:5;:10;;;;:::i;:::-;3466:2;:24;;;;:::i;:::-;3453:39;;3436:6;3443;3436:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;3515:2;3506:11;;;;;:::i;:::-;;;3378:150;;;3551:6;3537:21;;;;;3049:516;;;;:::o;15373:135::-;15434:7;15468:12;:19;15481:5;15468:19;;;;;;;;;;;;;;;:32;;;;;;;;;;;;15460:41;;15453:48;;15373:135;;;:::o;1141:184::-;1262:4;1314;1285:25;1298:5;1305:4;1285:12;:25::i;:::-;:33;1278:40;;1141:184;;;;;:::o;29085:189::-;29222:2;29195:15;:24;29211:7;29195:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;29259:7;29255:2;29239:28;;29248:5;29239:28;;;;;;;;;;;;29085:189;;;:::o;21776:157::-;21894:32;21900:2;21904:8;21914:5;21921:4;21894:5;:32::i;:::-;21776:157;;;:::o;24155:2082::-;24265:35;24303:21;24316:7;24303:12;:21::i;:::-;24265:59;;24361:4;24339:26;;:13;:18;;;:26;;;24335:67;;24374:28;;;;;;;;;;;;;;24335:67;24413:22;24455:4;24439:20;;:12;:10;:12::i;:::-;:20;;;:72;;;;24475:36;24492:4;24498:12;:10;:12::i;:::-;24475:16;:36::i;:::-;24439:72;:124;;;;24551:12;:10;:12::i;:::-;24527:36;;:20;24539:7;24527:11;:20::i;:::-;:36;;;24439:124;24413:151;;24580:17;24575:66;;24606:35;;;;;;;;;;;;;;24575:66;24669:1;24655:16;;:2;:16;;;24651:52;;24680:23;;;;;;;;;;;;;;24651:52;24714:43;24736:4;24742:2;24746:7;24755:1;24714:21;:43::i;:::-;24819:35;24836:1;24840:7;24849:4;24819:8;:35::i;:::-;25174:1;25144:12;:18;25157:4;25144:18;;;;;;;;;;;;;;;:26;;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25217:1;25189:12;:16;25202:2;25189:16;;;;;;;;;;;;;;;:24;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25233:31;25267:11;:20;25279:7;25267:20;;;;;;;;;;;25233:54;;25317:2;25301:8;:13;;;:18;;;;;;;;;;;;;;;;;;25366:15;25333:8;:23;;;:49;;;;;;;;;;;;;;;;;;25630:19;25662:1;25652:7;:11;25630:33;;25677:31;25711:11;:24;25723:11;25711:24;;;;;;;;;;;25677:58;;25778:1;25753:27;;:8;:13;;;;;;;;;;;;:27;;;25749:377;;25960:13;;25945:11;:28;25941:171;;26013:4;25997:8;:13;;;:20;;;;;;;;;;;;;;;;;;26065:13;:28;;;26039:8;:23;;;:54;;;;;;;;;;;;;;;;;;25941:171;25749:377;25120:1016;;;26170:7;26166:2;26151:27;;26160:4;26151:27;;;;;;;;;;;;26188:42;26209:4;26215:2;26219:7;26228:1;26188:20;:42::i;:::-;24255:1982;;24155:2082;;;:::o;5568:191::-;5628:4;5645:12;5710:7;5698:20;5690:28;;5751:1;5744:4;:8;5737:15;;;5568:191;;;:::o;29755:650::-;29913:4;29949:2;29933:36;;;29970:12;:10;:12::i;:::-;29984:4;29990:7;29999:5;29933:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;29929:470;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30181:1;30164:6;:13;:18;30160:229;;30209:40;;;;;;;;;;;;;;30160:229;30349:6;30343:13;30334:6;30330:2;30326:15;30319:38;29929:470;30061:45;;;30051:55;;;:6;:55;;;;30044:62;;;29755:650;;;;;;:::o;1676:662::-;1759:7;1778:20;1801:4;1778:27;;1820:9;1815:488;1839:5;:12;1835:1;:16;1815:488;;;1872:20;1895:5;1901:1;1895:8;;;;;;;;:::i;:::-;;;;;;;;1872:31;;1937:12;1921;:28;1917:376;;2062:42;2077:12;2091;2062:14;:42::i;:::-;2047:57;;1917:376;;;2236:42;2251:12;2265;2236:14;:42::i;:::-;2221:57;;1917:376;1858:445;1853:3;;;;;:::i;:::-;;;;1815:488;;;;2319:12;2312:19;;;1676:662;;;;:::o;22180:1733::-;22313:20;22336:13;;22313:36;;22377:1;22363:16;;:2;:16;;;22359:48;;22388:19;;;;;;;;;;;;;;22359:48;22433:1;22421:8;:13;22417:44;;22443:18;;;;;;;;;;;;;;22417:44;22472:61;22502:1;22506:2;22510:12;22524:8;22472:21;:61::i;:::-;22839:8;22804:12;:16;22817:2;22804:16;;;;;;;;;;;;;;;:24;;;:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22902:8;22862:12;:16;22875:2;22862:16;;;;;;;;;;;;;;;:29;;;:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22959:2;22926:11;:25;22938:12;22926:25;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;23025:15;22975:11;:25;22987:12;22975:25;;;;;;;;;;;:40;;;:66;;;;;;;;;;;;;;;;;;23056:20;23079:12;23056:35;;23105:11;23134:8;23119:12;:23;23105:37;;23161:4;:23;;;;;23169:15;:2;:13;;;:15::i;:::-;23161:23;23157:628;;;23204:309;23259:12;23255:2;23234:38;;23251:1;23234:38;;;;;;;;;;;;23299:69;23338:1;23342:2;23346:14;;;;;;23362:5;23299:30;:69::i;:::-;23294:172;;23403:40;;;;;;;;;;;;;;23294:172;23508:3;23492:12;:19;23204:309;;23592:12;23575:13;;:29;23571:43;;23606:8;;;23571:43;23157:628;;;23653:118;23708:14;;;;;;23704:2;23683:40;;23700:1;23683:40;;;;;;;;;;;;23766:3;23750:12;:19;23653:118;;23157:628;23814:12;23798:13;:28;;;;22780:1057;;23846:60;23875:1;23879:2;23883:12;23897:8;23846:20;:60::i;:::-;22303:1610;22180:1733;;;;:::o;31036:154::-;;;;;:::o;31831:153::-;;;;;:::o;2344:218::-;2412:13;2473:1;2467:4;2460:15;2501:1;2495:4;2488:15;2541:4;2535;2525:21;2516:30;;2344:218;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:14:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:77::-;2897:7;2926:5;2915:16;;2860:77;;;:::o;2943:122::-;3016:24;3034:5;3016:24;:::i;:::-;3009:5;3006:35;2996:63;;3055:1;3052;3045:12;2996:63;2943:122;:::o;3071:139::-;3117:5;3155:6;3142:20;3133:29;;3171:33;3198:5;3171:33;:::i;:::-;3071:139;;;;:::o;3216:329::-;3275:6;3324:2;3312:9;3303:7;3299:23;3295:32;3292:119;;;3330:79;;:::i;:::-;3292:119;3450:1;3475:53;3520:7;3511:6;3500:9;3496:22;3475:53;:::i;:::-;3465:63;;3421:117;3216:329;;;;:::o;3551:126::-;3588:7;3628:42;3621:5;3617:54;3606:65;;3551:126;;;:::o;3683:96::-;3720:7;3749:24;3767:5;3749:24;:::i;:::-;3738:35;;3683:96;;;:::o;3785:118::-;3872:24;3890:5;3872:24;:::i;:::-;3867:3;3860:37;3785:118;;:::o;3909:222::-;4002:4;4040:2;4029:9;4025:18;4017:26;;4053:71;4121:1;4110:9;4106:17;4097:6;4053:71;:::i;:::-;3909:222;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:474::-;4478:6;4486;4535:2;4523:9;4514:7;4510:23;4506:32;4503:119;;;4541:79;;:::i;:::-;4503:119;4661:1;4686:53;4731:7;4722:6;4711:9;4707:22;4686:53;:::i;:::-;4676:63;;4632:117;4788:2;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4759:118;4410:474;;;;;:::o;4890:118::-;4977:24;4995:5;4977:24;:::i;:::-;4972:3;4965:37;4890:118;;:::o;5014:222::-;5107:4;5145:2;5134:9;5130:18;5122:26;;5158:71;5226:1;5215:9;5211:17;5202:6;5158:71;:::i;:::-;5014:222;;;;:::o;5242:117::-;5351:1;5348;5341:12;5365:117;5474:1;5471;5464:12;5488:117;5597:1;5594;5587:12;5628:568;5701:8;5711:6;5761:3;5754:4;5746:6;5742:17;5738:27;5728:122;;5769:79;;:::i;:::-;5728:122;5882:6;5869:20;5859:30;;5912:18;5904:6;5901:30;5898:117;;;5934:79;;:::i;:::-;5898:117;6048:4;6040:6;6036:17;6024:29;;6102:3;6094:4;6086:6;6082:17;6072:8;6068:32;6065:41;6062:128;;;6109:79;;:::i;:::-;6062:128;5628:568;;;;;:::o;6202:704::-;6297:6;6305;6313;6362:2;6350:9;6341:7;6337:23;6333:32;6330:119;;;6368:79;;:::i;:::-;6330:119;6488:1;6513:53;6558:7;6549:6;6538:9;6534:22;6513:53;:::i;:::-;6503:63;;6459:117;6643:2;6632:9;6628:18;6615:32;6674:18;6666:6;6663:30;6660:117;;;6696:79;;:::i;:::-;6660:117;6809:80;6881:7;6872:6;6861:9;6857:22;6809:80;:::i;:::-;6791:98;;;;6586:313;6202:704;;;;;:::o;6912:329::-;6971:6;7020:2;7008:9;6999:7;6995:23;6991:32;6988:119;;;7026:79;;:::i;:::-;6988:119;7146:1;7171:53;7216:7;7207:6;7196:9;7192:22;7171:53;:::i;:::-;7161:63;;7117:117;6912:329;;;;:::o;7247:619::-;7324:6;7332;7340;7389:2;7377:9;7368:7;7364:23;7360:32;7357:119;;;7395:79;;:::i;:::-;7357:119;7515:1;7540:53;7585:7;7576:6;7565:9;7561:22;7540:53;:::i;:::-;7530:63;;7486:117;7642:2;7668:53;7713:7;7704:6;7693:9;7689:22;7668:53;:::i;:::-;7658:63;;7613:118;7770:2;7796:53;7841:7;7832:6;7821:9;7817:22;7796:53;:::i;:::-;7786:63;;7741:118;7247:619;;;;;:::o;7872:60::-;7900:3;7921:5;7914:12;;7872:60;;;:::o;7938:142::-;7988:9;8021:53;8039:34;8048:24;8066:5;8048:24;:::i;:::-;8039:34;:::i;:::-;8021:53;:::i;:::-;8008:66;;7938:142;;;:::o;8086:126::-;8136:9;8169:37;8200:5;8169:37;:::i;:::-;8156:50;;8086:126;;;:::o;8218:158::-;8300:9;8333:37;8364:5;8333:37;:::i;:::-;8320:50;;8218:158;;;:::o;8382:195::-;8501:69;8564:5;8501:69;:::i;:::-;8496:3;8489:82;8382:195;;:::o;8583:286::-;8708:4;8746:2;8735:9;8731:18;8723:26;;8759:103;8859:1;8848:9;8844:17;8835:6;8759:103;:::i;:::-;8583:286;;;;:::o;8875:117::-;8984:1;8981;8974:12;8998:180;9046:77;9043:1;9036:88;9143:4;9140:1;9133:15;9167:4;9164:1;9157:15;9184:281;9267:27;9289:4;9267:27;:::i;:::-;9259:6;9255:40;9397:6;9385:10;9382:22;9361:18;9349:10;9346:34;9343:62;9340:88;;;9408:18;;:::i;:::-;9340:88;9448:10;9444:2;9437:22;9227:238;9184:281;;:::o;9471:129::-;9505:6;9532:20;;:::i;:::-;9522:30;;9561:33;9589:4;9581:6;9561:33;:::i;:::-;9471:129;;;:::o;9606:308::-;9668:4;9758:18;9750:6;9747:30;9744:56;;;9780:18;;:::i;:::-;9744:56;9818:29;9840:6;9818:29;:::i;:::-;9810:37;;9902:4;9896;9892:15;9884:23;;9606:308;;;:::o;9920:146::-;10017:6;10012:3;10007;9994:30;10058:1;10049:6;10044:3;10040:16;10033:27;9920:146;;;:::o;10072:425::-;10150:5;10175:66;10191:49;10233:6;10191:49;:::i;:::-;10175:66;:::i;:::-;10166:75;;10264:6;10257:5;10250:21;10302:4;10295:5;10291:16;10340:3;10331:6;10326:3;10322:16;10319:25;10316:112;;;10347:79;;:::i;:::-;10316:112;10437:54;10484:6;10479:3;10474;10437:54;:::i;:::-;10156:341;10072:425;;;;;:::o;10517:340::-;10573:5;10622:3;10615:4;10607:6;10603:17;10599:27;10589:122;;10630:79;;:::i;:::-;10589:122;10747:6;10734:20;10772:79;10847:3;10839:6;10832:4;10824:6;10820:17;10772:79;:::i;:::-;10763:88;;10579:278;10517:340;;;;:::o;10863:509::-;10932:6;10981:2;10969:9;10960:7;10956:23;10952:32;10949:119;;;10987:79;;:::i;:::-;10949:119;11135:1;11124:9;11120:17;11107:31;11165:18;11157:6;11154:30;11151:117;;;11187:79;;:::i;:::-;11151:117;11292:63;11347:7;11338:6;11327:9;11323:22;11292:63;:::i;:::-;11282:73;;11078:287;10863:509;;;;:::o;11378:108::-;11455:24;11473:5;11455:24;:::i;:::-;11450:3;11443:37;11378:108;;:::o;11492:101::-;11528:7;11568:18;11561:5;11557:30;11546:41;;11492:101;;;:::o;11599:105::-;11674:23;11691:5;11674:23;:::i;:::-;11669:3;11662:36;11599:105;;:::o;11710:99::-;11781:21;11796:5;11781:21;:::i;:::-;11776:3;11769:34;11710:99;;:::o;11885:697::-;12044:4;12039:3;12035:14;12131:4;12124:5;12120:16;12114:23;12150:63;12207:4;12202:3;12198:14;12184:12;12150:63;:::i;:::-;12059:164;12315:4;12308:5;12304:16;12298:23;12334:61;12389:4;12384:3;12380:14;12366:12;12334:61;:::i;:::-;12233:172;12489:4;12482:5;12478:16;12472:23;12508:57;12559:4;12554:3;12550:14;12536:12;12508:57;:::i;:::-;12415:160;12013:569;11885:697;;:::o;12588:346::-;12743:4;12781:2;12770:9;12766:18;12758:26;;12794:133;12924:1;12913:9;12909:17;12900:6;12794:133;:::i;:::-;12588:346;;;;:::o;12940:116::-;13010:21;13025:5;13010:21;:::i;:::-;13003:5;13000:32;12990:60;;13046:1;13043;13036:12;12990:60;12940:116;:::o;13062:133::-;13105:5;13143:6;13130:20;13121:29;;13159:30;13183:5;13159:30;:::i;:::-;13062:133;;;;:::o;13201:468::-;13266:6;13274;13323:2;13311:9;13302:7;13298:23;13294:32;13291:119;;;13329:79;;:::i;:::-;13291:119;13449:1;13474:53;13519:7;13510:6;13499:9;13495:22;13474:53;:::i;:::-;13464:63;;13420:117;13576:2;13602:50;13644:7;13635:6;13624:9;13620:22;13602:50;:::i;:::-;13592:60;;13547:115;13201:468;;;;;:::o;13675:77::-;13712:7;13741:5;13730:16;;13675:77;;;:::o;13758:118::-;13845:24;13863:5;13845:24;:::i;:::-;13840:3;13833:37;13758:118;;:::o;13882:222::-;13975:4;14013:2;14002:9;13998:18;13990:26;;14026:71;14094:1;14083:9;14079:17;14070:6;14026:71;:::i;:::-;13882:222;;;;:::o;14110:307::-;14171:4;14261:18;14253:6;14250:30;14247:56;;;14283:18;;:::i;:::-;14247:56;14321:29;14343:6;14321:29;:::i;:::-;14313:37;;14405:4;14399;14395:15;14387:23;;14110:307;;;:::o;14423:423::-;14500:5;14525:65;14541:48;14582:6;14541:48;:::i;:::-;14525:65;:::i;:::-;14516:74;;14613:6;14606:5;14599:21;14651:4;14644:5;14640:16;14689:3;14680:6;14675:3;14671:16;14668:25;14665:112;;;14696:79;;:::i;:::-;14665:112;14786:54;14833:6;14828:3;14823;14786:54;:::i;:::-;14506:340;14423:423;;;;;:::o;14865:338::-;14920:5;14969:3;14962:4;14954:6;14950:17;14946:27;14936:122;;14977:79;;:::i;:::-;14936:122;15094:6;15081:20;15119:78;15193:3;15185:6;15178:4;15170:6;15166:17;15119:78;:::i;:::-;15110:87;;14926:277;14865:338;;;;:::o;15209:943::-;15304:6;15312;15320;15328;15377:3;15365:9;15356:7;15352:23;15348:33;15345:120;;;15384:79;;:::i;:::-;15345:120;15504:1;15529:53;15574:7;15565:6;15554:9;15550:22;15529:53;:::i;:::-;15519:63;;15475:117;15631:2;15657:53;15702:7;15693:6;15682:9;15678:22;15657:53;:::i;:::-;15647:63;;15602:118;15759:2;15785:53;15830:7;15821:6;15810:9;15806:22;15785:53;:::i;:::-;15775:63;;15730:118;15915:2;15904:9;15900:18;15887:32;15946:18;15938:6;15935:30;15932:117;;;15968:79;;:::i;:::-;15932:117;16073:62;16127:7;16118:6;16107:9;16103:22;16073:62;:::i;:::-;16063:72;;15858:287;15209:943;;;;;;;:::o;16158:122::-;16231:24;16249:5;16231:24;:::i;:::-;16224:5;16221:35;16211:63;;16270:1;16267;16260:12;16211:63;16158:122;:::o;16286:139::-;16332:5;16370:6;16357:20;16348:29;;16386:33;16413:5;16386:33;:::i;:::-;16286:139;;;;:::o;16431:329::-;16490:6;16539:2;16527:9;16518:7;16514:23;16510:32;16507:119;;;16545:79;;:::i;:::-;16507:119;16665:1;16690:53;16735:7;16726:6;16715:9;16711:22;16690:53;:::i;:::-;16680:63;;16636:117;16431:329;;;;:::o;16766:311::-;16843:4;16933:18;16925:6;16922:30;16919:56;;;16955:18;;:::i;:::-;16919:56;17005:4;16997:6;16993:17;16985:25;;17065:4;17059;17055:15;17047:23;;16766:311;;;:::o;17100:710::-;17196:5;17221:81;17237:64;17294:6;17237:64;:::i;:::-;17221:81;:::i;:::-;17212:90;;17322:5;17351:6;17344:5;17337:21;17385:4;17378:5;17374:16;17367:23;;17438:4;17430:6;17426:17;17418:6;17414:30;17467:3;17459:6;17456:15;17453:122;;;17486:79;;:::i;:::-;17453:122;17601:6;17584:220;17618:6;17613:3;17610:15;17584:220;;;17693:3;17722:37;17755:3;17743:10;17722:37;:::i;:::-;17717:3;17710:50;17789:4;17784:3;17780:14;17773:21;;17660:144;17644:4;17639:3;17635:14;17628:21;;17584:220;;;17588:21;17202:608;;17100:710;;;;;:::o;17833:370::-;17904:5;17953:3;17946:4;17938:6;17934:17;17930:27;17920:122;;17961:79;;:::i;:::-;17920:122;18078:6;18065:20;18103:94;18193:3;18185:6;18178:4;18170:6;18166:17;18103:94;:::i;:::-;18094:103;;17910:293;17833:370;;;;:::o;18209:684::-;18302:6;18310;18359:2;18347:9;18338:7;18334:23;18330:32;18327:119;;;18365:79;;:::i;:::-;18327:119;18513:1;18502:9;18498:17;18485:31;18543:18;18535:6;18532:30;18529:117;;;18565:79;;:::i;:::-;18529:117;18670:78;18740:7;18731:6;18720:9;18716:22;18670:78;:::i;:::-;18660:88;;18456:302;18797:2;18823:53;18868:7;18859:6;18848:9;18844:22;18823:53;:::i;:::-;18813:63;;18768:118;18209:684;;;;;:::o;18899:474::-;18967:6;18975;19024:2;19012:9;19003:7;18999:23;18995:32;18992:119;;;19030:79;;:::i;:::-;18992:119;19150:1;19175:53;19220:7;19211:6;19200:9;19196:22;19175:53;:::i;:::-;19165:63;;19121:117;19277:2;19303:53;19348:7;19339:6;19328:9;19324:22;19303:53;:::i;:::-;19293:63;;19248:118;18899:474;;;;;:::o;19379:180::-;19427:77;19424:1;19417:88;19524:4;19521:1;19514:15;19548:4;19545:1;19538:15;19565:320;19609:6;19646:1;19640:4;19636:12;19626:22;;19693:1;19687:4;19683:12;19714:18;19704:81;;19770:4;19762:6;19758:17;19748:27;;19704:81;19832:2;19824:6;19821:14;19801:18;19798:38;19795:84;;19851:18;;:::i;:::-;19795:84;19616:269;19565:320;;;:::o;19891:169::-;20031:21;20027:1;20019:6;20015:14;20008:45;19891:169;:::o;20066:366::-;20208:3;20229:67;20293:2;20288:3;20229:67;:::i;:::-;20222:74;;20305:93;20394:3;20305:93;:::i;:::-;20423:2;20418:3;20414:12;20407:19;;20066:366;;;:::o;20438:419::-;20604:4;20642:2;20631:9;20627:18;20619:26;;20691:9;20685:4;20681:20;20677:1;20666:9;20662:17;20655:47;20719:131;20845:4;20719:131;:::i;:::-;20711:139;;20438:419;;;:::o;20863:180::-;20911:77;20908:1;20901:88;21008:4;21005:1;20998:15;21032:4;21029:1;21022:15;21049:191;21089:3;21108:20;21126:1;21108:20;:::i;:::-;21103:25;;21142:20;21160:1;21142:20;:::i;:::-;21137:25;;21185:1;21182;21178:9;21171:16;;21206:3;21203:1;21200:10;21197:36;;;21213:18;;:::i;:::-;21197:36;21049:191;;;;:::o;21246:225::-;21386:34;21382:1;21374:6;21370:14;21363:58;21455:8;21450:2;21442:6;21438:15;21431:33;21246:225;:::o;21477:366::-;21619:3;21640:67;21704:2;21699:3;21640:67;:::i;:::-;21633:74;;21716:93;21805:3;21716:93;:::i;:::-;21834:2;21829:3;21825:12;21818:19;;21477:366;;;:::o;21849:419::-;22015:4;22053:2;22042:9;22038:18;22030:26;;22102:9;22096:4;22092:20;22088:1;22077:9;22073:17;22066:47;22130:131;22256:4;22130:131;:::i;:::-;22122:139;;21849:419;;;:::o;22274:172::-;22414:24;22410:1;22402:6;22398:14;22391:48;22274:172;:::o;22452:366::-;22594:3;22615:67;22679:2;22674:3;22615:67;:::i;:::-;22608:74;;22691:93;22780:3;22691:93;:::i;:::-;22809:2;22804:3;22800:12;22793:19;;22452:366;;;:::o;22824:419::-;22990:4;23028:2;23017:9;23013:18;23005:26;;23077:9;23071:4;23067:20;23063:1;23052:9;23048:17;23041:47;23105:131;23231:4;23105:131;:::i;:::-;23097:139;;22824:419;;;:::o;23249:410::-;23289:7;23312:20;23330:1;23312:20;:::i;:::-;23307:25;;23346:20;23364:1;23346:20;:::i;:::-;23341:25;;23401:1;23398;23394:9;23423:30;23441:11;23423:30;:::i;:::-;23412:41;;23602:1;23593:7;23589:15;23586:1;23583:22;23563:1;23556:9;23536:83;23513:139;;23632:18;;:::i;:::-;23513:139;23297:362;23249:410;;;;:::o;23665:170::-;23805:22;23801:1;23793:6;23789:14;23782:46;23665:170;:::o;23841:366::-;23983:3;24004:67;24068:2;24063:3;24004:67;:::i;:::-;23997:74;;24080:93;24169:3;24080:93;:::i;:::-;24198:2;24193:3;24189:12;24182:19;;23841:366;;;:::o;24213:419::-;24379:4;24417:2;24406:9;24402:18;24394:26;;24466:9;24460:4;24456:20;24452:1;24441:9;24437:17;24430:47;24494:131;24620:4;24494:131;:::i;:::-;24486:139;;24213:419;;;:::o;24638:172::-;24778:24;24774:1;24766:6;24762:14;24755:48;24638:172;:::o;24816:366::-;24958:3;24979:67;25043:2;25038:3;24979:67;:::i;:::-;24972:74;;25055:93;25144:3;25055:93;:::i;:::-;25173:2;25168:3;25164:12;25157:19;;24816:366;;;:::o;25188:419::-;25354:4;25392:2;25381:9;25377:18;25369:26;;25441:9;25435:4;25431:20;25427:1;25416:9;25412:17;25405:47;25469:131;25595:4;25469:131;:::i;:::-;25461:139;;25188:419;;;:::o;25613:178::-;25753:30;25749:1;25741:6;25737:14;25730:54;25613:178;:::o;25797:366::-;25939:3;25960:67;26024:2;26019:3;25960:67;:::i;:::-;25953:74;;26036:93;26125:3;26036:93;:::i;:::-;26154:2;26149:3;26145:12;26138:19;;25797:366;;;:::o;26169:419::-;26335:4;26373:2;26362:9;26358:18;26350:26;;26422:9;26416:4;26412:20;26408:1;26397:9;26393:17;26386:47;26450:131;26576:4;26450:131;:::i;:::-;26442:139;;26169:419;;;:::o;26594:182::-;26734:34;26730:1;26722:6;26718:14;26711:58;26594:182;:::o;26782:366::-;26924:3;26945:67;27009:2;27004:3;26945:67;:::i;:::-;26938:74;;27021:93;27110:3;27021:93;:::i;:::-;27139:2;27134:3;27130:12;27123:19;;26782:366;;;:::o;27154:419::-;27320:4;27358:2;27347:9;27343:18;27335:26;;27407:9;27401:4;27397:20;27393:1;27382:9;27378:17;27371:47;27435:131;27561:4;27435:131;:::i;:::-;27427:139;;27154:419;;;:::o;27579:141::-;27628:4;27651:3;27643:11;;27674:3;27671:1;27664:14;27708:4;27705:1;27695:18;27687:26;;27579:141;;;:::o;27726:93::-;27763:6;27810:2;27805;27798:5;27794:14;27790:23;27780:33;;27726:93;;;:::o;27825:107::-;27869:8;27919:5;27913:4;27909:16;27888:37;;27825:107;;;;:::o;27938:393::-;28007:6;28057:1;28045:10;28041:18;28080:97;28110:66;28099:9;28080:97;:::i;:::-;28198:39;28228:8;28217:9;28198:39;:::i;:::-;28186:51;;28270:4;28266:9;28259:5;28255:21;28246:30;;28319:4;28309:8;28305:19;28298:5;28295:30;28285:40;;28014:317;;27938:393;;;;;:::o;28337:142::-;28387:9;28420:53;28438:34;28447:24;28465:5;28447:24;:::i;:::-;28438:34;:::i;:::-;28420:53;:::i;:::-;28407:66;;28337:142;;;:::o;28485:75::-;28528:3;28549:5;28542:12;;28485:75;;;:::o;28566:269::-;28676:39;28707:7;28676:39;:::i;:::-;28737:91;28786:41;28810:16;28786:41;:::i;:::-;28778:6;28771:4;28765:11;28737:91;:::i;:::-;28731:4;28724:105;28642:193;28566:269;;;:::o;28841:73::-;28886:3;28841:73;:::o;28920:189::-;28997:32;;:::i;:::-;29038:65;29096:6;29088;29082:4;29038:65;:::i;:::-;28973:136;28920:189;;:::o;29115:186::-;29175:120;29192:3;29185:5;29182:14;29175:120;;;29246:39;29283:1;29276:5;29246:39;:::i;:::-;29219:1;29212:5;29208:13;29199:22;;29175:120;;;29115:186;;:::o;29307:543::-;29408:2;29403:3;29400:11;29397:446;;;29442:38;29474:5;29442:38;:::i;:::-;29526:29;29544:10;29526:29;:::i;:::-;29516:8;29512:44;29709:2;29697:10;29694:18;29691:49;;;29730:8;29715:23;;29691:49;29753:80;29809:22;29827:3;29809:22;:::i;:::-;29799:8;29795:37;29782:11;29753:80;:::i;:::-;29412:431;;29397:446;29307:543;;;:::o;29856:117::-;29910:8;29960:5;29954:4;29950:16;29929:37;;29856:117;;;;:::o;29979:169::-;30023:6;30056:51;30104:1;30100:6;30092:5;30089:1;30085:13;30056:51;:::i;:::-;30052:56;30137:4;30131;30127:15;30117:25;;30030:118;29979:169;;;;:::o;30153:295::-;30229:4;30375:29;30400:3;30394:4;30375:29;:::i;:::-;30367:37;;30437:3;30434:1;30430:11;30424:4;30421:21;30413:29;;30153:295;;;;:::o;30453:1395::-;30570:37;30603:3;30570:37;:::i;:::-;30672:18;30664:6;30661:30;30658:56;;;30694:18;;:::i;:::-;30658:56;30738:38;30770:4;30764:11;30738:38;:::i;:::-;30823:67;30883:6;30875;30869:4;30823:67;:::i;:::-;30917:1;30941:4;30928:17;;30973:2;30965:6;30962:14;30990:1;30985:618;;;;31647:1;31664:6;31661:77;;;31713:9;31708:3;31704:19;31698:26;31689:35;;31661:77;31764:67;31824:6;31817:5;31764:67;:::i;:::-;31758:4;31751:81;31620:222;30955:887;;30985:618;31037:4;31033:9;31025:6;31021:22;31071:37;31103:4;31071:37;:::i;:::-;31130:1;31144:208;31158:7;31155:1;31152:14;31144:208;;;31237:9;31232:3;31228:19;31222:26;31214:6;31207:42;31288:1;31280:6;31276:14;31266:24;;31335:2;31324:9;31320:18;31307:31;;31181:4;31178:1;31174:12;31169:17;;31144:208;;;31380:6;31371:7;31368:19;31365:179;;;31438:9;31433:3;31429:19;31423:26;31481:48;31523:4;31515:6;31511:17;31500:9;31481:48;:::i;:::-;31473:6;31466:64;31388:156;31365:179;31590:1;31586;31578:6;31574:14;31570:22;31564:4;31557:36;30992:611;;;30955:887;;30545:1303;;;30453:1395;;:::o;31854:168::-;31994:20;31990:1;31982:6;31978:14;31971:44;31854:168;:::o;32028:366::-;32170:3;32191:67;32255:2;32250:3;32191:67;:::i;:::-;32184:74;;32267:93;32356:3;32267:93;:::i;:::-;32385:2;32380:3;32376:12;32369:19;;32028:366;;;:::o;32400:419::-;32566:4;32604:2;32593:9;32589:18;32581:26;;32653:9;32647:4;32643:20;32639:1;32628:9;32624:17;32617:47;32681:131;32807:4;32681:131;:::i;:::-;32673:139;;32400:419;;;:::o;32825:180::-;32965:32;32961:1;32953:6;32949:14;32942:56;32825:180;:::o;33011:366::-;33153:3;33174:67;33238:2;33233:3;33174:67;:::i;:::-;33167:74;;33250:93;33339:3;33250:93;:::i;:::-;33368:2;33363:3;33359:12;33352:19;;33011:366;;;:::o;33383:419::-;33549:4;33587:2;33576:9;33572:18;33564:26;;33636:9;33630:4;33626:20;33622:1;33611:9;33607:17;33600:47;33664:131;33790:4;33664:131;:::i;:::-;33656:139;;33383:419;;;:::o;33808:168::-;33948:20;33944:1;33936:6;33932:14;33925:44;33808:168;:::o;33982:366::-;34124:3;34145:67;34209:2;34204:3;34145:67;:::i;:::-;34138:74;;34221:93;34310:3;34221:93;:::i;:::-;34339:2;34334:3;34330:12;34323:19;;33982:366;;;:::o;34354:419::-;34520:4;34558:2;34547:9;34543:18;34535:26;;34607:9;34601:4;34597:20;34593:1;34582:9;34578:17;34571:47;34635:131;34761:4;34635:131;:::i;:::-;34627:139;;34354:419;;;:::o;34779:174::-;34919:26;34915:1;34907:6;34903:14;34896:50;34779:174;:::o;34959:366::-;35101:3;35122:67;35186:2;35181:3;35122:67;:::i;:::-;35115:74;;35198:93;35287:3;35198:93;:::i;:::-;35316:2;35311:3;35307:12;35300:19;;34959:366;;;:::o;35331:419::-;35497:4;35535:2;35524:9;35520:18;35512:26;;35584:9;35578:4;35574:20;35570:1;35559:9;35555:17;35548:47;35612:131;35738:4;35612:131;:::i;:::-;35604:139;;35331:419;;;:::o;35756:172::-;35896:24;35892:1;35884:6;35880:14;35873:48;35756:172;:::o;35934:366::-;36076:3;36097:67;36161:2;36156:3;36097:67;:::i;:::-;36090:74;;36173:93;36262:3;36173:93;:::i;:::-;36291:2;36286:3;36282:12;36275:19;;35934:366;;;:::o;36306:419::-;36472:4;36510:2;36499:9;36495:18;36487:26;;36559:9;36553:4;36549:20;36545:1;36534:9;36530:17;36523:47;36587:131;36713:4;36587:131;:::i;:::-;36579:139;;36306:419;;;:::o;36731:181::-;36871:33;36867:1;36859:6;36855:14;36848:57;36731:181;:::o;36918:366::-;37060:3;37081:67;37145:2;37140:3;37081:67;:::i;:::-;37074:74;;37157:93;37246:3;37157:93;:::i;:::-;37275:2;37270:3;37266:12;37259:19;;36918:366;;;:::o;37290:419::-;37456:4;37494:2;37483:9;37479:18;37471:26;;37543:9;37537:4;37533:20;37529:1;37518:9;37514:17;37507:47;37571:131;37697:4;37571:131;:::i;:::-;37563:139;;37290:419;;;:::o;37715:147::-;37816:11;37853:3;37838:18;;37715:147;;;;:::o;37868:114::-;;:::o;37988:398::-;38147:3;38168:83;38249:1;38244:3;38168:83;:::i;:::-;38161:90;;38260:93;38349:3;38260:93;:::i;:::-;38378:1;38373:3;38369:11;38362:18;;37988:398;;;:::o;38392:379::-;38576:3;38598:147;38741:3;38598:147;:::i;:::-;38591:154;;38762:3;38755:10;;38392:379;;;:::o;38777:166::-;38917:18;38913:1;38905:6;38901:14;38894:42;38777:166;:::o;38949:366::-;39091:3;39112:67;39176:2;39171:3;39112:67;:::i;:::-;39105:74;;39188:93;39277:3;39188:93;:::i;:::-;39306:2;39301:3;39297:12;39290:19;;38949:366;;;:::o;39321:419::-;39487:4;39525:2;39514:9;39510:18;39502:26;;39574:9;39568:4;39564:20;39560:1;39549:9;39545:17;39538:47;39602:131;39728:4;39602:131;:::i;:::-;39594:139;;39321:419;;;:::o;39746:234::-;39886:34;39882:1;39874:6;39870:14;39863:58;39955:17;39950:2;39942:6;39938:15;39931:42;39746:234;:::o;39986:366::-;40128:3;40149:67;40213:2;40208:3;40149:67;:::i;:::-;40142:74;;40225:93;40314:3;40225:93;:::i;:::-;40343:2;40338:3;40334:12;40327:19;;39986:366;;;:::o;40358:419::-;40524:4;40562:2;40551:9;40547:18;40539:26;;40611:9;40605:4;40601:20;40597:1;40586:9;40582:17;40575:47;40639:131;40765:4;40639:131;:::i;:::-;40631:139;;40358:419;;;:::o;40783:148::-;40885:11;40922:3;40907:18;;40783:148;;;;:::o;40937:390::-;41043:3;41071:39;41104:5;41071:39;:::i;:::-;41126:89;41208:6;41203:3;41126:89;:::i;:::-;41119:96;;41224:65;41282:6;41277:3;41270:4;41263:5;41259:16;41224:65;:::i;:::-;41314:6;41309:3;41305:16;41298:23;;41047:280;40937:390;;;;:::o;41333:151::-;41473:3;41469:1;41461:6;41457:14;41450:27;41333:151;:::o;41490:400::-;41650:3;41671:84;41753:1;41748:3;41671:84;:::i;:::-;41664:91;;41764:93;41853:3;41764:93;:::i;:::-;41882:1;41877:3;41873:11;41866:18;;41490:400;;;:::o;41896:155::-;42036:7;42032:1;42024:6;42020:14;42013:31;41896:155;:::o;42057:400::-;42217:3;42238:84;42320:1;42315:3;42238:84;:::i;:::-;42231:91;;42331:93;42420:3;42331:93;:::i;:::-;42449:1;42444:3;42440:11;42433:18;;42057:400;;;:::o;42463:967::-;42845:3;42867:95;42958:3;42949:6;42867:95;:::i;:::-;42860:102;;42979:148;43123:3;42979:148;:::i;:::-;42972:155;;43144:95;43235:3;43226:6;43144:95;:::i;:::-;43137:102;;43256:148;43400:3;43256:148;:::i;:::-;43249:155;;43421:3;43414:10;;42463:967;;;;;:::o;43436:94::-;43469:8;43517:5;43513:2;43509:14;43488:35;;43436:94;;;:::o;43536:::-;43575:7;43604:20;43618:5;43604:20;:::i;:::-;43593:31;;43536:94;;;:::o;43636:100::-;43675:7;43704:26;43724:5;43704:26;:::i;:::-;43693:37;;43636:100;;;:::o;43742:157::-;43847:45;43867:24;43885:5;43867:24;:::i;:::-;43847:45;:::i;:::-;43842:3;43835:58;43742:157;;:::o;43905:256::-;44017:3;44032:75;44103:3;44094:6;44032:75;:::i;:::-;44132:2;44127:3;44123:12;44116:19;;44152:3;44145:10;;43905:256;;;;:::o;44167:225::-;44307:34;44303:1;44295:6;44291:14;44284:58;44376:8;44371:2;44363:6;44359:15;44352:33;44167:225;:::o;44398:366::-;44540:3;44561:67;44625:2;44620:3;44561:67;:::i;:::-;44554:74;;44637:93;44726:3;44637:93;:::i;:::-;44755:2;44750:3;44746:12;44739:19;;44398:366;;;:::o;44770:419::-;44936:4;44974:2;44963:9;44959:18;44951:26;;45023:9;45017:4;45013:20;45009:1;44998:9;44994:17;44987:47;45051:131;45177:4;45051:131;:::i;:::-;45043:139;;44770:419;;;:::o;45195:332::-;45316:4;45354:2;45343:9;45339:18;45331:26;;45367:71;45435:1;45424:9;45420:17;45411:6;45367:71;:::i;:::-;45448:72;45516:2;45505:9;45501:18;45492:6;45448:72;:::i;:::-;45195:332;;;;;:::o;45533:137::-;45587:5;45618:6;45612:13;45603:22;;45634:30;45658:5;45634:30;:::i;:::-;45533:137;;;;:::o;45676:345::-;45743:6;45792:2;45780:9;45771:7;45767:23;45763:32;45760:119;;;45798:79;;:::i;:::-;45760:119;45918:1;45943:61;45996:7;45987:6;45976:9;45972:22;45943:61;:::i;:::-;45933:71;;45889:125;45676:345;;;;:::o;46027:233::-;46066:3;46089:24;46107:5;46089:24;:::i;:::-;46080:33;;46135:66;46128:5;46125:77;46122:103;;46205:18;;:::i;:::-;46122:103;46252:1;46245:5;46241:13;46234:20;;46027:233;;;:::o;46266:180::-;46314:77;46311:1;46304:88;46411:4;46408:1;46401:15;46435:4;46432:1;46425:15;46452:185;46492:1;46509:20;46527:1;46509:20;:::i;:::-;46504:25;;46543:20;46561:1;46543:20;:::i;:::-;46538:25;;46582:1;46572:35;;46587:18;;:::i;:::-;46572:35;46629:1;46626;46622:9;46617:14;;46452:185;;;;:::o;46643:194::-;46683:4;46703:20;46721:1;46703:20;:::i;:::-;46698:25;;46737:20;46755:1;46737:20;:::i;:::-;46732:25;;46781:1;46778;46774:9;46766:17;;46805:1;46799:4;46796:11;46793:37;;;46810:18;;:::i;:::-;46793:37;46643:194;;;;:::o;46843:176::-;46875:1;46892:20;46910:1;46892:20;:::i;:::-;46887:25;;46926:20;46944:1;46926:20;:::i;:::-;46921:25;;46965:1;46955:35;;46970:18;;:::i;:::-;46955:35;47011:1;47008;47004:9;46999:14;;46843:176;;;;:::o;47025:180::-;47073:77;47070:1;47063:88;47170:4;47167:1;47160:15;47194:4;47191:1;47184:15;47211:98;47262:6;47296:5;47290:12;47280:22;;47211:98;;;:::o;47315:168::-;47398:11;47432:6;47427:3;47420:19;47472:4;47467:3;47463:14;47448:29;;47315:168;;;;:::o;47489:373::-;47575:3;47603:38;47635:5;47603:38;:::i;:::-;47657:70;47720:6;47715:3;47657:70;:::i;:::-;47650:77;;47736:65;47794:6;47789:3;47782:4;47775:5;47771:16;47736:65;:::i;:::-;47826:29;47848:6;47826:29;:::i;:::-;47821:3;47817:39;47810:46;;47579:283;47489:373;;;;:::o;47868:640::-;48063:4;48101:3;48090:9;48086:19;48078:27;;48115:71;48183:1;48172:9;48168:17;48159:6;48115:71;:::i;:::-;48196:72;48264:2;48253:9;48249:18;48240:6;48196:72;:::i;:::-;48278;48346:2;48335:9;48331:18;48322:6;48278:72;:::i;:::-;48397:9;48391:4;48387:20;48382:2;48371:9;48367:18;48360:48;48425:76;48496:4;48487:6;48425:76;:::i;:::-;48417:84;;47868:640;;;;;;;:::o;48514:141::-;48570:5;48601:6;48595:13;48586:22;;48617:32;48643:5;48617:32;:::i;:::-;48514:141;;;;:::o;48661:349::-;48730:6;48779:2;48767:9;48758:7;48754:23;48750:32;48747:119;;;48785:79;;:::i;:::-;48747:119;48905:1;48930:63;48985:7;48976:6;48965:9;48961:22;48930:63;:::i;:::-;48920:73;;48876:127;48661:349;;;;:::o

Swarm Source

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