Feature Tip: Add private address tag to any address under My Name Tag !
ERC-721
NFT
Overview
Max Total Supply
1,000 FAPEC-G
Holders
105
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
0 FAPEC-GLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
FinanceApeClub_Genesis
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "./ERC721A.sol"; import "./Ownable.sol"; import {MerkleProof} from "./MerkleProof.sol"; contract FinanceApeClub_Genesis is ERC721A, Ownable { // unchangeable collection size uint256 public constant collectionSize = 1000; // mint price for each whitelist category mapping(uint8 => uint256) public mintPrice; // max mint per whitelist and merkle root for each whitelist category mapping(uint8 => uint256) public maxMintPerWhitelist; mapping(uint8 => bytes32) public merkleRoot; // constructor setting NFT name and symbol constructor() ERC721A("FinanceApeClub-Genesis", "FAPEC-G") {} // function for minting NFT tokens function whitelistMint(uint256 quantity, uint8 wlCategory, bytes32[] calldata proof) external payable { // require that the caller is not a contract require(tx.origin == msg.sender, "Caller cannot be a contract."); // require that the caller is whitelisted require(merkeltreeVerify(msg.sender, wlCategory, proof), "Not whitelisted"); // require that the collection size has not been reached require(_totalMinted() < collectionSize, "Collection Size reached!"); // require that the total mint quantity of the caller is not more than the max mint per whitelist require((_numberMinted(msg.sender) + quantity) <= maxMintPerWhitelist[wlCategory], "Whitelist mint limit exceeds"); // if quantity to mint causes collection size to be reached, set quantity to the remaining collection size if (_totalMinted() + quantity > collectionSize) { quantity = collectionSize - _totalMinted(); } // require that the caller has sent enough ETH to cover the mint price uint256 requiredPayment = quantity * mintPrice[wlCategory]; require(msg.value >= requiredPayment, "ETH insufficient."); // mint the NFT tokens _safeMint(msg.sender, quantity); // if the caller has sent more than the required payment, send the excess back to the caller, // this may happen when the mint request reaches the collection size. if (msg.value > requiredPayment) { payable(msg.sender).transfer(msg.value - requiredPayment); } } // function for verifying the caller's address against the merkle root for the whitelist category function merkeltreeVerify(address account, uint8 wlCategory, bytes32[] calldata proof) public view returns (bool) { bytes32 leaf = keccak256(abi.encodePacked(account)); return MerkleProof.verify(proof, merkleRoot[wlCategory], leaf); } // define function for setting the max mint per whitelist function setMaxMintPerWhitelist(uint8[] calldata wlCategories, uint256[] calldata maxMints) external onlyOwner{ require(wlCategories.length == maxMints.length, "Array lengths do not match."); for (uint256 i = 0; i < wlCategories.length; i++) { maxMintPerWhitelist[wlCategories[i]] = maxMints[i]; } } // function for setting the merkle root for each whitelist category function setMerkleRoots(uint8[] calldata wlCategories, bytes32[] calldata rootHashes) external onlyOwner{ require(wlCategories.length == rootHashes.length, "Array lengths do not match."); for (uint256 i = 0; i < wlCategories.length; i++) { merkleRoot[wlCategories[i]] = rootHashes[i]; } } // function for setting the merkle root for each whitelist category function setMintPrices(uint8[] calldata wlCategories, uint256[] calldata mintPrices) external onlyOwner { require(wlCategories.length == mintPrices.length, "Array lengths do not match."); for (uint256 i = 0; i < wlCategories.length; i++) { mintPrice[wlCategories[i]] = mintPrices[i]; } } // function for getting the number of minted NFT tokens function mintedNumberOf(address account) public view returns (uint256) { return _numberMinted(account); } // functions for baseTokenURI and unrevealedURI string private _baseTokenURI; string private _unrevealedURI; function _baseURI() internal view virtual override returns (string memory) { return _baseTokenURI; } // function for setting baseTokenURI function setBaseURI(string calldata baseURI) external onlyOwner { _baseTokenURI = baseURI; } // function for getting tokenURI function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) _revert(URIQueryForNonexistentToken.selector); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : _unrevealedURI; } // function for setting unrevealedURI function setUnrevealedURI(string calldata unrevealedURI) external onlyOwner { _unrevealedURI = unrevealedURI; } // function for withdrawing ETH from the contract to the owner's address function withdraw() external onlyOwner { (bool success,) = msg.sender.call{value: address(this).balance}(""); require(success, "Transfer failed."); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; import './IERC721A.sol'; /** * @dev Interface of ERC721 token receiver. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC721A * * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721) * Non-Fungible Token Standard, including the Metadata extension. * Optimized for lower gas during batch mints. * * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...) * starting from `_startTokenId()`. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364). struct TokenApprovalRef { address value; } // ============================================================= // CONSTANTS // ============================================================= // Mask of an entry in packed address data. uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant _BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant _BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant _BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant _BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant _BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant _BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225; // The bit position of `extraData` in packed ownership. uint256 private constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with {_mintERC2309}. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309} // is required to cause an overflow, which is unrealistic. uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // ============================================================= // STORAGE // ============================================================= // The next token ID to be minted. uint256 private _currentIndex; // The number of tokens burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See {_packedOwnershipOf} implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => TokenApprovalRef) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // ============================================================= // CONSTRUCTOR // ============================================================= constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); } // ============================================================= // TOKEN COUNTING OPERATIONS // ============================================================= /** * @dev Returns the starting token ID. * To change the starting token ID, please override this function. */ function _startTokenId() internal view virtual returns (uint256) { return 1; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view virtual returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() public view virtual override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than `_currentIndex - _startTokenId()` times. unchecked { return _currentIndex - _burnCounter - _startTokenId(); } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view virtual returns (uint256) { // Counter underflow is impossible as `_currentIndex` does not decrement, // and it is initialized to `_startTokenId()`. unchecked { return _currentIndex - _startTokenId(); } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return _burnCounter; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(0)) _revert(BalanceQueryForZeroAddress.selector); return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes // of the XOR of all function selectors in the interface. // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165) // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`) return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) _revert(URIQueryForNonexistentToken.selector); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ''; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Returns whether the ownership slot at `index` is initialized. * An uninitialized slot does not necessarily mean that the slot has no owner. */ function _ownershipIsInitialized(uint256 index) internal view virtual returns (bool) { return _packedOwnerships[index] != 0; } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256 packed) { if (_startTokenId() <= tokenId) { packed = _packedOwnerships[tokenId]; // If the data at the starting slot does not exist, start the scan. if (packed == 0) { if (tokenId >= _currentIndex) _revert(OwnerQueryForNonexistentToken.selector); // Invariant: // There will always be an initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `tokenId` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. for (;;) { unchecked { packed = _packedOwnerships[--tokenId]; } if (packed == 0) continue; if (packed & _BITMASK_BURNED == 0) return packed; // Otherwise, the token is burned, and we must revert. // This handles the case of batch burned tokens, where only the burned bit // of the starting slot is set, and remaining slots are left uninitialized. _revert(OwnerQueryForNonexistentToken.selector); } } // Otherwise, the data exists and we can skip the scan. // This is possible because we have already achieved the target condition. // This saves 2143 gas on transfers of initialized tokens. // If the token is not burned, return `packed`. Otherwise, revert. if (packed & _BITMASK_BURNED == 0) return packed; } _revert(OwnerQueryForNonexistentToken.selector); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags)) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. See {ERC721A-_approve}. * * Requirements: * * - The caller must own the token or be an approved operator. */ function approve(address to, uint256 tokenId) public payable virtual override { _approve(to, tokenId, true); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) _revert(ApprovalQueryForNonexistentToken.selector); return _tokenApprovals[tokenId].value; } /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) public virtual override { _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool result) { if (_startTokenId() <= tokenId) { if (tokenId < _currentIndex) { uint256 packed; while ((packed = _packedOwnerships[tokenId]) == 0) --tokenId; result = packed & _BITMASK_BURNED == 0; } } } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`. assembly { approvedAddressSlot := tokenApproval.slot approvedAddress := sload(approvedAddressSlot) } } // ============================================================= // TRANSFER OPERATIONS // ============================================================= /** * @dev Transfers `tokenId` from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) public payable virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); // Mask `from` to the lower 160 bits, in case the upper bits somehow aren't clean. from = address(uint160(uint256(uint160(from)) & _BITMASK_ADDRESS)); if (address(uint160(prevOwnershipPacked)) != from) _revert(TransferFromIncorrectOwner.selector); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) _revert(TransferCallerNotOwnerNorApproved.selector); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS; assembly { // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. from, // `from`. toMasked, // `to`. tokenId // `tokenId`. ) } if (toMasked == 0) _revert(TransferToZeroAddress.selector); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public payable virtual override { safeTransferFrom(from, to, tokenId, ''); } /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public payable virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { _revert(TransferToNonERC721ReceiverImplementer.selector); } } /** * @dev Hook that is called before a set of serially-ordered token IDs * are about to be transferred. This includes minting. * And also called before burning one token. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token IDs * have been transferred. This includes minting. * And also called after one token has been burned. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns whether the call correctly returned the expected magic value. */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns ( bytes4 retval ) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { _revert(TransferToNonERC721ReceiverImplementer.selector); } assembly { revert(add(32, reason), mload(reason)) } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (quantity == 0) _revert(MintZeroQuantity.selector); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS; if (toMasked == 0) _revert(MintToZeroAddress.selector); uint256 end = startTokenId + quantity; uint256 tokenId = startTokenId; do { assembly { // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. tokenId // `tokenId`. ) } // The `!=` check ensures that large values of `quantity` // that overflows uint256 will make the loop run out of gas. } while (++tokenId != end); _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (to == address(0)) _revert(MintToZeroAddress.selector); if (quantity == 0) _revert(MintZeroQuantity.selector); if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) _revert(MintERC2309QuantityExceedsLimit.selector); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to); _currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = _currentIndex; uint256 index = end - quantity; do { if (!_checkContractOnERC721Received(address(0), to, index++, _data)) { _revert(TransferToNonERC721ReceiverImplementer.selector); } } while (index < end); // Reentrancy protection. if (_currentIndex != end) _revert(bytes4(0)); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ''); } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Equivalent to `_approve(to, tokenId, false)`. */ function _approve(address to, uint256 tokenId) internal virtual { _approve(to, tokenId, false); } /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - `tokenId` must exist. * * Emits an {Approval} event. */ function _approve( address to, uint256 tokenId, bool approvalCheck ) internal virtual { address owner = ownerOf(tokenId); if (approvalCheck && _msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { _revert(ApprovalCallerNotOwnerNorApproved.selector); } _tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) _revert(TransferCallerNotOwnerNorApproved.selector); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { _burnCounter++; } } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) _revert(OwnershipNotInitializedForExtraData.selector); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } /** * @dev For more efficient reverts. */ function _revert(bytes4 errorSelector) internal pure { assembly { mstore(0x00, errorSelector) revert(0x00, 0x04) } } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables * (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, * checking first that contract recipients are aware of the ERC721 protocol * to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move * this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external payable; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Transfers `tokenId` from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} * whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external payable; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) external view returns (bool); // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The tree and the proofs can be generated using our * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. * You will find a quickstart guide in the readme. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the merkle tree could be reinterpreted as a leaf value. * OpenZeppelin's JavaScript library generates merkle trees that are safe * against this attack out of the box. */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} * * _Available since v4.7._ */ function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _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++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} * * _Available since v4.7._ */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). * * _Available since v4.7._ */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "./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); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collectionSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"maxMintPerWhitelist","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint8","name":"wlCategory","type":"uint8"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"merkeltreeVerify","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"mintedNumberOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8[]","name":"wlCategories","type":"uint8[]"},{"internalType":"uint256[]","name":"maxMints","type":"uint256[]"}],"name":"setMaxMintPerWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8[]","name":"wlCategories","type":"uint8[]"},{"internalType":"bytes32[]","name":"rootHashes","type":"bytes32[]"}],"name":"setMerkleRoots","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8[]","name":"wlCategories","type":"uint8[]"},{"internalType":"uint256[]","name":"mintPrices","type":"uint256[]"}],"name":"setMintPrices","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"unrevealedURI","type":"string"}],"name":"setUnrevealedURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"uint8","name":"wlCategory","type":"uint8"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b506040518060400160405280601681526020017f46696e616e6365417065436c75622d47656e65736973000000000000000000008152506040518060400160405280600781526020017f46415045432d470000000000000000000000000000000000000000000000000081525081600290816200008f919062000431565b508060039081620000a1919062000431565b50620000b2620000e060201b60201c565b6000819055505050620000da620000ce620000e960201b60201c565b620000f160201b60201c565b62000518565b60006001905090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200023957607f821691505b6020821081036200024f576200024e620001f1565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620002b97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200027a565b620002c586836200027a565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620003126200030c6200030684620002dd565b620002e7565b620002dd565b9050919050565b6000819050919050565b6200032e83620002f1565b620003466200033d8262000319565b84845462000287565b825550505050565b600090565b6200035d6200034e565b6200036a81848462000323565b505050565b5b8181101562000392576200038660008262000353565b60018101905062000370565b5050565b601f821115620003e157620003ab8162000255565b620003b6846200026a565b81016020851015620003c6578190505b620003de620003d5856200026a565b8301826200036f565b50505b505050565b600082821c905092915050565b60006200040660001984600802620003e6565b1980831691505092915050565b6000620004218383620003f3565b9150826002028217905092915050565b6200043c82620001b7565b67ffffffffffffffff811115620004585762000457620001c2565b5b62000464825462000220565b6200047182828562000396565b600060209050601f831160018114620004a9576000841562000494578287015190505b620004a0858262000413565b86555062000510565b601f198416620004b98662000255565b60005b82811015620004e357848901518255600182019150602085019450602081019050620004bc565b86831015620005035784890151620004ff601f891682620003f3565b8355505b6001600288020188555050505b505050505050565b6135ef80620005286000396000f3fe6080604052600436106101cd5760003560e01c8063715018a6116100f7578063b88d4fde11610095578063f23768b511610064578063f23768b514610655578063f2fde38b14610692578063f949942a146106bb578063fe2c7fee146106f8576101cd565b8063b88d4fde14610582578063bc49fc551461059e578063c87b56dd146105db578063e985e9c514610618576101cd565b80638da5cb5b116100d15780638da5cb5b146104da57806395d89b4114610505578063a22cb46514610530578063b7a4ea8a14610559576101cd565b8063715018a6146104495780637ae0f496146104605780638147ef371461049d576101cd565b80633ccfd60b1161016f57806355f804b31161013e57806355f804b31461038a5780636352211e146103b35780636df69b18146103f057806370a082311461040c576101cd565b80633ccfd60b1461030357806342842e0e1461031a57806345c0f533146103365780634a02a3f314610361576101cd565b8063081812fc116101ab578063081812fc14610263578063095ea7b3146102a057806318160ddd146102bc57806323b872dd146102e7576101cd565b806301f8bf17146101d257806301ffc9a7146101fb57806306fdde0314610238575b600080fd5b3480156101de57600080fd5b506101f960048036038101906101f4919061225d565b610721565b005b34801561020757600080fd5b50610222600480360381019061021d9190612336565b6107f7565b60405161022f919061237e565b60405180910390f35b34801561024457600080fd5b5061024d610889565b60405161025a9190612429565b60405180910390f35b34801561026f57600080fd5b5061028a60048036038101906102859190612481565b61091b565b60405161029791906124ef565b60405180910390f35b6102ba60048036038101906102b59190612536565b610979565b005b3480156102c857600080fd5b506102d1610989565b6040516102de9190612585565b60405180910390f35b61030160048036038101906102fc91906125a0565b6109a0565b005b34801561030f57600080fd5b50610318610c61565b005b610334600480360381019061032f91906125a0565b610d18565b005b34801561034257600080fd5b5061034b610d38565b6040516103589190612585565b60405180910390f35b34801561036d57600080fd5b5061038860048036038101906103839190612649565b610d3e565b005b34801561039657600080fd5b506103b160048036038101906103ac9190612720565b610e14565b005b3480156103bf57600080fd5b506103da60048036038101906103d59190612481565b610e32565b6040516103e791906124ef565b60405180910390f35b61040a600480360381019061040591906127a6565b610e44565b005b34801561041857600080fd5b50610433600480360381019061042e919061281a565b6110c3565b6040516104409190612585565b60405180910390f35b34801561045557600080fd5b5061045e61115a565b005b34801561046c57600080fd5b5061048760048036038101906104829190612847565b61116e565b604051610494919061288d565b60405180910390f35b3480156104a957600080fd5b506104c460048036038101906104bf9190612847565b611186565b6040516104d19190612585565b60405180910390f35b3480156104e657600080fd5b506104ef61119e565b6040516104fc91906124ef565b60405180910390f35b34801561051157600080fd5b5061051a6111c8565b6040516105279190612429565b60405180910390f35b34801561053c57600080fd5b50610557600480360381019061055291906128d4565b61125a565b005b34801561056557600080fd5b50610580600480360381019061057b9190612649565b611365565b005b61059c60048036038101906105979190612a44565b61143b565b005b3480156105aa57600080fd5b506105c560048036038101906105c09190612847565b61148d565b6040516105d29190612585565b60405180910390f35b3480156105e757600080fd5b5061060260048036038101906105fd9190612481565b6114a5565b60405161060f9190612429565b60405180910390f35b34801561062457600080fd5b5061063f600480360381019061063a9190612ac7565b61159d565b60405161064c919061237e565b60405180910390f35b34801561066157600080fd5b5061067c60048036038101906106779190612b07565b611631565b604051610689919061237e565b60405180910390f35b34801561069e57600080fd5b506106b960048036038101906106b4919061281a565b6116cd565b005b3480156106c757600080fd5b506106e260048036038101906106dd919061281a565b611750565b6040516106ef9190612585565b60405180910390f35b34801561070457600080fd5b5061071f600480360381019061071a9190612720565b611762565b005b610729611780565b818190508484905014610771576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161076890612bc7565b60405180910390fd5b60005b848490508110156107f05782828281811061079257610791612be7565b5b90506020020135600b60008787858181106107b0576107af612be7565b5b90506020020160208101906107c59190612847565b60ff1660ff1681526020019081526020016000208190555080806107e890612c45565b915050610774565b5050505050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061085257506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108825750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461089890612cbc565b80601f01602080910402602001604051908101604052809291908181526020018280546108c490612cbc565b80156109115780601f106108e657610100808354040283529160200191610911565b820191906000526020600020905b8154815290600101906020018083116108f457829003601f168201915b5050505050905090565b6000610926826117fe565b61093b5761093a63cf4700e460e01b611877565b5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b61098582826001611881565b5050565b60006109936119b0565b6001546000540303905090565b60006109ab826119b9565b905073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161693508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a2057610a1f63a114810060e01b611877565b5b600080610a2c84611aa5565b91509150610a428187610a3d611acc565b611ad4565b610a6d57610a5786610a52611acc565b61159d565b610a6c57610a6b6359c896be60e01b611877565b5b5b610a7a8686866001611b18565b8015610a8557600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610b5385610b2f888887611b1e565b7c020000000000000000000000000000000000000000000000000000000017611b46565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610bd95760006001850190506000600460008381526020019081526020016000205403610bd7576000548114610bd6578360046000838152602001908152602001600020819055505b5b505b600073ffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff161690508481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460008103610c4b57610c4a63ea553b3460e01b611877565b5b610c588787876001611b71565b50505050505050565b610c69611780565b60003373ffffffffffffffffffffffffffffffffffffffff1647604051610c8f90612d1e565b60006040518083038185875af1925050503d8060008114610ccc576040519150601f19603f3d011682016040523d82523d6000602084013e610cd1565b606091505b5050905080610d15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0c90612d7f565b60405180910390fd5b50565b610d338383836040518060200160405280600081525061143b565b505050565b6103e881565b610d46611780565b818190508484905014610d8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d8590612bc7565b60405180910390fd5b60005b84849050811015610e0d57828282818110610daf57610dae612be7565b5b90506020020135600a6000878785818110610dcd57610dcc612be7565b5b9050602002016020810190610de29190612847565b60ff1660ff168152602001908152602001600020819055508080610e0590612c45565b915050610d91565b5050505050565b610e1c611780565b8181600c9182610e2d929190612f56565b505050565b6000610e3d826119b9565b9050919050565b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614610eb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea990613072565b60405180910390fd5b610ebe33848484611631565b610efd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ef4906130de565b60405180910390fd5b6103e8610f08611b77565b10610f48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3f9061314a565b60405180910390fd5b600a60008460ff1660ff1681526020019081526020016000205484610f6c33611b8a565b610f76919061316a565b1115610fb7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fae906131ea565b60405180910390fd5b6103e884610fc3611b77565b610fcd919061316a565b1115610feb57610fdb611b77565b6103e8610fe8919061320a565b93505b6000600960008560ff1660ff1681526020019081526020016000205485611012919061323e565b905080341015611057576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104e906132cc565b60405180910390fd5b6110613386611be1565b803411156110bc573373ffffffffffffffffffffffffffffffffffffffff166108fc823461108f919061320a565b9081150290604051600060405180830381858888f193505050501580156110ba573d6000803e3d6000fd5b505b5050505050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361110957611108638f4eb60460e01b611877565b5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b611162611780565b61116c6000611bff565b565b600b6020528060005260406000206000915090505481565b60096020528060005260406000206000915090505481565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600380546111d790612cbc565b80601f016020809104026020016040519081016040528092919081815260200182805461120390612cbc565b80156112505780601f1061122557610100808354040283529160200191611250565b820191906000526020600020905b81548152906001019060200180831161123357829003601f168201915b5050505050905090565b8060076000611267611acc565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611314611acc565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611359919061237e565b60405180910390a35050565b61136d611780565b8181905084849050146113b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ac90612bc7565b60405180910390fd5b60005b84849050811015611434578282828181106113d6576113d5612be7565b5b90506020020135600960008787858181106113f4576113f3612be7565b5b90506020020160208101906114099190612847565b60ff1660ff16815260200190815260200160002081905550808061142c90612c45565b9150506113b8565b5050505050565b6114468484846109a0565b60008373ffffffffffffffffffffffffffffffffffffffff163b146114875761147184848484611cc5565b6114865761148563d1a57ed660e01b611877565b5b5b50505050565b600a6020528060005260406000206000915090505481565b60606114b0826117fe565b6114c5576114c463a14c4b5060e01b611877565b5b60006114cf611df4565b9050600081510361156a57600d80546114e790612cbc565b80601f016020809104026020016040519081016040528092919081815260200182805461151390612cbc565b80156115605780601f1061153557610100808354040283529160200191611560565b820191906000526020600020905b81548152906001019060200180831161154357829003601f168201915b5050505050611595565b8061157484611e86565b604051602001611585929190613328565b6040516020818303038152906040525b915050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600080856040516020016116459190613394565b6040516020818303038152906040528051906020012090506116c2848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050600b60008860ff1660ff1681526020019081526020016000205483611ed6565b915050949350505050565b6116d5611780565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611744576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161173b90613421565b60405180910390fd5b61174d81611bff565b50565b600061175b82611b8a565b9050919050565b61176a611780565b8181600d918261177b929190612f56565b505050565b611788611eed565b73ffffffffffffffffffffffffffffffffffffffff166117a661119e565b73ffffffffffffffffffffffffffffffffffffffff16146117fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117f39061348d565b60405180910390fd5b565b6000816118096119b0565b11611872576000548210156118715760005b600060046000858152602001908152602001600020549150810361184a5782611843906134ad565b925061181b565b60007c01000000000000000000000000000000000000000000000000000000008216149150505b5b919050565b8060005260046000fd5b600061188c83610e32565b90508180156118ce57508073ffffffffffffffffffffffffffffffffffffffff166118b5611acc565b73ffffffffffffffffffffffffffffffffffffffff1614155b156118fa576118e4816118df611acc565b61159d565b6118f9576118f863cfb3b94260e01b611877565b5b5b836006600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b60006001905090565b6000816119c46119b0565b11611a8f576004600083815260200190815260200160002054905060008103611a66576000548210611a0157611a0063df2d9b4260e01b611877565b5b5b60046000836001900393508381526020019081526020016000205490506000810315611a615760007c010000000000000000000000000000000000000000000000000000000082160315611aa057611a6063df2d9b4260e01b611877565b5b611a02565b60007c010000000000000000000000000000000000000000000000000000000082160315611aa0575b611a9f63df2d9b4260e01b611877565b5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8611b35868684611ef5565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6000611b816119b0565b60005403905090565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b611bfb828260405180602001604052806000815250611efe565b5050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611ceb611acc565b8786866040518563ffffffff1660e01b8152600401611d0d949392919061352b565b6020604051808303816000875af1925050508015611d4957506040513d601f19601f82011682018060405250810190611d46919061358c565b60015b611da1573d8060008114611d79576040519150601f19603f3d011682016040523d82523d6000602084013e611d7e565b606091505b506000815103611d9957611d9863d1a57ed660e01b611877565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600c8054611e0390612cbc565b80601f0160208091040260200160405190810160405280929190818152602001828054611e2f90612cbc565b8015611e7c5780601f10611e5157610100808354040283529160200191611e7c565b820191906000526020600020905b815481529060010190602001808311611e5f57829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b600115611ec157600184039350600a81066030018453600a8104905080611e9f575b50828103602084039350808452505050919050565b600082611ee38584611f83565b1490509392505050565b600033905090565b60009392505050565b611f088383611fd9565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611f7e57600080549050600083820390505b611f486000868380600101945086611cc5565b611f5d57611f5c63d1a57ed660e01b611877565b5b818110611f35578160005414611f7b57611f7a600060e01b611877565b5b50505b505050565b60008082905060005b8451811015611fce57611fb982868381518110611fac57611fab612be7565b5b602002602001015161213c565b91508080611fc690612c45565b915050611f8c565b508091505092915050565b60008054905060008203611ff857611ff763b562e8dd60e01b611877565b5b6120056000848385611b18565b612025836120166000866000611b1e565b61201f85612167565b17611b46565b6004600083815260200190815260200160002081905550600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550600073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff16169050600081036120dd576120dc632e07630060e01b611877565b5b6000838301905060008390505b808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a48181600101915081036120ea57816000819055505050506121376000848385611b71565b505050565b60008183106121545761214f8284612177565b61215f565b61215e8383612177565b5b905092915050565b60006001821460e11b9050919050565b600082600052816020526040600020905092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126121c7576121c66121a2565b5b8235905067ffffffffffffffff8111156121e4576121e36121a7565b5b602083019150836020820283011115612200576121ff6121ac565b5b9250929050565b60008083601f84011261221d5761221c6121a2565b5b8235905067ffffffffffffffff81111561223a576122396121a7565b5b602083019150836020820283011115612256576122556121ac565b5b9250929050565b6000806000806040858703121561227757612276612198565b5b600085013567ffffffffffffffff8111156122955761229461219d565b5b6122a1878288016121b1565b9450945050602085013567ffffffffffffffff8111156122c4576122c361219d565b5b6122d087828801612207565b925092505092959194509250565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612313816122de565b811461231e57600080fd5b50565b6000813590506123308161230a565b92915050565b60006020828403121561234c5761234b612198565b5b600061235a84828501612321565b91505092915050565b60008115159050919050565b61237881612363565b82525050565b6000602082019050612393600083018461236f565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156123d35780820151818401526020810190506123b8565b60008484015250505050565b6000601f19601f8301169050919050565b60006123fb82612399565b61240581856123a4565b93506124158185602086016123b5565b61241e816123df565b840191505092915050565b6000602082019050818103600083015261244381846123f0565b905092915050565b6000819050919050565b61245e8161244b565b811461246957600080fd5b50565b60008135905061247b81612455565b92915050565b60006020828403121561249757612496612198565b5b60006124a58482850161246c565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006124d9826124ae565b9050919050565b6124e9816124ce565b82525050565b600060208201905061250460008301846124e0565b92915050565b612513816124ce565b811461251e57600080fd5b50565b6000813590506125308161250a565b92915050565b6000806040838503121561254d5761254c612198565b5b600061255b85828601612521565b925050602061256c8582860161246c565b9150509250929050565b61257f8161244b565b82525050565b600060208201905061259a6000830184612576565b92915050565b6000806000606084860312156125b9576125b8612198565b5b60006125c786828701612521565b93505060206125d886828701612521565b92505060406125e98682870161246c565b9150509250925092565b60008083601f840112612609576126086121a2565b5b8235905067ffffffffffffffff811115612626576126256121a7565b5b602083019150836020820283011115612642576126416121ac565b5b9250929050565b6000806000806040858703121561266357612662612198565b5b600085013567ffffffffffffffff8111156126815761268061219d565b5b61268d878288016121b1565b9450945050602085013567ffffffffffffffff8111156126b0576126af61219d565b5b6126bc878288016125f3565b925092505092959194509250565b60008083601f8401126126e0576126df6121a2565b5b8235905067ffffffffffffffff8111156126fd576126fc6121a7565b5b602083019150836001820283011115612719576127186121ac565b5b9250929050565b6000806020838503121561273757612736612198565b5b600083013567ffffffffffffffff8111156127555761275461219d565b5b612761858286016126ca565b92509250509250929050565b600060ff82169050919050565b6127838161276d565b811461278e57600080fd5b50565b6000813590506127a08161277a565b92915050565b600080600080606085870312156127c0576127bf612198565b5b60006127ce8782880161246c565b94505060206127df87828801612791565b935050604085013567ffffffffffffffff811115612800576127ff61219d565b5b61280c87828801612207565b925092505092959194509250565b6000602082840312156128305761282f612198565b5b600061283e84828501612521565b91505092915050565b60006020828403121561285d5761285c612198565b5b600061286b84828501612791565b91505092915050565b6000819050919050565b61288781612874565b82525050565b60006020820190506128a2600083018461287e565b92915050565b6128b181612363565b81146128bc57600080fd5b50565b6000813590506128ce816128a8565b92915050565b600080604083850312156128eb576128ea612198565b5b60006128f985828601612521565b925050602061290a858286016128bf565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612951826123df565b810181811067ffffffffffffffff821117156129705761296f612919565b5b80604052505050565b600061298361218e565b905061298f8282612948565b919050565b600067ffffffffffffffff8211156129af576129ae612919565b5b6129b8826123df565b9050602081019050919050565b82818337600083830152505050565b60006129e76129e284612994565b612979565b905082815260208101848484011115612a0357612a02612914565b5b612a0e8482856129c5565b509392505050565b600082601f830112612a2b57612a2a6121a2565b5b8135612a3b8482602086016129d4565b91505092915050565b60008060008060808587031215612a5e57612a5d612198565b5b6000612a6c87828801612521565b9450506020612a7d87828801612521565b9350506040612a8e8782880161246c565b925050606085013567ffffffffffffffff811115612aaf57612aae61219d565b5b612abb87828801612a16565b91505092959194509250565b60008060408385031215612ade57612add612198565b5b6000612aec85828601612521565b9250506020612afd85828601612521565b9150509250929050565b60008060008060608587031215612b2157612b20612198565b5b6000612b2f87828801612521565b9450506020612b4087828801612791565b935050604085013567ffffffffffffffff811115612b6157612b6061219d565b5b612b6d87828801612207565b925092505092959194509250565b7f4172726179206c656e6774687320646f206e6f74206d617463682e0000000000600082015250565b6000612bb1601b836123a4565b9150612bbc82612b7b565b602082019050919050565b60006020820190508181036000830152612be081612ba4565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612c508261244b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612c8257612c81612c16565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680612cd457607f821691505b602082108103612ce757612ce6612c8d565b5b50919050565b600081905092915050565b50565b6000612d08600083612ced565b9150612d1382612cf8565b600082019050919050565b6000612d2982612cfb565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b6000612d696010836123a4565b9150612d7482612d33565b602082019050919050565b60006020820190508181036000830152612d9881612d5c565b9050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302612e0c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612dcf565b612e168683612dcf565b95508019841693508086168417925050509392505050565b6000819050919050565b6000612e53612e4e612e498461244b565b612e2e565b61244b565b9050919050565b6000819050919050565b612e6d83612e38565b612e81612e7982612e5a565b848454612ddc565b825550505050565b600090565b612e96612e89565b612ea1818484612e64565b505050565b5b81811015612ec557612eba600082612e8e565b600181019050612ea7565b5050565b601f821115612f0a57612edb81612daa565b612ee484612dbf565b81016020851015612ef3578190505b612f07612eff85612dbf565b830182612ea6565b50505b505050565b600082821c905092915050565b6000612f2d60001984600802612f0f565b1980831691505092915050565b6000612f468383612f1c565b9150826002028217905092915050565b612f608383612d9f565b67ffffffffffffffff811115612f7957612f78612919565b5b612f838254612cbc565b612f8e828285612ec9565b6000601f831160018114612fbd5760008415612fab578287013590505b612fb58582612f3a565b86555061301d565b601f198416612fcb86612daa565b60005b82811015612ff357848901358255600182019150602085019450602081019050612fce565b86831015613010578489013561300c601f891682612f1c565b8355505b6001600288020188555050505b50505050505050565b7f43616c6c65722063616e6e6f74206265206120636f6e74726163742e00000000600082015250565b600061305c601c836123a4565b915061306782613026565b602082019050919050565b6000602082019050818103600083015261308b8161304f565b9050919050565b7f4e6f742077686974656c69737465640000000000000000000000000000000000600082015250565b60006130c8600f836123a4565b91506130d382613092565b602082019050919050565b600060208201905081810360008301526130f7816130bb565b9050919050565b7f436f6c6c656374696f6e2053697a652072656163686564210000000000000000600082015250565b60006131346018836123a4565b915061313f826130fe565b602082019050919050565b6000602082019050818103600083015261316381613127565b9050919050565b60006131758261244b565b91506131808361244b565b925082820190508082111561319857613197612c16565b5b92915050565b7f57686974656c697374206d696e74206c696d6974206578636565647300000000600082015250565b60006131d4601c836123a4565b91506131df8261319e565b602082019050919050565b60006020820190508181036000830152613203816131c7565b9050919050565b60006132158261244b565b91506132208361244b565b925082820390508181111561323857613237612c16565b5b92915050565b60006132498261244b565b91506132548361244b565b92508282026132628161244b565b9150828204841483151761327957613278612c16565b5b5092915050565b7f45544820696e73756666696369656e742e000000000000000000000000000000600082015250565b60006132b66011836123a4565b91506132c182613280565b602082019050919050565b600060208201905081810360008301526132e5816132a9565b9050919050565b600081905092915050565b600061330282612399565b61330c81856132ec565b935061331c8185602086016123b5565b80840191505092915050565b600061333482856132f7565b915061334082846132f7565b91508190509392505050565b60008160601b9050919050565b60006133648261334c565b9050919050565b600061337682613359565b9050919050565b61338e613389826124ce565b61336b565b82525050565b60006133a0828461337d565b60148201915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061340b6026836123a4565b9150613416826133af565b604082019050919050565b6000602082019050818103600083015261343a816133fe565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006134776020836123a4565b915061348282613441565b602082019050919050565b600060208201905081810360008301526134a68161346a565b9050919050565b60006134b88261244b565b9150600082036134cb576134ca612c16565b5b600182039050919050565b600081519050919050565b600082825260208201905092915050565b60006134fd826134d6565b61350781856134e1565b93506135178185602086016123b5565b613520816123df565b840191505092915050565b600060808201905061354060008301876124e0565b61354d60208301866124e0565b61355a6040830185612576565b818103606083015261356c81846134f2565b905095945050505050565b6000815190506135868161230a565b92915050565b6000602082840312156135a2576135a1612198565b5b60006135b084828501613577565b9150509291505056fea264697066735822122050efdeb9f18d283c584034d25ae65a96eb26f2f11a550e955d70bdbcebaf364964736f6c63430008120033
Deployed Bytecode
0x6080604052600436106101cd5760003560e01c8063715018a6116100f7578063b88d4fde11610095578063f23768b511610064578063f23768b514610655578063f2fde38b14610692578063f949942a146106bb578063fe2c7fee146106f8576101cd565b8063b88d4fde14610582578063bc49fc551461059e578063c87b56dd146105db578063e985e9c514610618576101cd565b80638da5cb5b116100d15780638da5cb5b146104da57806395d89b4114610505578063a22cb46514610530578063b7a4ea8a14610559576101cd565b8063715018a6146104495780637ae0f496146104605780638147ef371461049d576101cd565b80633ccfd60b1161016f57806355f804b31161013e57806355f804b31461038a5780636352211e146103b35780636df69b18146103f057806370a082311461040c576101cd565b80633ccfd60b1461030357806342842e0e1461031a57806345c0f533146103365780634a02a3f314610361576101cd565b8063081812fc116101ab578063081812fc14610263578063095ea7b3146102a057806318160ddd146102bc57806323b872dd146102e7576101cd565b806301f8bf17146101d257806301ffc9a7146101fb57806306fdde0314610238575b600080fd5b3480156101de57600080fd5b506101f960048036038101906101f4919061225d565b610721565b005b34801561020757600080fd5b50610222600480360381019061021d9190612336565b6107f7565b60405161022f919061237e565b60405180910390f35b34801561024457600080fd5b5061024d610889565b60405161025a9190612429565b60405180910390f35b34801561026f57600080fd5b5061028a60048036038101906102859190612481565b61091b565b60405161029791906124ef565b60405180910390f35b6102ba60048036038101906102b59190612536565b610979565b005b3480156102c857600080fd5b506102d1610989565b6040516102de9190612585565b60405180910390f35b61030160048036038101906102fc91906125a0565b6109a0565b005b34801561030f57600080fd5b50610318610c61565b005b610334600480360381019061032f91906125a0565b610d18565b005b34801561034257600080fd5b5061034b610d38565b6040516103589190612585565b60405180910390f35b34801561036d57600080fd5b5061038860048036038101906103839190612649565b610d3e565b005b34801561039657600080fd5b506103b160048036038101906103ac9190612720565b610e14565b005b3480156103bf57600080fd5b506103da60048036038101906103d59190612481565b610e32565b6040516103e791906124ef565b60405180910390f35b61040a600480360381019061040591906127a6565b610e44565b005b34801561041857600080fd5b50610433600480360381019061042e919061281a565b6110c3565b6040516104409190612585565b60405180910390f35b34801561045557600080fd5b5061045e61115a565b005b34801561046c57600080fd5b5061048760048036038101906104829190612847565b61116e565b604051610494919061288d565b60405180910390f35b3480156104a957600080fd5b506104c460048036038101906104bf9190612847565b611186565b6040516104d19190612585565b60405180910390f35b3480156104e657600080fd5b506104ef61119e565b6040516104fc91906124ef565b60405180910390f35b34801561051157600080fd5b5061051a6111c8565b6040516105279190612429565b60405180910390f35b34801561053c57600080fd5b50610557600480360381019061055291906128d4565b61125a565b005b34801561056557600080fd5b50610580600480360381019061057b9190612649565b611365565b005b61059c60048036038101906105979190612a44565b61143b565b005b3480156105aa57600080fd5b506105c560048036038101906105c09190612847565b61148d565b6040516105d29190612585565b60405180910390f35b3480156105e757600080fd5b5061060260048036038101906105fd9190612481565b6114a5565b60405161060f9190612429565b60405180910390f35b34801561062457600080fd5b5061063f600480360381019061063a9190612ac7565b61159d565b60405161064c919061237e565b60405180910390f35b34801561066157600080fd5b5061067c60048036038101906106779190612b07565b611631565b604051610689919061237e565b60405180910390f35b34801561069e57600080fd5b506106b960048036038101906106b4919061281a565b6116cd565b005b3480156106c757600080fd5b506106e260048036038101906106dd919061281a565b611750565b6040516106ef9190612585565b60405180910390f35b34801561070457600080fd5b5061071f600480360381019061071a9190612720565b611762565b005b610729611780565b818190508484905014610771576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161076890612bc7565b60405180910390fd5b60005b848490508110156107f05782828281811061079257610791612be7565b5b90506020020135600b60008787858181106107b0576107af612be7565b5b90506020020160208101906107c59190612847565b60ff1660ff1681526020019081526020016000208190555080806107e890612c45565b915050610774565b5050505050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061085257506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108825750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461089890612cbc565b80601f01602080910402602001604051908101604052809291908181526020018280546108c490612cbc565b80156109115780601f106108e657610100808354040283529160200191610911565b820191906000526020600020905b8154815290600101906020018083116108f457829003601f168201915b5050505050905090565b6000610926826117fe565b61093b5761093a63cf4700e460e01b611877565b5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b61098582826001611881565b5050565b60006109936119b0565b6001546000540303905090565b60006109ab826119b9565b905073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161693508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a2057610a1f63a114810060e01b611877565b5b600080610a2c84611aa5565b91509150610a428187610a3d611acc565b611ad4565b610a6d57610a5786610a52611acc565b61159d565b610a6c57610a6b6359c896be60e01b611877565b5b5b610a7a8686866001611b18565b8015610a8557600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610b5385610b2f888887611b1e565b7c020000000000000000000000000000000000000000000000000000000017611b46565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610bd95760006001850190506000600460008381526020019081526020016000205403610bd7576000548114610bd6578360046000838152602001908152602001600020819055505b5b505b600073ffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff161690508481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460008103610c4b57610c4a63ea553b3460e01b611877565b5b610c588787876001611b71565b50505050505050565b610c69611780565b60003373ffffffffffffffffffffffffffffffffffffffff1647604051610c8f90612d1e565b60006040518083038185875af1925050503d8060008114610ccc576040519150601f19603f3d011682016040523d82523d6000602084013e610cd1565b606091505b5050905080610d15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0c90612d7f565b60405180910390fd5b50565b610d338383836040518060200160405280600081525061143b565b505050565b6103e881565b610d46611780565b818190508484905014610d8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d8590612bc7565b60405180910390fd5b60005b84849050811015610e0d57828282818110610daf57610dae612be7565b5b90506020020135600a6000878785818110610dcd57610dcc612be7565b5b9050602002016020810190610de29190612847565b60ff1660ff168152602001908152602001600020819055508080610e0590612c45565b915050610d91565b5050505050565b610e1c611780565b8181600c9182610e2d929190612f56565b505050565b6000610e3d826119b9565b9050919050565b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614610eb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea990613072565b60405180910390fd5b610ebe33848484611631565b610efd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ef4906130de565b60405180910390fd5b6103e8610f08611b77565b10610f48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3f9061314a565b60405180910390fd5b600a60008460ff1660ff1681526020019081526020016000205484610f6c33611b8a565b610f76919061316a565b1115610fb7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fae906131ea565b60405180910390fd5b6103e884610fc3611b77565b610fcd919061316a565b1115610feb57610fdb611b77565b6103e8610fe8919061320a565b93505b6000600960008560ff1660ff1681526020019081526020016000205485611012919061323e565b905080341015611057576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104e906132cc565b60405180910390fd5b6110613386611be1565b803411156110bc573373ffffffffffffffffffffffffffffffffffffffff166108fc823461108f919061320a565b9081150290604051600060405180830381858888f193505050501580156110ba573d6000803e3d6000fd5b505b5050505050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361110957611108638f4eb60460e01b611877565b5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b611162611780565b61116c6000611bff565b565b600b6020528060005260406000206000915090505481565b60096020528060005260406000206000915090505481565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600380546111d790612cbc565b80601f016020809104026020016040519081016040528092919081815260200182805461120390612cbc565b80156112505780601f1061122557610100808354040283529160200191611250565b820191906000526020600020905b81548152906001019060200180831161123357829003601f168201915b5050505050905090565b8060076000611267611acc565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611314611acc565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611359919061237e565b60405180910390a35050565b61136d611780565b8181905084849050146113b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ac90612bc7565b60405180910390fd5b60005b84849050811015611434578282828181106113d6576113d5612be7565b5b90506020020135600960008787858181106113f4576113f3612be7565b5b90506020020160208101906114099190612847565b60ff1660ff16815260200190815260200160002081905550808061142c90612c45565b9150506113b8565b5050505050565b6114468484846109a0565b60008373ffffffffffffffffffffffffffffffffffffffff163b146114875761147184848484611cc5565b6114865761148563d1a57ed660e01b611877565b5b5b50505050565b600a6020528060005260406000206000915090505481565b60606114b0826117fe565b6114c5576114c463a14c4b5060e01b611877565b5b60006114cf611df4565b9050600081510361156a57600d80546114e790612cbc565b80601f016020809104026020016040519081016040528092919081815260200182805461151390612cbc565b80156115605780601f1061153557610100808354040283529160200191611560565b820191906000526020600020905b81548152906001019060200180831161154357829003601f168201915b5050505050611595565b8061157484611e86565b604051602001611585929190613328565b6040516020818303038152906040525b915050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600080856040516020016116459190613394565b6040516020818303038152906040528051906020012090506116c2848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050600b60008860ff1660ff1681526020019081526020016000205483611ed6565b915050949350505050565b6116d5611780565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611744576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161173b90613421565b60405180910390fd5b61174d81611bff565b50565b600061175b82611b8a565b9050919050565b61176a611780565b8181600d918261177b929190612f56565b505050565b611788611eed565b73ffffffffffffffffffffffffffffffffffffffff166117a661119e565b73ffffffffffffffffffffffffffffffffffffffff16146117fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117f39061348d565b60405180910390fd5b565b6000816118096119b0565b11611872576000548210156118715760005b600060046000858152602001908152602001600020549150810361184a5782611843906134ad565b925061181b565b60007c01000000000000000000000000000000000000000000000000000000008216149150505b5b919050565b8060005260046000fd5b600061188c83610e32565b90508180156118ce57508073ffffffffffffffffffffffffffffffffffffffff166118b5611acc565b73ffffffffffffffffffffffffffffffffffffffff1614155b156118fa576118e4816118df611acc565b61159d565b6118f9576118f863cfb3b94260e01b611877565b5b5b836006600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b60006001905090565b6000816119c46119b0565b11611a8f576004600083815260200190815260200160002054905060008103611a66576000548210611a0157611a0063df2d9b4260e01b611877565b5b5b60046000836001900393508381526020019081526020016000205490506000810315611a615760007c010000000000000000000000000000000000000000000000000000000082160315611aa057611a6063df2d9b4260e01b611877565b5b611a02565b60007c010000000000000000000000000000000000000000000000000000000082160315611aa0575b611a9f63df2d9b4260e01b611877565b5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8611b35868684611ef5565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6000611b816119b0565b60005403905090565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b611bfb828260405180602001604052806000815250611efe565b5050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611ceb611acc565b8786866040518563ffffffff1660e01b8152600401611d0d949392919061352b565b6020604051808303816000875af1925050508015611d4957506040513d601f19601f82011682018060405250810190611d46919061358c565b60015b611da1573d8060008114611d79576040519150601f19603f3d011682016040523d82523d6000602084013e611d7e565b606091505b506000815103611d9957611d9863d1a57ed660e01b611877565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600c8054611e0390612cbc565b80601f0160208091040260200160405190810160405280929190818152602001828054611e2f90612cbc565b8015611e7c5780601f10611e5157610100808354040283529160200191611e7c565b820191906000526020600020905b815481529060010190602001808311611e5f57829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b600115611ec157600184039350600a81066030018453600a8104905080611e9f575b50828103602084039350808452505050919050565b600082611ee38584611f83565b1490509392505050565b600033905090565b60009392505050565b611f088383611fd9565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611f7e57600080549050600083820390505b611f486000868380600101945086611cc5565b611f5d57611f5c63d1a57ed660e01b611877565b5b818110611f35578160005414611f7b57611f7a600060e01b611877565b5b50505b505050565b60008082905060005b8451811015611fce57611fb982868381518110611fac57611fab612be7565b5b602002602001015161213c565b91508080611fc690612c45565b915050611f8c565b508091505092915050565b60008054905060008203611ff857611ff763b562e8dd60e01b611877565b5b6120056000848385611b18565b612025836120166000866000611b1e565b61201f85612167565b17611b46565b6004600083815260200190815260200160002081905550600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550600073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff16169050600081036120dd576120dc632e07630060e01b611877565b5b6000838301905060008390505b808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a48181600101915081036120ea57816000819055505050506121376000848385611b71565b505050565b60008183106121545761214f8284612177565b61215f565b61215e8383612177565b5b905092915050565b60006001821460e11b9050919050565b600082600052816020526040600020905092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126121c7576121c66121a2565b5b8235905067ffffffffffffffff8111156121e4576121e36121a7565b5b602083019150836020820283011115612200576121ff6121ac565b5b9250929050565b60008083601f84011261221d5761221c6121a2565b5b8235905067ffffffffffffffff81111561223a576122396121a7565b5b602083019150836020820283011115612256576122556121ac565b5b9250929050565b6000806000806040858703121561227757612276612198565b5b600085013567ffffffffffffffff8111156122955761229461219d565b5b6122a1878288016121b1565b9450945050602085013567ffffffffffffffff8111156122c4576122c361219d565b5b6122d087828801612207565b925092505092959194509250565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612313816122de565b811461231e57600080fd5b50565b6000813590506123308161230a565b92915050565b60006020828403121561234c5761234b612198565b5b600061235a84828501612321565b91505092915050565b60008115159050919050565b61237881612363565b82525050565b6000602082019050612393600083018461236f565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156123d35780820151818401526020810190506123b8565b60008484015250505050565b6000601f19601f8301169050919050565b60006123fb82612399565b61240581856123a4565b93506124158185602086016123b5565b61241e816123df565b840191505092915050565b6000602082019050818103600083015261244381846123f0565b905092915050565b6000819050919050565b61245e8161244b565b811461246957600080fd5b50565b60008135905061247b81612455565b92915050565b60006020828403121561249757612496612198565b5b60006124a58482850161246c565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006124d9826124ae565b9050919050565b6124e9816124ce565b82525050565b600060208201905061250460008301846124e0565b92915050565b612513816124ce565b811461251e57600080fd5b50565b6000813590506125308161250a565b92915050565b6000806040838503121561254d5761254c612198565b5b600061255b85828601612521565b925050602061256c8582860161246c565b9150509250929050565b61257f8161244b565b82525050565b600060208201905061259a6000830184612576565b92915050565b6000806000606084860312156125b9576125b8612198565b5b60006125c786828701612521565b93505060206125d886828701612521565b92505060406125e98682870161246c565b9150509250925092565b60008083601f840112612609576126086121a2565b5b8235905067ffffffffffffffff811115612626576126256121a7565b5b602083019150836020820283011115612642576126416121ac565b5b9250929050565b6000806000806040858703121561266357612662612198565b5b600085013567ffffffffffffffff8111156126815761268061219d565b5b61268d878288016121b1565b9450945050602085013567ffffffffffffffff8111156126b0576126af61219d565b5b6126bc878288016125f3565b925092505092959194509250565b60008083601f8401126126e0576126df6121a2565b5b8235905067ffffffffffffffff8111156126fd576126fc6121a7565b5b602083019150836001820283011115612719576127186121ac565b5b9250929050565b6000806020838503121561273757612736612198565b5b600083013567ffffffffffffffff8111156127555761275461219d565b5b612761858286016126ca565b92509250509250929050565b600060ff82169050919050565b6127838161276d565b811461278e57600080fd5b50565b6000813590506127a08161277a565b92915050565b600080600080606085870312156127c0576127bf612198565b5b60006127ce8782880161246c565b94505060206127df87828801612791565b935050604085013567ffffffffffffffff811115612800576127ff61219d565b5b61280c87828801612207565b925092505092959194509250565b6000602082840312156128305761282f612198565b5b600061283e84828501612521565b91505092915050565b60006020828403121561285d5761285c612198565b5b600061286b84828501612791565b91505092915050565b6000819050919050565b61288781612874565b82525050565b60006020820190506128a2600083018461287e565b92915050565b6128b181612363565b81146128bc57600080fd5b50565b6000813590506128ce816128a8565b92915050565b600080604083850312156128eb576128ea612198565b5b60006128f985828601612521565b925050602061290a858286016128bf565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612951826123df565b810181811067ffffffffffffffff821117156129705761296f612919565b5b80604052505050565b600061298361218e565b905061298f8282612948565b919050565b600067ffffffffffffffff8211156129af576129ae612919565b5b6129b8826123df565b9050602081019050919050565b82818337600083830152505050565b60006129e76129e284612994565b612979565b905082815260208101848484011115612a0357612a02612914565b5b612a0e8482856129c5565b509392505050565b600082601f830112612a2b57612a2a6121a2565b5b8135612a3b8482602086016129d4565b91505092915050565b60008060008060808587031215612a5e57612a5d612198565b5b6000612a6c87828801612521565b9450506020612a7d87828801612521565b9350506040612a8e8782880161246c565b925050606085013567ffffffffffffffff811115612aaf57612aae61219d565b5b612abb87828801612a16565b91505092959194509250565b60008060408385031215612ade57612add612198565b5b6000612aec85828601612521565b9250506020612afd85828601612521565b9150509250929050565b60008060008060608587031215612b2157612b20612198565b5b6000612b2f87828801612521565b9450506020612b4087828801612791565b935050604085013567ffffffffffffffff811115612b6157612b6061219d565b5b612b6d87828801612207565b925092505092959194509250565b7f4172726179206c656e6774687320646f206e6f74206d617463682e0000000000600082015250565b6000612bb1601b836123a4565b9150612bbc82612b7b565b602082019050919050565b60006020820190508181036000830152612be081612ba4565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612c508261244b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612c8257612c81612c16565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680612cd457607f821691505b602082108103612ce757612ce6612c8d565b5b50919050565b600081905092915050565b50565b6000612d08600083612ced565b9150612d1382612cf8565b600082019050919050565b6000612d2982612cfb565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b6000612d696010836123a4565b9150612d7482612d33565b602082019050919050565b60006020820190508181036000830152612d9881612d5c565b9050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302612e0c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612dcf565b612e168683612dcf565b95508019841693508086168417925050509392505050565b6000819050919050565b6000612e53612e4e612e498461244b565b612e2e565b61244b565b9050919050565b6000819050919050565b612e6d83612e38565b612e81612e7982612e5a565b848454612ddc565b825550505050565b600090565b612e96612e89565b612ea1818484612e64565b505050565b5b81811015612ec557612eba600082612e8e565b600181019050612ea7565b5050565b601f821115612f0a57612edb81612daa565b612ee484612dbf565b81016020851015612ef3578190505b612f07612eff85612dbf565b830182612ea6565b50505b505050565b600082821c905092915050565b6000612f2d60001984600802612f0f565b1980831691505092915050565b6000612f468383612f1c565b9150826002028217905092915050565b612f608383612d9f565b67ffffffffffffffff811115612f7957612f78612919565b5b612f838254612cbc565b612f8e828285612ec9565b6000601f831160018114612fbd5760008415612fab578287013590505b612fb58582612f3a565b86555061301d565b601f198416612fcb86612daa565b60005b82811015612ff357848901358255600182019150602085019450602081019050612fce565b86831015613010578489013561300c601f891682612f1c565b8355505b6001600288020188555050505b50505050505050565b7f43616c6c65722063616e6e6f74206265206120636f6e74726163742e00000000600082015250565b600061305c601c836123a4565b915061306782613026565b602082019050919050565b6000602082019050818103600083015261308b8161304f565b9050919050565b7f4e6f742077686974656c69737465640000000000000000000000000000000000600082015250565b60006130c8600f836123a4565b91506130d382613092565b602082019050919050565b600060208201905081810360008301526130f7816130bb565b9050919050565b7f436f6c6c656374696f6e2053697a652072656163686564210000000000000000600082015250565b60006131346018836123a4565b915061313f826130fe565b602082019050919050565b6000602082019050818103600083015261316381613127565b9050919050565b60006131758261244b565b91506131808361244b565b925082820190508082111561319857613197612c16565b5b92915050565b7f57686974656c697374206d696e74206c696d6974206578636565647300000000600082015250565b60006131d4601c836123a4565b91506131df8261319e565b602082019050919050565b60006020820190508181036000830152613203816131c7565b9050919050565b60006132158261244b565b91506132208361244b565b925082820390508181111561323857613237612c16565b5b92915050565b60006132498261244b565b91506132548361244b565b92508282026132628161244b565b9150828204841483151761327957613278612c16565b5b5092915050565b7f45544820696e73756666696369656e742e000000000000000000000000000000600082015250565b60006132b66011836123a4565b91506132c182613280565b602082019050919050565b600060208201905081810360008301526132e5816132a9565b9050919050565b600081905092915050565b600061330282612399565b61330c81856132ec565b935061331c8185602086016123b5565b80840191505092915050565b600061333482856132f7565b915061334082846132f7565b91508190509392505050565b60008160601b9050919050565b60006133648261334c565b9050919050565b600061337682613359565b9050919050565b61338e613389826124ce565b61336b565b82525050565b60006133a0828461337d565b60148201915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061340b6026836123a4565b9150613416826133af565b604082019050919050565b6000602082019050818103600083015261343a816133fe565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006134776020836123a4565b915061348282613441565b602082019050919050565b600060208201905081810360008301526134a68161346a565b9050919050565b60006134b88261244b565b9150600082036134cb576134ca612c16565b5b600182039050919050565b600081519050919050565b600082825260208201905092915050565b60006134fd826134d6565b61350781856134e1565b93506135178185602086016123b5565b613520816123df565b840191505092915050565b600060808201905061354060008301876124e0565b61354d60208301866124e0565b61355a6040830185612576565b818103606083015261356c81846134f2565b905095945050505050565b6000815190506135868161230a565b92915050565b6000602082840312156135a2576135a1612198565b5b60006135b084828501613577565b9150509291505056fea264697066735822122050efdeb9f18d283c584034d25ae65a96eb26f2f11a550e955d70bdbcebaf364964736f6c63430008120033
Deployed Bytecode Sourcemap
154:5153:2:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3197:328;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;9164:630:1;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10048:98;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;16911:223;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;16639:122;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;5894:317;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;20546:3447;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;5136:169:2;;;;;;;;;;;;;:::i;:::-;;24084:187:1;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;249:45:2;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2780:339;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4401:104;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;11409:150:1;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;731:1611:2;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;7045:239:1;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1824:101:5;;;;;;;;;;;;;:::i;:::-;;528:43:2;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;347:42;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1194:85:5;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10217:102:1;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17461:231;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3603:327:2;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;24852:405:1;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;470:52:2;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4548:333;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17842:162:1;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2454:254:2;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2074:198:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3997:117:2;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4929:123;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3197:328;1087:13:5;:11;:13::i;:::-;3342:10:2::1;;:17;;3319:12;;:19;;:40;3311:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;3406:9;3401:118;3425:12;;:19;;3421:1;:23;3401:118;;;3495:10;;3506:1;3495:13;;;;;;;:::i;:::-;;;;;;;;3465:10;:27;3476:12;;3489:1;3476:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;3465:27;;;;;;;;;;;;;;;:43;;;;3446:3;;;;;:::i;:::-;;;;3401:118;;;;3197:328:::0;;;;:::o;9164:630:1:-;9249:4;9582:10;9567:25;;:11;:25;;;;:101;;;;9658:10;9643:25;;:11;:25;;;;9567:101;:177;;;;9734:10;9719:25;;:11;:25;;;;9567:177;9548:196;;9164:630;;;:::o;10048:98::-;10102:13;10134:5;10127:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10048:98;:::o;16911:223::-;16987:7;17011:16;17019:7;17011;:16::i;:::-;17006:73;;17029:50;17037:41;;;17029:7;:50::i;:::-;17006:73;17097:15;:24;17113:7;17097:24;;;;;;;;;;;:30;;;;;;;;;;;;17090:37;;16911:223;;;:::o;16639:122::-;16727:27;16736:2;16740:7;16749:4;16727:8;:27::i;:::-;16639:122;;:::o;5894:317::-;5955:7;6179:15;:13;:15::i;:::-;6164:12;;6148:13;;:28;:46;6141:53;;5894:317;:::o;20546:3447::-;20683:27;20713;20732:7;20713:18;:27::i;:::-;20683:57;;2785:14;20881:4;20865:22;;:41;20842:66;;20964:4;20923:45;;20939:19;20923:45;;;20919:95;;20970:44;20978:35;;;20970:7;:44::i;:::-;20919:95;21026:27;21055:23;21082:35;21109:7;21082:26;:35::i;:::-;21025:92;;;;21214:68;21239:15;21256:4;21262:19;:17;:19::i;:::-;21214:24;:68::i;:::-;21209:188;;21301:43;21318:4;21324:19;:17;:19::i;:::-;21301:16;:43::i;:::-;21296:101;;21346:51;21354:42;;;21346:7;:51::i;:::-;21296:101;21209:188;21408:43;21430:4;21436:2;21440:7;21449:1;21408:21;:43::i;:::-;21540:15;21537:157;;;21678:1;21657:19;21650:30;21537:157;22066:18;:24;22085:4;22066:24;;;;;;;;;;;;;;;;22064:26;;;;;;;;;;;;22134:18;:22;22153:2;22134:22;;;;;;;;;;;;;;;;22132:24;;;;;;;;;;;22449:143;22485:2;22533:45;22548:4;22554:2;22558:19;22533:14;:45::i;:::-;2392:8;22505:73;22449:18;:143::i;:::-;22420:17;:26;22438:7;22420:26;;;;;;;;;;;:172;;;;22760:1;2392:8;22709:19;:47;:52;22705:617;;22781:19;22813:1;22803:7;:11;22781:33;;22968:1;22934:17;:30;22952:11;22934:30;;;;;;;;;;;;:35;22930:378;;23070:13;;23055:11;:28;23051:239;;23248:19;23215:17;:30;23233:11;23215:30;;;;;;;;;;;:52;;;;23051:239;22930:378;22763:559;22705:617;23431:16;2785:14;23466:2;23450:20;;:39;23431:58;;23821:7;23786:8;23753:4;23696:25;23642:1;23586;23564:292;23891:1;23879:8;:13;23875:58;;23894:39;23902:30;;;23894:7;:39::i;:::-;23875:58;23944:42;23965:4;23971:2;23975:7;23984:1;23944:20;:42::i;:::-;20673:3320;;;;20546:3447;;;:::o;5136:169:2:-;1087:13:5;:11;:13::i;:::-;5186:12:2::1;5203:10;:15;;5226:21;5203:49;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5185:67;;;5270:7;5262:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;5175:130;5136:169::o:0;24084:187:1:-;24225:39;24242:4;24248:2;24252:7;24225:39;;;;;;;;;;;;:16;:39::i;:::-;24084:187;;;:::o;249:45:2:-;290:4;249:45;:::o;2780:339::-;1087:13:5;:11;:13::i;:::-;2931:8:2::1;;:15;;2908:12;;:19;;:38;2900:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;2993:9;2988:125;3012:12;;:19;;3008:1;:23;2988:125;;;3091:8;;3100:1;3091:11;;;;;;;:::i;:::-;;;;;;;;3052:19;:36;3072:12;;3085:1;3072:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;3052:36;;;;;;;;;;;;;;;:50;;;;3033:3;;;;;:::i;:::-;;;;2988:125;;;;2780:339:::0;;;;:::o;4401:104::-;1087:13:5;:11;:13::i;:::-;4491:7:2::1;;4475:13;:23;;;;;;;:::i;:::-;;4401:104:::0;;:::o;11409:150:1:-;11481:7;11523:27;11542:7;11523:18;:27::i;:::-;11500:52;;11409:150;;;:::o;731:1611:2:-;917:10;904:23;;:9;:23;;;896:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;1028:47;1045:10;1057;1069:5;;1028:16;:47::i;:::-;1020:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;290:4;1178:14;:12;:14::i;:::-;:31;1170:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;1404:19;:31;1424:10;1404:31;;;;;;;;;;;;;;;;1391:8;1363:25;1377:10;1363:13;:25::i;:::-;:36;;;;:::i;:::-;1362:73;;1354:131;;;;;;;;;;;;:::i;:::-;;;;;;;;;290:4;1632:8;1615:14;:12;:14::i;:::-;:25;;;;:::i;:::-;:42;1611:115;;;1701:14;:12;:14::i;:::-;290:4;1684:31;;;;:::i;:::-;1673:42;;1611:115;1815:23;1852:9;:21;1862:10;1852:21;;;;;;;;;;;;;;;;1841:8;:32;;;;:::i;:::-;1815:58;;1904:15;1891:9;:28;;1883:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;1991:31;2001:10;2013:8;1991:9;:31::i;:::-;2237:15;2225:9;:27;2221:115;;;2276:10;2268:28;;:57;2309:15;2297:9;:27;;;;:::i;:::-;2268:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2221:115;833:1509;731:1611;;;;:::o;7045:239:1:-;7117:7;7157:1;7140:19;;:5;:19;;;7136:69;;7161:44;7169:35;;;7161:7;:44::i;:::-;7136:69;1360:13;7222:18;:25;7241:5;7222:25;;;;;;;;;;;;;;;;:55;7215:62;;7045:239;;;:::o;1824:101:5:-;1087:13;:11;:13::i;:::-;1888:30:::1;1915:1;1888:18;:30::i;:::-;1824:101::o:0;528:43:2:-;;;;;;;;;;;;;;;;;:::o;347:42::-;;;;;;;;;;;;;;;;;:::o;1194:85:5:-;1240:7;1266:6;;;;;;;;;;;1259:13;;1194:85;:::o;10217:102:1:-;10273:13;10305:7;10298:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10217:102;:::o;17461:231::-;17607:8;17555:18;:39;17574:19;:17;:19::i;:::-;17555:39;;;;;;;;;;;;;;;:49;17595:8;17555:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;17666:8;17630:55;;17645:19;:17;:19::i;:::-;17630:55;;;17676:8;17630:55;;;;;;:::i;:::-;;;;;;;;17461:231;;:::o;3603:327:2:-;1087:13:5;:11;:13::i;:::-;3748:10:2::1;;:17;;3725:12;;:19;;:40;3717:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;3812:9;3807:117;3831:12;;:19;;3827:1;:23;3807:117;;;3900:10;;3911:1;3900:13;;;;;;;:::i;:::-;;;;;;;;3871:9;:26;3881:12;;3894:1;3881:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;3871:26;;;;;;;;;;;;;;;:42;;;;3852:3;;;;;:::i;:::-;;;;3807:117;;;;3603:327:::0;;;;:::o;24852:405:1:-;25021:31;25034:4;25040:2;25044:7;25021:12;:31::i;:::-;25084:1;25066:2;:14;;;:19;25062:189;;25104:56;25135:4;25141:2;25145:7;25154:5;25104:30;:56::i;:::-;25099:152;;25180:56;25188:47;;;25180:7;:56::i;:::-;25099:152;25062:189;24852:405;;;;:::o;470:52:2:-;;;;;;;;;;;;;;;;;:::o;4548:333::-;4621:13;4651:16;4659:7;4651;:16::i;:::-;4646:68;;4669:45;4677:36;;;4669:7;:45::i;:::-;4646:68;4724:21;4748:10;:8;:10::i;:::-;4724:34;;4800:1;4781:7;4775:21;:26;:99;;4860:14;4775:99;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4828:7;4837:18;4847:7;4837:9;:18::i;:::-;4811:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;4775:99;4768:106;;;4548:333;;;:::o;17842:162:1:-;17939:4;17962:18;:25;17981:5;17962:25;;;;;;;;;;;;;;;:35;17988:8;17962:35;;;;;;;;;;;;;;;;;;;;;;;;;17955:42;;17842:162;;;;:::o;2454:254:2:-;2562:4;2578:12;2620:7;2603:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;2593:36;;;;;;2578:51;;2646:55;2665:5;;2646:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2672:10;:22;2683:10;2672:22;;;;;;;;;;;;;;;;2696:4;2646:18;:55::i;:::-;2639:62;;;2454:254;;;;;;:::o;2074:198:5:-;1087:13;:11;:13::i;:::-;2182:1:::1;2162:22;;:8;:22;;::::0;2154:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;2237:28;2256:8;2237:18;:28::i;:::-;2074:198:::0;:::o;3997:117:2:-;4059:7;4085:22;4099:7;4085:13;:22::i;:::-;4078:29;;3997:117;;;:::o;4929:123::-;1087:13:5;:11;:13::i;:::-;5032::2::1;;5015:14;:30;;;;;;;:::i;:::-;;4929:123:::0;;:::o;1352:130:5:-;1426:12;:10;:12::i;:::-;1415:23;;:7;:5;:7::i;:::-;:23;;;1407:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;1352:130::o;18253:360:1:-;18318:11;18364:7;18345:15;:13;:15::i;:::-;:26;18341:266;;18401:13;;18391:7;:23;18387:210;;;18434:14;18466:60;18514:1;18483:17;:26;18501:7;18483:26;;;;;;;;;;;;18474:35;;;18473:42;18466:60;;18517:9;;;;:::i;:::-;;;18466:60;;;18581:1;2118:8;18553:6;:24;:29;18544:38;;18416:181;18387:210;18341:266;18253:360;;;:::o;43371:160::-;43470:13;43464:4;43457:27;43510:4;43504;43497:18;35019:460;35143:13;35159:16;35167:7;35159;:16::i;:::-;35143:32;;35190:13;:45;;;;;35230:5;35207:28;;:19;:17;:19::i;:::-;:28;;;;35190:45;35186:198;;;35254:44;35271:5;35278:19;:17;:19::i;:::-;35254:16;:44::i;:::-;35249:135;;35318:51;35326:42;;;35318:7;:51::i;:::-;35249:135;35186:198;35427:2;35394:15;:24;35410:7;35394:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;35464:7;35460:2;35444:28;;35453:5;35444:28;;;;;;;;;;;;35133:346;35019:460;;;:::o;5426:90::-;5482:7;5508:1;5501:8;;5426:90;:::o;12850:1978::-;12917:14;12966:7;12947:15;:13;:15::i;:::-;:26;12943:1822;;12998:17;:26;13016:7;12998:26;;;;;;;;;;;;12989:35;;13132:1;13122:6;:11;13118:1270;;13168:13;;13157:7;:24;13153:77;;13183:47;13191:38;;;13183:7;:47::i;:::-;13153:77;13777:597;13853:17;:28;13871:9;;;;;;;13853:28;;;;;;;;;;;;13844:37;;13939:1;13929:6;:11;13925:25;13942:8;13925:25;14004:1;2118:8;13976:6;:24;:29;13972:48;14007:13;13972:48;14308:47;14316:38;;;14308:7;:47::i;:::-;13777:597;;;13118:1270;14738:1;2118:8;14710:6;:24;:29;14706:48;14741:13;14706:48;12943:1822;14774:47;14782:38;;;14774:7;:47::i;:::-;12850:1978;;;;:::o;19471:474::-;19570:27;19599:23;19638:38;19679:15;:24;19695:7;19679:24;;;;;;;;;;;19638:65;;19853:18;19830:41;;19909:19;19903:26;19884:45;;19816:123;19471:474;;;:::o;41401:103::-;41461:7;41487:10;41480:17;;41401:103;:::o;18717:646::-;18862:11;19024:16;19017:5;19013:28;19004:37;;19182:16;19171:9;19167:32;19154:45;;19330:15;19319:9;19316:30;19308:5;19297:9;19294:20;19291:56;19281:66;;18717:646;;;;;:::o;25901:154::-;;;;;:::o;40728:304::-;40859:7;40878:16;2513:3;40904:19;:41;;40878:68;;2513:3;40971:31;40982:4;40988:2;40992:9;40971:10;:31::i;:::-;40963:40;;:62;;40956:69;;;40728:304;;;;;:::o;15361:443::-;15441:14;15606:16;15599:5;15595:28;15586:37;;15781:5;15767:11;15742:23;15738:41;15735:52;15728:5;15725:63;15715:73;;15361:443;;;;:::o;26702:153::-;;;;;:::o;6304:290::-;6359:7;6562:15;:13;:15::i;:::-;6546:13;;:31;6539:38;;6304:290;:::o;7361:176::-;7422:7;1360:13;1495:2;7449:18;:25;7468:5;7449:25;;;;;;;;;;;;;;;;:50;;7448:82;7441:89;;7361:176;;;:::o;34129:110::-;34205:27;34215:2;34219:8;34205:27;;;;;;;;;;;;:9;:27::i;:::-;34129:110;;:::o;2426:187:5:-;2499:16;2518:6;;;;;;;;;;;2499:25;;2543:8;2534:6;;:17;;;;;;;;;;;;;;;;;;2597:8;2566:40;;2587:8;2566:40;;;;;;;;;;;;2489:124;2426:187;:::o;27283:673:1:-;27441:4;27486:2;27461:45;;;27507:19;:17;:19::i;:::-;27528:4;27534:7;27543:5;27461:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;27457:493;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27756:1;27739:6;:13;:18;27735:113;;27777:56;27785:47;;;27777:7;:56::i;:::-;27735:113;27918:6;27912:13;27903:6;27899:2;27895:15;27888:38;27457:493;27627:54;;;27617:64;;;:6;:64;;;;27610:71;;;27283:673;;;;;;:::o;4242:112:2:-;4302:13;4334;4327:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4242:112;:::o;41601:1708:1:-;41666:17;42094:4;42087;42081:11;42077:22;42184:1;42178:4;42171:15;42257:4;42254:1;42250:12;42243:19;;42337:1;42332:3;42325:14;42438:3;42672:5;42654:419;42680:1;42654:419;;;42719:1;42714:3;42710:11;42703:18;;42887:2;42881:4;42877:13;42873:2;42869:22;42864:3;42856:36;42979:2;42973:4;42969:13;42961:21;;43044:4;42654:419;43034:25;42654:419;42658:21;43110:3;43105;43101:13;43223:4;43218:3;43214:14;43207:21;;43286:6;43281:3;43274:19;41704:1599;;;41601:1708;;;:::o;1156:154:4:-;1247:4;1299;1270:25;1283:5;1290:4;1270:12;:25::i;:::-;:33;1263:40;;1156:154;;;;;:::o;640:96:0:-;693:7;719:10;712:17;;640:96;:::o;40439:143:1:-;40572:6;40439:143;;;;;:::o;33362:688::-;33488:19;33494:2;33498:8;33488:5;:19::i;:::-;33564:1;33546:2;:14;;;:19;33542:492;;33585:11;33599:13;;33585:27;;33630:13;33652:8;33646:3;:14;33630:30;;33678:238;33708:62;33747:1;33751:2;33755:7;;;;;;33764:5;33708:30;:62::i;:::-;33703:174;;33798:56;33806:47;;;33798:7;:56::i;:::-;33703:174;33911:3;33903:5;:11;33678:238;;33996:3;33979:13;;:20;33975:44;;34001:18;34016:1;34009:9;;34001:7;:18::i;:::-;33975:44;33567:467;;33542:492;33362:688;;;:::o;1934:290:4:-;2017:7;2036:20;2059:4;2036:27;;2078:9;2073:116;2097:5;:12;2093:1;:16;2073:116;;;2145:33;2155:12;2169:5;2175:1;2169:8;;;;;;;;:::i;:::-;;;;;;;;2145:9;:33::i;:::-;2130:48;;2111:3;;;;;:::i;:::-;;;;2073:116;;;;2205:12;2198:19;;;1934:290;;;;:::o;28402:2251:1:-;28474:20;28497:13;;28474:36;;28536:1;28524:8;:13;28520:53;;28539:34;28547:25;;;28539:7;:34::i;:::-;28520:53;28584:61;28614:1;28618:2;28622:12;28636:8;28584:21;:61::i;:::-;29107:136;29143:2;29196:33;29219:1;29223:2;29227:1;29196:14;:33::i;:::-;29163:30;29184:8;29163:20;:30::i;:::-;:66;29107:18;:136::i;:::-;29073:17;:31;29091:12;29073:31;;;;;;;;;;;:170;;;;29523:1;1495:2;29493:1;:26;;29492:32;29480:8;:45;29454:18;:22;29473:2;29454:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;29633:16;2785:14;29668:2;29652:20;;:39;29633:58;;29722:1;29710:8;:13;29706:54;;29725:35;29733:26;;;29725:7;:35::i;:::-;29706:54;29775:11;29804:8;29789:12;:23;29775:37;;29826:15;29844:12;29826:30;;29871:662;30281:7;30238:8;30194:1;30129:25;30067:1;30003;29973:351;30528:3;30515:9;;;;;;:16;29871:662;;30563:3;30547:13;:19;;;;28828:1749;;;30586:60;30615:1;30619:2;30623:12;30637:8;30586:20;:60::i;:::-;28464:2189;28402:2251;;:::o;8975:147:4:-;9038:7;9068:1;9064;:5;:51;;9095:20;9110:1;9113;9095:14;:20::i;:::-;9064:51;;;9072:20;9087:1;9090;9072:14;:20::i;:::-;9064:51;9057:58;;8975:147;;;;:::o;15901:318:1:-;15971:14;16200:1;16190:8;16187:15;16161:24;16157:46;16147:56;;15901:318;;;:::o;9128:261:4:-;9196:13;9300:1;9294:4;9287:15;9328:1;9322:4;9315:15;9368:4;9362;9352:21;9343:30;;9128:261;;;;:::o;7:75:6:-;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:117;443:1;440;433:12;457:117;566:1;563;556:12;580:117;689:1;686;679:12;718:566;789:8;799:6;849:3;842:4;834:6;830:17;826:27;816:122;;857:79;;:::i;:::-;816:122;970:6;957:20;947:30;;1000:18;992:6;989:30;986:117;;;1022:79;;:::i;:::-;986:117;1136:4;1128:6;1124:17;1112:29;;1190:3;1182:4;1174:6;1170:17;1160:8;1156:32;1153:41;1150:128;;;1197:79;;:::i;:::-;1150:128;718:566;;;;;:::o;1307:568::-;1380:8;1390:6;1440:3;1433:4;1425:6;1421:17;1417:27;1407:122;;1448:79;;:::i;:::-;1407:122;1561:6;1548:20;1538:30;;1591:18;1583:6;1580:30;1577:117;;;1613:79;;:::i;:::-;1577:117;1727:4;1719:6;1715:17;1703:29;;1781:3;1773:4;1765:6;1761:17;1751:8;1747:32;1744:41;1741:128;;;1788:79;;:::i;:::-;1741:128;1307:568;;;;;:::o;1881:930::-;2001:6;2009;2017;2025;2074:2;2062:9;2053:7;2049:23;2045:32;2042:119;;;2080:79;;:::i;:::-;2042:119;2228:1;2217:9;2213:17;2200:31;2258:18;2250:6;2247:30;2244:117;;;2280:79;;:::i;:::-;2244:117;2393:78;2463:7;2454:6;2443:9;2439:22;2393:78;:::i;:::-;2375:96;;;;2171:310;2548:2;2537:9;2533:18;2520:32;2579:18;2571:6;2568:30;2565:117;;;2601:79;;:::i;:::-;2565:117;2714:80;2786:7;2777:6;2766:9;2762:22;2714:80;:::i;:::-;2696:98;;;;2491:313;1881:930;;;;;;;:::o;2817:149::-;2853:7;2893:66;2886:5;2882:78;2871:89;;2817:149;;;:::o;2972:120::-;3044:23;3061:5;3044:23;:::i;:::-;3037:5;3034:34;3024:62;;3082:1;3079;3072:12;3024:62;2972:120;:::o;3098:137::-;3143:5;3181:6;3168:20;3159:29;;3197:32;3223:5;3197:32;:::i;:::-;3098:137;;;;:::o;3241:327::-;3299:6;3348:2;3336:9;3327:7;3323:23;3319:32;3316:119;;;3354:79;;:::i;:::-;3316:119;3474:1;3499:52;3543:7;3534:6;3523:9;3519:22;3499:52;:::i;:::-;3489:62;;3445:116;3241:327;;;;:::o;3574:90::-;3608:7;3651:5;3644:13;3637:21;3626:32;;3574:90;;;:::o;3670:109::-;3751:21;3766:5;3751:21;:::i;:::-;3746:3;3739:34;3670:109;;:::o;3785:210::-;3872:4;3910:2;3899:9;3895:18;3887:26;;3923:65;3985:1;3974:9;3970:17;3961:6;3923:65;:::i;:::-;3785:210;;;;:::o;4001:99::-;4053:6;4087:5;4081:12;4071:22;;4001:99;;;:::o;4106:169::-;4190:11;4224:6;4219:3;4212:19;4264:4;4259:3;4255:14;4240:29;;4106:169;;;;:::o;4281:246::-;4362:1;4372:113;4386:6;4383:1;4380:13;4372:113;;;4471:1;4466:3;4462:11;4456:18;4452:1;4447:3;4443:11;4436:39;4408:2;4405:1;4401:10;4396:15;;4372:113;;;4519:1;4510:6;4505:3;4501:16;4494:27;4343:184;4281:246;;;:::o;4533:102::-;4574:6;4625:2;4621:7;4616:2;4609:5;4605:14;4601:28;4591:38;;4533:102;;;:::o;4641:377::-;4729:3;4757:39;4790:5;4757:39;:::i;:::-;4812:71;4876:6;4871:3;4812:71;:::i;:::-;4805:78;;4892:65;4950:6;4945:3;4938:4;4931:5;4927:16;4892:65;:::i;:::-;4982:29;5004:6;4982:29;:::i;:::-;4977:3;4973:39;4966:46;;4733:285;4641:377;;;;:::o;5024:313::-;5137:4;5175:2;5164:9;5160:18;5152:26;;5224:9;5218:4;5214:20;5210:1;5199:9;5195:17;5188:47;5252:78;5325:4;5316:6;5252:78;:::i;:::-;5244:86;;5024:313;;;;:::o;5343:77::-;5380:7;5409:5;5398:16;;5343:77;;;:::o;5426:122::-;5499:24;5517:5;5499:24;:::i;:::-;5492:5;5489:35;5479:63;;5538:1;5535;5528:12;5479:63;5426:122;:::o;5554:139::-;5600:5;5638:6;5625:20;5616:29;;5654:33;5681:5;5654:33;:::i;:::-;5554:139;;;;:::o;5699:329::-;5758:6;5807:2;5795:9;5786:7;5782:23;5778:32;5775:119;;;5813:79;;:::i;:::-;5775:119;5933:1;5958:53;6003:7;5994:6;5983:9;5979:22;5958:53;:::i;:::-;5948:63;;5904:117;5699:329;;;;:::o;6034:126::-;6071:7;6111:42;6104:5;6100:54;6089:65;;6034:126;;;:::o;6166:96::-;6203:7;6232:24;6250:5;6232:24;:::i;:::-;6221:35;;6166:96;;;:::o;6268:118::-;6355:24;6373:5;6355:24;:::i;:::-;6350:3;6343:37;6268:118;;:::o;6392:222::-;6485:4;6523:2;6512:9;6508:18;6500:26;;6536:71;6604:1;6593:9;6589:17;6580:6;6536:71;:::i;:::-;6392:222;;;;:::o;6620:122::-;6693:24;6711:5;6693:24;:::i;:::-;6686:5;6683:35;6673:63;;6732:1;6729;6722:12;6673:63;6620:122;:::o;6748:139::-;6794:5;6832:6;6819:20;6810:29;;6848:33;6875:5;6848:33;:::i;:::-;6748:139;;;;:::o;6893:474::-;6961:6;6969;7018:2;7006:9;6997:7;6993:23;6989:32;6986:119;;;7024:79;;:::i;:::-;6986:119;7144:1;7169:53;7214:7;7205:6;7194:9;7190:22;7169:53;:::i;:::-;7159:63;;7115:117;7271:2;7297:53;7342:7;7333:6;7322:9;7318:22;7297:53;:::i;:::-;7287:63;;7242:118;6893:474;;;;;:::o;7373:118::-;7460:24;7478:5;7460:24;:::i;:::-;7455:3;7448:37;7373:118;;:::o;7497:222::-;7590:4;7628:2;7617:9;7613:18;7605:26;;7641:71;7709:1;7698:9;7694:17;7685:6;7641:71;:::i;:::-;7497:222;;;;:::o;7725:619::-;7802:6;7810;7818;7867:2;7855:9;7846:7;7842:23;7838:32;7835:119;;;7873:79;;:::i;:::-;7835:119;7993:1;8018:53;8063:7;8054:6;8043:9;8039:22;8018:53;:::i;:::-;8008:63;;7964:117;8120:2;8146:53;8191:7;8182:6;8171:9;8167:22;8146:53;:::i;:::-;8136:63;;8091:118;8248:2;8274:53;8319:7;8310:6;8299:9;8295:22;8274:53;:::i;:::-;8264:63;;8219:118;7725:619;;;;;:::o;8367:568::-;8440:8;8450:6;8500:3;8493:4;8485:6;8481:17;8477:27;8467:122;;8508:79;;:::i;:::-;8467:122;8621:6;8608:20;8598:30;;8651:18;8643:6;8640:30;8637:117;;;8673:79;;:::i;:::-;8637:117;8787:4;8779:6;8775:17;8763:29;;8841:3;8833:4;8825:6;8821:17;8811:8;8807:32;8804:41;8801:128;;;8848:79;;:::i;:::-;8801:128;8367:568;;;;;:::o;8941:930::-;9061:6;9069;9077;9085;9134:2;9122:9;9113:7;9109:23;9105:32;9102:119;;;9140:79;;:::i;:::-;9102:119;9288:1;9277:9;9273:17;9260:31;9318:18;9310:6;9307:30;9304:117;;;9340:79;;:::i;:::-;9304:117;9453:78;9523:7;9514:6;9503:9;9499:22;9453:78;:::i;:::-;9435:96;;;;9231:310;9608:2;9597:9;9593:18;9580:32;9639:18;9631:6;9628:30;9625:117;;;9661:79;;:::i;:::-;9625:117;9774:80;9846:7;9837:6;9826:9;9822:22;9774:80;:::i;:::-;9756:98;;;;9551:313;8941:930;;;;;;;:::o;9891:553::-;9949:8;9959:6;10009:3;10002:4;9994:6;9990:17;9986:27;9976:122;;10017:79;;:::i;:::-;9976:122;10130:6;10117:20;10107:30;;10160:18;10152:6;10149:30;10146:117;;;10182:79;;:::i;:::-;10146:117;10296:4;10288:6;10284:17;10272:29;;10350:3;10342:4;10334:6;10330:17;10320:8;10316:32;10313:41;10310:128;;;10357:79;;:::i;:::-;10310:128;9891:553;;;;;:::o;10450:529::-;10521:6;10529;10578:2;10566:9;10557:7;10553:23;10549:32;10546:119;;;10584:79;;:::i;:::-;10546:119;10732:1;10721:9;10717:17;10704:31;10762:18;10754:6;10751:30;10748:117;;;10784:79;;:::i;:::-;10748:117;10897:65;10954:7;10945:6;10934:9;10930:22;10897:65;:::i;:::-;10879:83;;;;10675:297;10450:529;;;;;:::o;10985:86::-;11020:7;11060:4;11053:5;11049:16;11038:27;;10985:86;;;:::o;11077:118::-;11148:22;11164:5;11148:22;:::i;:::-;11141:5;11138:33;11128:61;;11185:1;11182;11175:12;11128:61;11077:118;:::o;11201:135::-;11245:5;11283:6;11270:20;11261:29;;11299:31;11324:5;11299:31;:::i;:::-;11201:135;;;;:::o;11342:845::-;11444:6;11452;11460;11468;11517:2;11505:9;11496:7;11492:23;11488:32;11485:119;;;11523:79;;:::i;:::-;11485:119;11643:1;11668:53;11713:7;11704:6;11693:9;11689:22;11668:53;:::i;:::-;11658:63;;11614:117;11770:2;11796:51;11839:7;11830:6;11819:9;11815:22;11796:51;:::i;:::-;11786:61;;11741:116;11924:2;11913:9;11909:18;11896:32;11955:18;11947:6;11944:30;11941:117;;;11977:79;;:::i;:::-;11941:117;12090:80;12162:7;12153:6;12142:9;12138:22;12090:80;:::i;:::-;12072:98;;;;11867:313;11342:845;;;;;;;:::o;12193:329::-;12252:6;12301:2;12289:9;12280:7;12276:23;12272:32;12269:119;;;12307:79;;:::i;:::-;12269:119;12427:1;12452:53;12497:7;12488:6;12477:9;12473:22;12452:53;:::i;:::-;12442:63;;12398:117;12193:329;;;;:::o;12528:325::-;12585:6;12634:2;12622:9;12613:7;12609:23;12605:32;12602:119;;;12640:79;;:::i;:::-;12602:119;12760:1;12785:51;12828:7;12819:6;12808:9;12804:22;12785:51;:::i;:::-;12775:61;;12731:115;12528:325;;;;:::o;12859:77::-;12896:7;12925:5;12914:16;;12859:77;;;:::o;12942:118::-;13029:24;13047:5;13029:24;:::i;:::-;13024:3;13017:37;12942:118;;:::o;13066:222::-;13159:4;13197:2;13186:9;13182:18;13174:26;;13210:71;13278:1;13267:9;13263:17;13254:6;13210:71;:::i;:::-;13066:222;;;;:::o;13294:116::-;13364:21;13379:5;13364:21;:::i;:::-;13357:5;13354:32;13344:60;;13400:1;13397;13390:12;13344:60;13294:116;:::o;13416:133::-;13459:5;13497:6;13484:20;13475:29;;13513:30;13537:5;13513:30;:::i;:::-;13416:133;;;;:::o;13555:468::-;13620:6;13628;13677:2;13665:9;13656:7;13652:23;13648:32;13645:119;;;13683:79;;:::i;:::-;13645:119;13803:1;13828:53;13873:7;13864:6;13853:9;13849:22;13828:53;:::i;:::-;13818:63;;13774:117;13930:2;13956:50;13998:7;13989:6;13978:9;13974:22;13956:50;:::i;:::-;13946:60;;13901:115;13555:468;;;;;:::o;14029:117::-;14138:1;14135;14128:12;14152:180;14200:77;14197:1;14190:88;14297:4;14294:1;14287:15;14321:4;14318:1;14311:15;14338:281;14421:27;14443:4;14421:27;:::i;:::-;14413:6;14409:40;14551:6;14539:10;14536:22;14515:18;14503:10;14500:34;14497:62;14494:88;;;14562:18;;:::i;:::-;14494:88;14602:10;14598:2;14591:22;14381:238;14338:281;;:::o;14625:129::-;14659:6;14686:20;;:::i;:::-;14676:30;;14715:33;14743:4;14735:6;14715:33;:::i;:::-;14625:129;;;:::o;14760:307::-;14821:4;14911:18;14903:6;14900:30;14897:56;;;14933:18;;:::i;:::-;14897:56;14971:29;14993:6;14971:29;:::i;:::-;14963:37;;15055:4;15049;15045:15;15037:23;;14760:307;;;:::o;15073:146::-;15170:6;15165:3;15160;15147:30;15211:1;15202:6;15197:3;15193:16;15186:27;15073:146;;;:::o;15225:423::-;15302:5;15327:65;15343:48;15384:6;15343:48;:::i;:::-;15327:65;:::i;:::-;15318:74;;15415:6;15408:5;15401:21;15453:4;15446:5;15442:16;15491:3;15482:6;15477:3;15473:16;15470:25;15467:112;;;15498:79;;:::i;:::-;15467:112;15588:54;15635:6;15630:3;15625;15588:54;:::i;:::-;15308:340;15225:423;;;;;:::o;15667:338::-;15722:5;15771:3;15764:4;15756:6;15752:17;15748:27;15738:122;;15779:79;;:::i;:::-;15738:122;15896:6;15883:20;15921:78;15995:3;15987:6;15980:4;15972:6;15968:17;15921:78;:::i;:::-;15912:87;;15728:277;15667:338;;;;:::o;16011:943::-;16106:6;16114;16122;16130;16179:3;16167:9;16158:7;16154:23;16150:33;16147:120;;;16186:79;;:::i;:::-;16147:120;16306:1;16331:53;16376:7;16367:6;16356:9;16352:22;16331:53;:::i;:::-;16321:63;;16277:117;16433:2;16459:53;16504:7;16495:6;16484:9;16480:22;16459:53;:::i;:::-;16449:63;;16404:118;16561:2;16587:53;16632:7;16623:6;16612:9;16608:22;16587:53;:::i;:::-;16577:63;;16532:118;16717:2;16706:9;16702:18;16689:32;16748:18;16740:6;16737:30;16734:117;;;16770:79;;:::i;:::-;16734:117;16875:62;16929:7;16920:6;16909:9;16905:22;16875:62;:::i;:::-;16865:72;;16660:287;16011:943;;;;;;;:::o;16960:474::-;17028:6;17036;17085:2;17073:9;17064:7;17060:23;17056:32;17053:119;;;17091:79;;:::i;:::-;17053:119;17211:1;17236:53;17281:7;17272:6;17261:9;17257:22;17236:53;:::i;:::-;17226:63;;17182:117;17338:2;17364:53;17409:7;17400:6;17389:9;17385:22;17364:53;:::i;:::-;17354:63;;17309:118;16960:474;;;;;:::o;17440:845::-;17542:6;17550;17558;17566;17615:2;17603:9;17594:7;17590:23;17586:32;17583:119;;;17621:79;;:::i;:::-;17583:119;17741:1;17766:53;17811:7;17802:6;17791:9;17787:22;17766:53;:::i;:::-;17756:63;;17712:117;17868:2;17894:51;17937:7;17928:6;17917:9;17913:22;17894:51;:::i;:::-;17884:61;;17839:116;18022:2;18011:9;18007:18;17994:32;18053:18;18045:6;18042:30;18039:117;;;18075:79;;:::i;:::-;18039:117;18188:80;18260:7;18251:6;18240:9;18236:22;18188:80;:::i;:::-;18170:98;;;;17965:313;17440:845;;;;;;;:::o;18291:177::-;18431:29;18427:1;18419:6;18415:14;18408:53;18291:177;:::o;18474:366::-;18616:3;18637:67;18701:2;18696:3;18637:67;:::i;:::-;18630:74;;18713:93;18802:3;18713:93;:::i;:::-;18831:2;18826:3;18822:12;18815:19;;18474:366;;;:::o;18846:419::-;19012:4;19050:2;19039:9;19035:18;19027:26;;19099:9;19093:4;19089:20;19085:1;19074:9;19070:17;19063:47;19127:131;19253:4;19127:131;:::i;:::-;19119:139;;18846:419;;;:::o;19271:180::-;19319:77;19316:1;19309:88;19416:4;19413:1;19406:15;19440:4;19437:1;19430:15;19457:180;19505:77;19502:1;19495:88;19602:4;19599:1;19592:15;19626:4;19623:1;19616:15;19643:233;19682:3;19705:24;19723:5;19705:24;:::i;:::-;19696:33;;19751:66;19744:5;19741:77;19738:103;;19821:18;;:::i;:::-;19738:103;19868:1;19861:5;19857:13;19850:20;;19643:233;;;:::o;19882:180::-;19930:77;19927:1;19920:88;20027:4;20024:1;20017:15;20051:4;20048:1;20041:15;20068:320;20112:6;20149:1;20143:4;20139:12;20129:22;;20196:1;20190:4;20186:12;20217:18;20207:81;;20273:4;20265:6;20261:17;20251:27;;20207:81;20335:2;20327:6;20324:14;20304:18;20301:38;20298:84;;20354:18;;:::i;:::-;20298:84;20119:269;20068:320;;;:::o;20394:147::-;20495:11;20532:3;20517:18;;20394:147;;;;:::o;20547:114::-;;:::o;20667:398::-;20826:3;20847:83;20928:1;20923:3;20847:83;:::i;:::-;20840:90;;20939:93;21028:3;20939:93;:::i;:::-;21057:1;21052:3;21048:11;21041:18;;20667:398;;;:::o;21071:379::-;21255:3;21277:147;21420:3;21277:147;:::i;:::-;21270:154;;21441:3;21434:10;;21071:379;;;:::o;21456:166::-;21596:18;21592:1;21584:6;21580:14;21573:42;21456:166;:::o;21628:366::-;21770:3;21791:67;21855:2;21850:3;21791:67;:::i;:::-;21784:74;;21867:93;21956:3;21867:93;:::i;:::-;21985:2;21980:3;21976:12;21969:19;;21628:366;;;:::o;22000:419::-;22166:4;22204:2;22193:9;22189:18;22181:26;;22253:9;22247:4;22243:20;22239:1;22228:9;22224:17;22217:47;22281:131;22407:4;22281:131;:::i;:::-;22273:139;;22000:419;;;:::o;22425:97::-;22484:6;22512:3;22502:13;;22425:97;;;;:::o;22528:141::-;22577:4;22600:3;22592:11;;22623:3;22620:1;22613:14;22657:4;22654:1;22644:18;22636:26;;22528:141;;;:::o;22675:93::-;22712:6;22759:2;22754;22747:5;22743:14;22739:23;22729:33;;22675:93;;;:::o;22774:107::-;22818:8;22868:5;22862:4;22858:16;22837:37;;22774:107;;;;:::o;22887:393::-;22956:6;23006:1;22994:10;22990:18;23029:97;23059:66;23048:9;23029:97;:::i;:::-;23147:39;23177:8;23166:9;23147:39;:::i;:::-;23135:51;;23219:4;23215:9;23208:5;23204:21;23195:30;;23268:4;23258:8;23254:19;23247:5;23244:30;23234:40;;22963:317;;22887:393;;;;;:::o;23286:60::-;23314:3;23335:5;23328:12;;23286:60;;;:::o;23352:142::-;23402:9;23435:53;23453:34;23462:24;23480:5;23462:24;:::i;:::-;23453:34;:::i;:::-;23435:53;:::i;:::-;23422:66;;23352:142;;;:::o;23500:75::-;23543:3;23564:5;23557:12;;23500:75;;;:::o;23581:269::-;23691:39;23722:7;23691:39;:::i;:::-;23752:91;23801:41;23825:16;23801:41;:::i;:::-;23793:6;23786:4;23780:11;23752:91;:::i;:::-;23746:4;23739:105;23657:193;23581:269;;;:::o;23856:73::-;23901:3;23856:73;:::o;23935:189::-;24012:32;;:::i;:::-;24053:65;24111:6;24103;24097:4;24053:65;:::i;:::-;23988:136;23935:189;;:::o;24130:186::-;24190:120;24207:3;24200:5;24197:14;24190:120;;;24261:39;24298:1;24291:5;24261:39;:::i;:::-;24234:1;24227:5;24223:13;24214:22;;24190:120;;;24130:186;;:::o;24322:543::-;24423:2;24418:3;24415:11;24412:446;;;24457:38;24489:5;24457:38;:::i;:::-;24541:29;24559:10;24541:29;:::i;:::-;24531:8;24527:44;24724:2;24712:10;24709:18;24706:49;;;24745:8;24730:23;;24706:49;24768:80;24824:22;24842:3;24824:22;:::i;:::-;24814:8;24810:37;24797:11;24768:80;:::i;:::-;24427:431;;24412:446;24322:543;;;:::o;24871:117::-;24925:8;24975:5;24969:4;24965:16;24944:37;;24871:117;;;;:::o;24994:169::-;25038:6;25071:51;25119:1;25115:6;25107:5;25104:1;25100:13;25071:51;:::i;:::-;25067:56;25152:4;25146;25142:15;25132:25;;25045:118;24994:169;;;;:::o;25168:295::-;25244:4;25390:29;25415:3;25409:4;25390:29;:::i;:::-;25382:37;;25452:3;25449:1;25445:11;25439:4;25436:21;25428:29;;25168:295;;;;:::o;25468:1403::-;25592:44;25632:3;25627;25592:44;:::i;:::-;25701:18;25693:6;25690:30;25687:56;;;25723:18;;:::i;:::-;25687:56;25767:38;25799:4;25793:11;25767:38;:::i;:::-;25852:67;25912:6;25904;25898:4;25852:67;:::i;:::-;25946:1;25975:2;25967:6;25964:14;25992:1;25987:632;;;;26663:1;26680:6;26677:84;;;26736:9;26731:3;26727:19;26714:33;26705:42;;26677:84;26787:67;26847:6;26840:5;26787:67;:::i;:::-;26781:4;26774:81;26636:229;25957:908;;25987:632;26039:4;26035:9;26027:6;26023:22;26073:37;26105:4;26073:37;:::i;:::-;26132:1;26146:215;26160:7;26157:1;26154:14;26146:215;;;26246:9;26241:3;26237:19;26224:33;26216:6;26209:49;26297:1;26289:6;26285:14;26275:24;;26344:2;26333:9;26329:18;26316:31;;26183:4;26180:1;26176:12;26171:17;;26146:215;;;26389:6;26380:7;26377:19;26374:186;;;26454:9;26449:3;26445:19;26432:33;26497:48;26539:4;26531:6;26527:17;26516:9;26497:48;:::i;:::-;26489:6;26482:64;26397:163;26374:186;26606:1;26602;26594:6;26590:14;26586:22;26580:4;26573:36;25994:625;;;25957:908;;25567:1304;;;25468:1403;;;:::o;26877:178::-;27017:30;27013:1;27005:6;27001:14;26994:54;26877:178;:::o;27061:366::-;27203:3;27224:67;27288:2;27283:3;27224:67;:::i;:::-;27217:74;;27300:93;27389:3;27300:93;:::i;:::-;27418:2;27413:3;27409:12;27402:19;;27061:366;;;:::o;27433:419::-;27599:4;27637:2;27626:9;27622:18;27614:26;;27686:9;27680:4;27676:20;27672:1;27661:9;27657:17;27650:47;27714:131;27840:4;27714:131;:::i;:::-;27706:139;;27433:419;;;:::o;27858:165::-;27998:17;27994:1;27986:6;27982:14;27975:41;27858:165;:::o;28029:366::-;28171:3;28192:67;28256:2;28251:3;28192:67;:::i;:::-;28185:74;;28268:93;28357:3;28268:93;:::i;:::-;28386:2;28381:3;28377:12;28370:19;;28029:366;;;:::o;28401:419::-;28567:4;28605:2;28594:9;28590:18;28582:26;;28654:9;28648:4;28644:20;28640:1;28629:9;28625:17;28618:47;28682:131;28808:4;28682:131;:::i;:::-;28674:139;;28401:419;;;:::o;28826:174::-;28966:26;28962:1;28954:6;28950:14;28943:50;28826:174;:::o;29006:366::-;29148:3;29169:67;29233:2;29228:3;29169:67;:::i;:::-;29162:74;;29245:93;29334:3;29245:93;:::i;:::-;29363:2;29358:3;29354:12;29347:19;;29006:366;;;:::o;29378:419::-;29544:4;29582:2;29571:9;29567:18;29559:26;;29631:9;29625:4;29621:20;29617:1;29606:9;29602:17;29595:47;29659:131;29785:4;29659:131;:::i;:::-;29651:139;;29378:419;;;:::o;29803:191::-;29843:3;29862:20;29880:1;29862:20;:::i;:::-;29857:25;;29896:20;29914:1;29896:20;:::i;:::-;29891:25;;29939:1;29936;29932:9;29925:16;;29960:3;29957:1;29954:10;29951:36;;;29967:18;;:::i;:::-;29951:36;29803:191;;;;:::o;30000:178::-;30140:30;30136:1;30128:6;30124:14;30117:54;30000:178;:::o;30184:366::-;30326:3;30347:67;30411:2;30406:3;30347:67;:::i;:::-;30340:74;;30423:93;30512:3;30423:93;:::i;:::-;30541:2;30536:3;30532:12;30525:19;;30184:366;;;:::o;30556:419::-;30722:4;30760:2;30749:9;30745:18;30737:26;;30809:9;30803:4;30799:20;30795:1;30784:9;30780:17;30773:47;30837:131;30963:4;30837:131;:::i;:::-;30829:139;;30556:419;;;:::o;30981:194::-;31021:4;31041:20;31059:1;31041:20;:::i;:::-;31036:25;;31075:20;31093:1;31075:20;:::i;:::-;31070:25;;31119:1;31116;31112:9;31104:17;;31143:1;31137:4;31134:11;31131:37;;;31148:18;;:::i;:::-;31131:37;30981:194;;;;:::o;31181:410::-;31221:7;31244:20;31262:1;31244:20;:::i;:::-;31239:25;;31278:20;31296:1;31278:20;:::i;:::-;31273:25;;31333:1;31330;31326:9;31355:30;31373:11;31355:30;:::i;:::-;31344:41;;31534:1;31525:7;31521:15;31518:1;31515:22;31495:1;31488:9;31468:83;31445:139;;31564:18;;:::i;:::-;31445:139;31229:362;31181:410;;;;:::o;31597:167::-;31737:19;31733:1;31725:6;31721:14;31714:43;31597:167;:::o;31770:366::-;31912:3;31933:67;31997:2;31992:3;31933:67;:::i;:::-;31926:74;;32009:93;32098:3;32009:93;:::i;:::-;32127:2;32122:3;32118:12;32111:19;;31770:366;;;:::o;32142:419::-;32308:4;32346:2;32335:9;32331:18;32323:26;;32395:9;32389:4;32385:20;32381:1;32370:9;32366:17;32359:47;32423:131;32549:4;32423:131;:::i;:::-;32415:139;;32142:419;;;:::o;32567:148::-;32669:11;32706:3;32691:18;;32567:148;;;;:::o;32721:390::-;32827:3;32855:39;32888:5;32855:39;:::i;:::-;32910:89;32992:6;32987:3;32910:89;:::i;:::-;32903:96;;33008:65;33066:6;33061:3;33054:4;33047:5;33043:16;33008:65;:::i;:::-;33098:6;33093:3;33089:16;33082:23;;32831:280;32721:390;;;;:::o;33117:435::-;33297:3;33319:95;33410:3;33401:6;33319:95;:::i;:::-;33312:102;;33431:95;33522:3;33513:6;33431:95;:::i;:::-;33424:102;;33543:3;33536:10;;33117:435;;;;;:::o;33558:94::-;33591:8;33639:5;33635:2;33631:14;33610:35;;33558:94;;;:::o;33658:::-;33697:7;33726:20;33740:5;33726:20;:::i;:::-;33715:31;;33658:94;;;:::o;33758:100::-;33797:7;33826:26;33846:5;33826:26;:::i;:::-;33815:37;;33758:100;;;:::o;33864:157::-;33969:45;33989:24;34007:5;33989:24;:::i;:::-;33969:45;:::i;:::-;33964:3;33957:58;33864:157;;:::o;34027:256::-;34139:3;34154:75;34225:3;34216:6;34154:75;:::i;:::-;34254:2;34249:3;34245:12;34238:19;;34274:3;34267:10;;34027:256;;;;:::o;34289:225::-;34429:34;34425:1;34417:6;34413:14;34406:58;34498:8;34493:2;34485:6;34481:15;34474:33;34289:225;:::o;34520:366::-;34662:3;34683:67;34747:2;34742:3;34683:67;:::i;:::-;34676:74;;34759:93;34848:3;34759:93;:::i;:::-;34877:2;34872:3;34868:12;34861:19;;34520:366;;;:::o;34892:419::-;35058:4;35096:2;35085:9;35081:18;35073:26;;35145:9;35139:4;35135:20;35131:1;35120:9;35116:17;35109:47;35173:131;35299:4;35173:131;:::i;:::-;35165:139;;34892:419;;;:::o;35317:182::-;35457:34;35453:1;35445:6;35441:14;35434:58;35317:182;:::o;35505:366::-;35647:3;35668:67;35732:2;35727:3;35668:67;:::i;:::-;35661:74;;35744:93;35833:3;35744:93;:::i;:::-;35862:2;35857:3;35853:12;35846:19;;35505:366;;;:::o;35877:419::-;36043:4;36081:2;36070:9;36066:18;36058:26;;36130:9;36124:4;36120:20;36116:1;36105:9;36101:17;36094:47;36158:131;36284:4;36158:131;:::i;:::-;36150:139;;35877:419;;;:::o;36302:171::-;36341:3;36364:24;36382:5;36364:24;:::i;:::-;36355:33;;36410:4;36403:5;36400:15;36397:41;;36418:18;;:::i;:::-;36397:41;36465:1;36458:5;36454:13;36447:20;;36302:171;;;:::o;36479:98::-;36530:6;36564:5;36558:12;36548:22;;36479:98;;;:::o;36583:168::-;36666:11;36700:6;36695:3;36688:19;36740:4;36735:3;36731:14;36716:29;;36583:168;;;;:::o;36757:373::-;36843:3;36871:38;36903:5;36871:38;:::i;:::-;36925:70;36988:6;36983:3;36925:70;:::i;:::-;36918:77;;37004:65;37062:6;37057:3;37050:4;37043:5;37039:16;37004:65;:::i;:::-;37094:29;37116:6;37094:29;:::i;:::-;37089:3;37085:39;37078:46;;36847:283;36757:373;;;;:::o;37136:640::-;37331:4;37369:3;37358:9;37354:19;37346:27;;37383:71;37451:1;37440:9;37436:17;37427:6;37383:71;:::i;:::-;37464:72;37532:2;37521:9;37517:18;37508:6;37464:72;:::i;:::-;37546;37614:2;37603:9;37599:18;37590:6;37546:72;:::i;:::-;37665:9;37659:4;37655:20;37650:2;37639:9;37635:18;37628:48;37693:76;37764:4;37755:6;37693:76;:::i;:::-;37685:84;;37136:640;;;;;;;:::o;37782:141::-;37838:5;37869:6;37863:13;37854:22;;37885:32;37911:5;37885:32;:::i;:::-;37782:141;;;;:::o;37929:349::-;37998:6;38047:2;38035:9;38026:7;38022:23;38018:32;38015:119;;;38053:79;;:::i;:::-;38015:119;38173:1;38198:63;38253:7;38244:6;38233:9;38229:22;38198:63;:::i;:::-;38188:73;;38144:127;37929:349;;;;:::o
Swarm Source
ipfs://50efdeb9f18d283c584034d25ae65a96eb26f2f11a550e955d70bdbcebaf3649
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.