Overview
TokenID
6
Total Transfers
-
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract
Loading...
Loading
Loading...
Loading
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
ApesOnApe
Compiler Version
v0.8.26+commit.8a97fa7a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity >=0.8.20; import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "erc721a/contracts/ERC721A.sol"; contract ApesOnApe is ERC721A, Ownable(msg.sender), ReentrancyGuard { string public _twitter = ""; bool public isOpen = false; uint256 public price = 3 ether; string public baseURI; mapping (address => uint256) public wallet; uint256 public maxPerTransaction = 100; uint256 public maxPerWallet = 100; uint256 public maxSupply = 10000; constructor() ERC721A("ApesOnApe", "AOA"){} function _startTokenId() internal view virtual override returns (uint256) { return 1; } function mint(uint256 qty) external payable { require(isOpen , "Minting are closed !"); require(qty <= maxPerTransaction, "Limit Transaction !"); require(wallet[msg.sender] <= maxPerTransaction, "Limit Wallet !"); require(totalSupply() + qty <= maxSupply,"Soldout !"); require(msg.value >= qty * price,"Insufficient Funds !"); wallet[msg.sender] += qty; _safeMint(msg.sender, qty); } function _baseURI() internal view virtual override returns (string memory) { return baseURI; } function airdrop(address[] memory listedAirdrop ,uint256[] memory qty) external onlyOwner { for (uint256 i = 0; i < listedAirdrop.length; i++) { _safeMint(listedAirdrop[i], qty[i]); } } function ownerMint(uint256 qty) external onlyOwner { _safeMint(msg.sender, qty); } function setSocial(string memory _newTwitter) external onlyOwner { _twitter = _newTwitter; } function setOpen() external onlyOwner { isOpen = !isOpen ; } function setBaseURI(string memory baseURI_) external onlyOwner { baseURI = baseURI_; } function setPrice(uint256 price_) external onlyOwner { price = price_; } function setmaxPerTransaction(uint256 maxPerTransaction_) external onlyOwner { maxPerTransaction = maxPerTransaction_; } function setmaxPerWallet(uint256 maxPerWallet_) external onlyOwner { maxPerWallet = maxPerWallet_; } function withdraw() public onlyOwner { payable(msg.sender).transfer(payable(address(this)).balance); } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.3.0 // 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()`. * * The `_sequentialUpTo()` function can be overriden to enable spot mints * (i.e. non-consecutive mints) for `tokenId`s greater than `_sequentialUpTo()`. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364). struct TokenApprovalRef { address value; } // ============================================================= // CONSTANTS // ============================================================= // Mask of an entry in packed address data. uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant _BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant _BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant _BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant _BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant _BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant _BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225; // The bit position of `extraData` in packed ownership. uint256 private constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with {_mintERC2309}. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309} // is required to cause an overflow, which is unrealistic. uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // ============================================================= // STORAGE // ============================================================= // The next token ID to be minted. uint256 private _currentIndex; // The number of tokens burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See {_packedOwnershipOf} implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => TokenApprovalRef) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // The amount of tokens minted above `_sequentialUpTo()`. // We call these spot mints (i.e. non-sequential mints). uint256 private _spotMinted; // ============================================================= // CONSTRUCTOR // ============================================================= constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); if (_sequentialUpTo() < _startTokenId()) _revert(SequentialUpToTooSmall.selector); } // ============================================================= // TOKEN COUNTING OPERATIONS // ============================================================= /** * @dev Returns the starting token ID for sequential mints. * * Override this function to change the starting token ID for sequential mints. * * Note: The value returned must never change after any tokens have been minted. */ function _startTokenId() internal view virtual returns (uint256) { return 0; } /** * @dev Returns the maximum token ID (inclusive) for sequential mints. * * Override this function to return a value less than 2**256 - 1, * but greater than `_startTokenId()`, to enable spot (non-sequential) mints. * * Note: The value returned must never change after any tokens have been minted. */ function _sequentialUpTo() internal view virtual returns (uint256) { return type(uint256).max; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view virtual returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() public view virtual override returns (uint256 result) { // Counter underflow is impossible as `_burnCounter` cannot be incremented // more than `_currentIndex + _spotMinted - _startTokenId()` times. unchecked { // With spot minting, the intermediate `result` can be temporarily negative, // and the computation must be unchecked. result = _currentIndex - _burnCounter - _startTokenId(); if (_sequentialUpTo() != type(uint256).max) result += _spotMinted; } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view virtual returns (uint256 result) { // Counter underflow is impossible as `_currentIndex` does not decrement, // and it is initialized to `_startTokenId()`. unchecked { result = _currentIndex - _startTokenId(); if (_sequentialUpTo() != type(uint256).max) result += _spotMinted; } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return _burnCounter; } /** * @dev Returns the total number of tokens that are spot-minted. */ function _totalSpotMinted() internal view virtual returns (uint256) { return _spotMinted; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(0)) _revert(BalanceQueryForZeroAddress.selector); return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes // of the XOR of all function selectors in the interface. // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165) // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`) return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) _revert(URIQueryForNonexistentToken.selector); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ''; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Returns whether the ownership slot at `index` is initialized. * An uninitialized slot does not necessarily mean that the slot has no owner. */ function _ownershipIsInitialized(uint256 index) internal view virtual returns (bool) { return _packedOwnerships[index] != 0; } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * @dev Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256 packed) { if (_startTokenId() <= tokenId) { packed = _packedOwnerships[tokenId]; if (tokenId > _sequentialUpTo()) { if (_packedOwnershipExists(packed)) return packed; _revert(OwnerQueryForNonexistentToken.selector); } // If the data at the starting slot does not exist, start the scan. if (packed == 0) { if (tokenId >= _currentIndex) _revert(OwnerQueryForNonexistentToken.selector); // Invariant: // There will always be an initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `tokenId` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. for (;;) { unchecked { packed = _packedOwnerships[--tokenId]; } if (packed == 0) continue; if (packed & _BITMASK_BURNED == 0) return packed; // Otherwise, the token is burned, and we must revert. // This handles the case of batch burned tokens, where only the burned bit // of the starting slot is set, and remaining slots are left uninitialized. _revert(OwnerQueryForNonexistentToken.selector); } } // Otherwise, the data exists and we can skip the scan. // This is possible because we have already achieved the target condition. // This saves 2143 gas on transfers of initialized tokens. // If the token is not burned, return `packed`. Otherwise, revert. if (packed & _BITMASK_BURNED == 0) return packed; } _revert(OwnerQueryForNonexistentToken.selector); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags)) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. See {ERC721A-_approve}. * * Requirements: * * - The caller must own the token or be an approved operator. */ function approve(address to, uint256 tokenId) public payable virtual override { _approve(to, tokenId, true); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) _revert(ApprovalQueryForNonexistentToken.selector); return _tokenApprovals[tokenId].value; } /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) public virtual override { _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool result) { if (_startTokenId() <= tokenId) { if (tokenId > _sequentialUpTo()) return _packedOwnershipExists(_packedOwnerships[tokenId]); if (tokenId < _currentIndex) { uint256 packed; while ((packed = _packedOwnerships[tokenId]) == 0) --tokenId; result = packed & _BITMASK_BURNED == 0; } } } /** * @dev Returns whether `packed` represents a token that exists. */ function _packedOwnershipExists(uint256 packed) private pure returns (bool result) { assembly { // The following is equivalent to `owner != address(0) && burned == false`. // Symbolically tested. result := gt(and(packed, _BITMASK_ADDRESS), and(packed, _BITMASK_BURNED)) } } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`. assembly { approvedAddressSlot := tokenApproval.slot approvedAddress := sload(approvedAddressSlot) } } // ============================================================= // TRANSFER OPERATIONS // ============================================================= /** * @dev Transfers `tokenId` from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) public payable virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); // Mask `from` to the lower 160 bits, in case the upper bits somehow aren't clean. from = address(uint160(uint256(uint160(from)) & _BITMASK_ADDRESS)); if (address(uint160(prevOwnershipPacked)) != from) _revert(TransferFromIncorrectOwner.selector); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) _revert(TransferCallerNotOwnerNorApproved.selector); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS; assembly { // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. from, // `from`. toMasked, // `to`. tokenId // `tokenId`. ) } if (toMasked == 0) _revert(TransferToZeroAddress.selector); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public payable virtual override { safeTransferFrom(from, to, tokenId, ''); } /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public payable virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { _revert(TransferToNonERC721ReceiverImplementer.selector); } } /** * @dev Hook that is called before a set of serially-ordered token IDs * are about to be transferred. This includes minting. * And also called before burning one token. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token IDs * have been transferred. This includes minting. * And also called after one token has been burned. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns whether the call correctly returned the expected magic value. */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns ( bytes4 retval ) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { _revert(TransferToNonERC721ReceiverImplementer.selector); } assembly { revert(add(32, reason), mload(reason)) } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (quantity == 0) _revert(MintZeroQuantity.selector); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS; if (toMasked == 0) _revert(MintToZeroAddress.selector); uint256 end = startTokenId + quantity; uint256 tokenId = startTokenId; if (end - 1 > _sequentialUpTo()) _revert(SequentialMintExceedsLimit.selector); do { assembly { // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. tokenId // `tokenId`. ) } // The `!=` check ensures that large values of `quantity` // that overflows uint256 will make the loop run out of gas. } while (++tokenId != end); _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (to == address(0)) _revert(MintToZeroAddress.selector); if (quantity == 0) _revert(MintZeroQuantity.selector); if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) _revert(MintERC2309QuantityExceedsLimit.selector); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); if (startTokenId + quantity - 1 > _sequentialUpTo()) _revert(SequentialMintExceedsLimit.selector); emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to); _currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = _currentIndex; uint256 index = end - quantity; do { if (!_checkContractOnERC721Received(address(0), to, index++, _data)) { _revert(TransferToNonERC721ReceiverImplementer.selector); } } while (index < end); // This prevents reentrancy to `_safeMint`. // It does not prevent reentrancy to `_safeMintSpot`. if (_currentIndex != end) revert(); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ''); } /** * @dev Mints a single token at `tokenId`. * * Note: A spot-minted `tokenId` that has been burned can be re-minted again. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` must be greater than `_sequentialUpTo()`. * - `tokenId` must not exist. * * Emits a {Transfer} event for each mint. */ function _mintSpot(address to, uint256 tokenId) internal virtual { if (tokenId <= _sequentialUpTo()) _revert(SpotMintTokenIdTooSmall.selector); uint256 prevOwnershipPacked = _packedOwnerships[tokenId]; if (_packedOwnershipExists(prevOwnershipPacked)) _revert(TokenAlreadyExists.selector); _beforeTokenTransfers(address(0), to, tokenId, 1); // Overflows are incredibly unrealistic. // The `numberMinted` for `to` is incremented by 1, and has a max limit of 2**64 - 1. // `_spotMinted` is incremented by 1, and has a max limit of 2**256 - 1. unchecked { // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `true` (as `quantity == 1`). _packedOwnerships[tokenId] = _packOwnershipData( to, _nextInitializedFlag(1) | _nextExtraData(address(0), to, prevOwnershipPacked) ); // Updates: // - `balance += 1`. // - `numberMinted += 1`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += (1 << _BITPOS_NUMBER_MINTED) | 1; // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS; if (toMasked == 0) _revert(MintToZeroAddress.selector); assembly { // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. tokenId // `tokenId`. ) } ++_spotMinted; } _afterTokenTransfers(address(0), to, tokenId, 1); } /** * @dev Safely mints a single token at `tokenId`. * * Note: A spot-minted `tokenId` that has been burned can be re-minted again. * * Requirements: * * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}. * - `tokenId` must be greater than `_sequentialUpTo()`. * - `tokenId` must not exist. * * See {_mintSpot}. * * Emits a {Transfer} event. */ function _safeMintSpot( address to, uint256 tokenId, bytes memory _data ) internal virtual { _mintSpot(to, tokenId); unchecked { if (to.code.length != 0) { uint256 currentSpotMinted = _spotMinted; if (!_checkContractOnERC721Received(address(0), to, tokenId, _data)) { _revert(TransferToNonERC721ReceiverImplementer.selector); } // This prevents reentrancy to `_safeMintSpot`. // It does not prevent reentrancy to `_safeMint`. if (_spotMinted != currentSpotMinted) revert(); } } } /** * @dev Equivalent to `_safeMintSpot(to, tokenId, '')`. */ function _safeMintSpot(address to, uint256 tokenId) internal virtual { _safeMintSpot(to, tokenId, ''); } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Equivalent to `_approve(to, tokenId, false)`. */ function _approve(address to, uint256 tokenId) internal virtual { _approve(to, tokenId, false); } /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - `tokenId` must exist. * * Emits an {Approval} event. */ function _approve( address to, uint256 tokenId, bool approvalCheck ) internal virtual { address owner = ownerOf(tokenId); if (approvalCheck && _msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { _revert(ApprovalCallerNotOwnerNorApproved.selector); } _tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) _revert(TransferCallerNotOwnerNorApproved.selector); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as `_burnCounter` cannot be exceed `_currentIndex + _spotMinted` times. unchecked { _burnCounter++; } } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) _revert(OwnershipNotInitializedForExtraData.selector); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } /** * @dev For more efficient reverts. */ function _revert(bytes4 errorSelector) internal pure { assembly { mstore(0x00, errorSelector) revert(0x00, 0x04) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/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. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/MerkleProof.sol) // This file was procedurally generated from scripts/generate/templates/MerkleProof.js. pragma solidity ^0.8.20; import {Hashes} from "./Hashes.sol"; /** * @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. * * IMPORTANT: Consider memory side-effects when using custom hashing functions * that access memory in an unsafe way. * * NOTE: This library supports proof verification for merkle trees built using * custom _commutative_ hashing functions (i.e. `H(a, b) == H(b, a)`). Proving * leaf inclusion in trees built using non-commutative hashing functions requires * additional logic that is not supported by this library. */ library MerkleProof { /** *@dev The multiproof provided is not valid. */ error MerkleProofInvalidMultiproof(); /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. * * This version handles proofs in memory with the default hashing function. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leaves & pre-images are assumed to be sorted. * * This version handles proofs in memory with the default hashing function. */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = Hashes.commutativeKeccak256(computedHash, proof[i]); } return computedHash; } /** * @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. * * This version handles proofs in memory with a custom hashing function. */ function verify( bytes32[] memory proof, bytes32 root, bytes32 leaf, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view returns (bool) { return processProof(proof, leaf, hasher) == 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 leaves & pre-images are assumed to be sorted. * * This version handles proofs in memory with a custom hashing function. */ function processProof( bytes32[] memory proof, bytes32 leaf, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = hasher(computedHash, proof[i]); } return computedHash; } /** * @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. * * This version handles proofs in calldata with the default hashing function. */ 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 leaves & pre-images are assumed to be sorted. * * This version handles proofs in calldata with the default hashing function. */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = Hashes.commutativeKeccak256(computedHash, proof[i]); } return computedHash; } /** * @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. * * This version handles proofs in calldata with a custom hashing function. */ function verifyCalldata( bytes32[] calldata proof, bytes32 root, bytes32 leaf, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view returns (bool) { return processProofCalldata(proof, leaf, hasher) == 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 leaves & pre-images are assumed to be sorted. * * This version handles proofs in calldata with a custom hashing function. */ function processProofCalldata( bytes32[] calldata proof, bytes32 leaf, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = hasher(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}. * * This version handles multiproofs in memory with the default hashing function. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. * * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`. * The `leaves` must be validated independently. See {processMultiProof}. */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(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. * * This version handles multiproofs in memory with the default hashing function. * * 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). * * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op, * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not * validating the leaves elsewhere. */ 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 proofFlagsLen = proofFlags.length; // Check proof validity. if (leavesLen + proof.length != proofFlagsLen + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](proofFlagsLen); 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 < proofFlagsLen; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = Hashes.commutativeKeccak256(a, b); } if (proofFlagsLen > 0) { if (proofPos != proof.length) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[proofFlagsLen - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @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}. * * This version handles multiproofs in memory with a custom hashing function. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. * * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`. * The `leaves` must be validated independently. See {processMultiProof}. */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view returns (bool) { return processMultiProof(proof, proofFlags, leaves, hasher) == 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. * * This version handles multiproofs in memory with a custom hashing function. * * 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). * * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op, * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not * validating the leaves elsewhere. */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view 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 proofFlagsLen = proofFlags.length; // Check proof validity. if (leavesLen + proof.length != proofFlagsLen + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](proofFlagsLen); 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 < proofFlagsLen; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = hasher(a, b); } if (proofFlagsLen > 0) { if (proofPos != proof.length) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[proofFlagsLen - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @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}. * * This version handles multiproofs in calldata with the default hashing function. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. * * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`. * The `leaves` must be validated independently. See {processMultiProofCalldata}. */ 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. * * This version handles multiproofs in calldata with the default hashing function. * * 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). * * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op, * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not * validating the leaves elsewhere. */ 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 proofFlagsLen = proofFlags.length; // Check proof validity. if (leavesLen + proof.length != proofFlagsLen + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](proofFlagsLen); 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 < proofFlagsLen; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = Hashes.commutativeKeccak256(a, b); } if (proofFlagsLen > 0) { if (proofPos != proof.length) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[proofFlagsLen - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @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}. * * This version handles multiproofs in calldata with a custom hashing function. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. * * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`. * The `leaves` must be validated independently. See {processMultiProofCalldata}. */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves, hasher) == 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. * * This version handles multiproofs in calldata with a custom hashing function. * * 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). * * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op, * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not * validating the leaves elsewhere. */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view 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 proofFlagsLen = proofFlags.length; // Check proof validity. if (leavesLen + proof.length != proofFlagsLen + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](proofFlagsLen); 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 < proofFlagsLen; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = hasher(a, b); } if (proofFlagsLen > 0) { if (proofPos != proof.length) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[proofFlagsLen - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.3.0 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); /** * `_sequentialUpTo()` must be greater than `_startTokenId()`. */ error SequentialUpToTooSmall(); /** * The `tokenId` of a sequential mint exceeds `_sequentialUpTo()`. */ error SequentialMintExceedsLimit(); /** * Spot minting requires a `tokenId` greater than `_sequentialUpTo()`. */ error SpotMintTokenIdTooSmall(); /** * Cannot mint over a token that already exists. */ error TokenAlreadyExists(); /** * The feature is not compatible with spot mints. */ error NotCompatibleWithSpotMints(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables * (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, * checking first that contract recipients are aware of the ERC721 protocol * to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move * this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external payable; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Transfers `tokenId` from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} * whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external payable; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) external view returns (bool); // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/Hashes.sol) pragma solidity ^0.8.20; /** * @dev Library of standard hash functions. * * _Available since v5.1._ */ library Hashes { /** * @dev Commutative Keccak256 hash of a sorted pair of bytes32. Frequently used when working with merkle proofs. * * NOTE: Equivalent to the `standardNodeHash` in our https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. */ function commutativeKeccak256(bytes32 a, bytes32 b) internal pure returns (bytes32) { return a < b ? _efficientKeccak256(a, b) : _efficientKeccak256(b, a); } /** * @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory. */ function _efficientKeccak256(bytes32 a, bytes32 b) private pure returns (bytes32 value) { assembly ("memory-safe") { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "remappings": [] }
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":"NotCompatibleWithSpotMints","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"SequentialMintExceedsLimit","type":"error"},{"inputs":[],"name":"SequentialUpToTooSmall","type":"error"},{"inputs":[],"name":"SpotMintTokenIdTooSmall","type":"error"},{"inputs":[],"name":"TokenAlreadyExists","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"_twitter","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"listedAirdrop","type":"address[]"},{"internalType":"uint256[]","name":"qty","type":"uint256[]"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"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":[],"name":"isOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPerTransaction","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"qty","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"qty","type":"uint256"}],"name":"ownerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"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":[],"name":"setOpen","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"price_","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newTwitter","type":"string"}],"name":"setSocial","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxPerTransaction_","type":"uint256"}],"name":"setmaxPerTransaction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxPerWallet_","type":"uint256"}],"name":"setmaxPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"wallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405260405180602001604052805f815250600b908161002191906104ff565b505f600c5f6101000a81548160ff0219169083151502179055506729a2241af62c0000600d5560646010556064601155612710601255348015610062575f80fd5b50336040518060400160405280600981526020017f417065734f6e41706500000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f414f41000000000000000000000000000000000000000000000000000000000081525081600290816100df91906104ff565b5080600390816100ef91906104ff565b506100fe6101cb60201b60201c565b5f819055506101116101cb60201b60201c565b61011f6101d360201b60201c565b101561013c5761013b63fed8210f60e01b6101fa60201b60201c565b5b50505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101ae575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016101a5919061060d565b60405180910390fd5b6101bd8161020260201b60201c565b506001600a81905550610626565b5f6001905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b805f5260045ffd5b5f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061034057607f821691505b602082108103610353576103526102fc565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026103b57fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261037a565b6103bf868361037a565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6104036103fe6103f9846103d7565b6103e0565b6103d7565b9050919050565b5f819050919050565b61041c836103e9565b6104306104288261040a565b848454610386565b825550505050565b5f90565b610444610438565b61044f818484610413565b505050565b5b81811015610472576104675f8261043c565b600181019050610455565b5050565b601f8211156104b75761048881610359565b6104918461036b565b810160208510156104a0578190505b6104b46104ac8561036b565b830182610454565b50505b505050565b5f82821c905092915050565b5f6104d75f19846008026104bc565b1980831691505092915050565b5f6104ef83836104c8565b9150826002028217905092915050565b610508826102c5565b67ffffffffffffffff811115610521576105206102cf565b5b61052b8254610329565b610536828285610476565b5f60209050601f831160018114610567575f8415610555578287015190505b61055f85826104e4565b8655506105c6565b601f19841661057586610359565b5f5b8281101561059c57848901518255600182019150602085019450602081019050610577565b868310156105b957848901516105b5601f8916826104c8565b8355505b6001600288020188555050505b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6105f7826105ce565b9050919050565b610607816105ed565b82525050565b5f6020820190506106205f8301846105fe565b92915050565b612e9e806106335f395ff3fe608060405260043610610203575f3560e01c80636c0360eb11610117578063a22cb4651161009f578063d5abeb011161006e578063d5abeb01146106cf578063daa6b00d146106f9578063e985e9c514610723578063f19e75d41461075f578063f2fde38b1461078757610203565b8063a22cb46514610613578063a56cc4391461063b578063b88d4fde14610677578063c87b56dd1461069357610203565b80638da5cb5b116100e65780638da5cb5b1461055157806391b7f5ed1461057b57806395d89b41146105a3578063a035b1fe146105cd578063a0712d68146105f757610203565b80636c0360eb146104bf57806370a08231146104e9578063712b7b1414610525578063715018a61461053b57610203565b80633f70eb8c1161019a5780634b980d67116101695780634b980d67146103e157806355f804b31461040b57806360d3e1ae146104335780636352211e1461045b578063672434821461049757610203565b80633f70eb8c1461034957806342842e0e14610371578063453c23101461038d57806347535d7b146103b757610203565b8063108bfbfa116101d6578063108bfbfa146102c557806318160ddd146102ed57806323b872dd146103175780633ccfd60b1461033357610203565b806301ffc9a71461020757806306fdde0314610243578063081812fc1461026d578063095ea7b3146102a9575b5f80fd5b348015610212575f80fd5b5061022d60048036038101906102289190611f8a565b6107af565b60405161023a9190611fcf565b60405180910390f35b34801561024e575f80fd5b50610257610840565b6040516102649190612058565b60405180910390f35b348015610278575f80fd5b50610293600480360381019061028e91906120ab565b6108d0565b6040516102a09190612115565b60405180910390f35b6102c360048036038101906102be9190612158565b610929565b005b3480156102d0575f80fd5b506102eb60048036038101906102e691906120ab565b610939565b005b3480156102f8575f80fd5b5061030161094b565b60405161030e91906121a5565b60405180910390f35b610331600480360381019061032c91906121be565b610996565b005b34801561033e575f80fd5b50610347610c41565b005b348015610354575f80fd5b5061036f600480360381019061036a919061233a565b610ca6565b005b61038b600480360381019061038691906121be565b610cc1565b005b348015610398575f80fd5b506103a1610ce0565b6040516103ae91906121a5565b60405180910390f35b3480156103c2575f80fd5b506103cb610ce6565b6040516103d89190611fcf565b60405180910390f35b3480156103ec575f80fd5b506103f5610cf8565b60405161040291906121a5565b60405180910390f35b348015610416575f80fd5b50610431600480360381019061042c919061233a565b610cfe565b005b34801561043e575f80fd5b50610459600480360381019061045491906120ab565b610d19565b005b348015610466575f80fd5b50610481600480360381019061047c91906120ab565b610d2b565b60405161048e9190612115565b60405180910390f35b3480156104a2575f80fd5b506104bd60048036038101906104b89190612505565b610d3c565b005b3480156104ca575f80fd5b506104d3610d9f565b6040516104e09190612058565b60405180910390f35b3480156104f4575f80fd5b5061050f600480360381019061050a919061257b565b610e2b565b60405161051c91906121a5565b60405180910390f35b348015610530575f80fd5b50610539610ebf565b005b348015610546575f80fd5b5061054f610ef1565b005b34801561055c575f80fd5b50610565610f04565b6040516105729190612115565b60405180910390f35b348015610586575f80fd5b506105a1600480360381019061059c91906120ab565b610f2c565b005b3480156105ae575f80fd5b506105b7610f3e565b6040516105c49190612058565b60405180910390f35b3480156105d8575f80fd5b506105e1610fce565b6040516105ee91906121a5565b60405180910390f35b610611600480360381019061060c91906120ab565b610fd4565b005b34801561061e575f80fd5b50610639600480360381019061063491906125d0565b6111f0565b005b348015610646575f80fd5b50610661600480360381019061065c919061257b565b6112f6565b60405161066e91906121a5565b60405180910390f35b610691600480360381019061068c91906126ac565b61130b565b005b34801561069e575f80fd5b506106b960048036038101906106b491906120ab565b61135c565b6040516106c69190612058565b60405180910390f35b3480156106da575f80fd5b506106e36113d6565b6040516106f091906121a5565b60405180910390f35b348015610704575f80fd5b5061070d6113dc565b60405161071a9190612058565b60405180910390f35b34801561072e575f80fd5b506107496004803603810190610744919061272c565b611468565b6040516107569190611fcf565b60405180910390f35b34801561076a575f80fd5b50610785600480360381019061078091906120ab565b6114f6565b005b348015610792575f80fd5b506107ad60048036038101906107a8919061257b565b61150b565b005b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061080957506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108395750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461084f90612797565b80601f016020809104026020016040519081016040528092919081815260200182805461087b90612797565b80156108c65780601f1061089d576101008083540402835291602001916108c6565b820191905f5260205f20905b8154815290600101906020018083116108a957829003601f168201915b5050505050905090565b5f6108da8261158f565b6108ef576108ee63cf4700e460e01b611632565b5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6109358282600161163a565b5050565b610941611764565b8060108190555050565b5f6109546117eb565b6001545f54030390507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6109866117f3565b1461099357600854810190505b90565b5f6109a08261181a565b905073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161693508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a1557610a1463a114810060e01b611632565b5b5f80610a2084611929565b91509150610a368187610a3161194c565b611953565b610a6157610a4b86610a4661194c565b611468565b610a6057610a5f6359c896be60e01b611632565b5b5b610a6e8686866001611996565b8015610a78575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f815460010191905081905550610b4085610b1c88888761199c565b7c0200000000000000000000000000000000000000000000000000000000176119c3565b60045f8681526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000841603610bbc575f6001850190505f60045f8381526020019081526020015f205403610bba575f548114610bb9578360045f8381526020019081526020015f20819055505b5b505b5f73ffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff161690508481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a45f8103610c2b57610c2a63ea553b3460e01b611632565b5b610c3887878760016119ed565b50505050505050565b610c49611764565b3373ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff163190811502906040515f60405180830381858888f19350505050158015610ca3573d5f803e3d5ffd5b50565b610cae611764565b80600b9081610cbd9190612964565b5050565b610cdb83838360405180602001604052805f81525061130b565b505050565b60115481565b600c5f9054906101000a900460ff1681565b60105481565b610d06611764565b80600e9081610d159190612964565b5050565b610d21611764565b8060118190555050565b5f610d358261181a565b9050919050565b610d44611764565b5f5b8251811015610d9a57610d8d838281518110610d6557610d64612a33565b5b6020026020010151838381518110610d8057610d7f612a33565b5b60200260200101516119f3565b8080600101915050610d46565b505050565b600e8054610dac90612797565b80601f0160208091040260200160405190810160405280929190818152602001828054610dd890612797565b8015610e235780601f10610dfa57610100808354040283529160200191610e23565b820191905f5260205f20905b815481529060010190602001808311610e0657829003601f168201915b505050505081565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610e7057610e6f638f4eb60460e01b611632565b5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b610ec7611764565b600c5f9054906101000a900460ff1615600c5f6101000a81548160ff021916908315150217905550565b610ef9611764565b610f025f611a10565b565b5f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610f34611764565b80600d8190555050565b606060038054610f4d90612797565b80601f0160208091040260200160405190810160405280929190818152602001828054610f7990612797565b8015610fc45780601f10610f9b57610100808354040283529160200191610fc4565b820191905f5260205f20905b815481529060010190602001808311610fa757829003601f168201915b5050505050905090565b600d5481565b600c5f9054906101000a900460ff16611022576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101990612aaa565b60405180910390fd5b601054811115611067576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105e90612b12565b60405180910390fd5b601054600f5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205411156110e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e090612b7a565b60405180910390fd5b601254816110f561094b565b6110ff9190612bc5565b1115611140576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113790612c42565b60405180910390fd5b600d548161114e9190612c60565b341015611190576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118790612ceb565b60405180910390fd5b80600f5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546111dc9190612bc5565b925050819055506111ed33826119f3565b50565b8060075f6111fc61194c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166112a561194c565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516112ea9190611fcf565b60405180910390a35050565b600f602052805f5260405f205f915090505481565b611316848484610996565b5f8373ffffffffffffffffffffffffffffffffffffffff163b146113565761134084848484611ad3565b6113555761135463d1a57ed660e01b611632565b5b5b50505050565b60606113678261158f565b61137c5761137b63a14c4b5060e01b611632565b5b5f611385611bfd565b90505f8151036113a35760405180602001604052805f8152506113ce565b806113ad84611c8d565b6040516020016113be929190612d43565b6040516020818303038152906040525b915050919050565b60125481565b600b80546113e990612797565b80601f016020809104026020016040519081016040528092919081815260200182805461141590612797565b80156114605780601f1061143757610100808354040283529160200191611460565b820191905f5260205f20905b81548152906001019060200180831161144357829003601f168201915b505050505081565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b6114fe611764565b61150833826119f3565b50565b611513611764565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611583575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161157a9190612115565b60405180910390fd5b61158c81611a10565b50565b5f816115996117eb565b1161162c576115a66117f3565b8211156115ce576115c760045f8481526020019081526020015f2054611cdc565b905061162d565b5f5482101561162b575f5b5f60045f8581526020019081526020015f20549150810361160557826115fe90612d66565b92506115d9565b5f7c01000000000000000000000000000000000000000000000000000000008216149150505b5b5b919050565b805f5260045ffd5b5f61164483610d2b565b905081801561168657508073ffffffffffffffffffffffffffffffffffffffff1661166d61194c565b73ffffffffffffffffffffffffffffffffffffffff1614155b156116b25761169c8161169761194c565b611468565b6116b1576116b063cfb3b94260e01b611632565b5b5b8360065f8581526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b61176c611d1c565b73ffffffffffffffffffffffffffffffffffffffff1661178a610f04565b73ffffffffffffffffffffffffffffffffffffffff16146117e9576117ad611d1c565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016117e09190612115565b60405180910390fd5b565b5f6001905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b5f816118246117eb565b116119135760045f8381526020019081526020015f205490506118456117f3565b82111561186a5761185581611cdc565b6119245761186963df2d9b4260e01b611632565b5b5f81036118eb575f54821061188a5761188963df2d9b4260e01b611632565b5b5b60045f836001900393508381526020019081526020015f205490505f8103156118e6575f7c010000000000000000000000000000000000000000000000000000000082160315611924576118e563df2d9b4260e01b611632565b5b61188b565b5f7c010000000000000000000000000000000000000000000000000000000082160315611924575b61192363df2d9b4260e01b611632565b5b919050565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b5f8060e883901c905060e86119b2868684611d23565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b611a0c828260405180602001604052805f815250611d2b565b5050565b5f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611af861194c565b8786866040518563ffffffff1660e01b8152600401611b1a9493929190612ddf565b6020604051808303815f875af1925050508015611b5557506040513d601f19601f82011682018060405250810190611b529190612e3d565b60015b611baa573d805f8114611b83576040519150601f19603f3d011682016040523d82523d5f602084013e611b88565b606091505b505f815103611ba257611ba163d1a57ed660e01b611632565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600e8054611c0c90612797565b80601f0160208091040260200160405190810160405280929190818152602001828054611c3890612797565b8015611c835780601f10611c5a57610100808354040283529160200191611c83565b820191905f5260205f20905b815481529060010190602001808311611c6657829003601f168201915b5050505050905090565b606060a060405101806040526020810391505f825281835b600115611cc757600184039350600a81066030018453600a8104905080611ca5575b50828103602084039350808452505050919050565b5f7c0100000000000000000000000000000000000000000000000000000000821673ffffffffffffffffffffffffffffffffffffffff8316119050919050565b5f33905090565b5f9392505050565b611d358383611da1565b5f8373ffffffffffffffffffffffffffffffffffffffff163b14611d9c575f805490505f83820390505b611d715f868380600101945086611ad3565b611d8657611d8563d1a57ed660e01b611632565b5b818110611d5f57815f5414611d99575f80fd5b50505b505050565b5f805490505f8203611dbe57611dbd63b562e8dd60e01b611632565b5b611dca5f848385611996565b611de883611dd95f865f61199c565b611de285611f15565b176119c3565b60045f8381526020019081526020015f2081905550600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505f73ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161690505f8103611e9957611e98632e07630060e01b611632565b5b5f83830190505f839050611eab6117f3565b600183031115611ec657611ec56381647e3a60e01b611632565b5b5b80835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4818160010191508103611ec757815f81905550505050611f105f8483856119ed565b505050565b5f6001821460e11b9050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611f6981611f35565b8114611f73575f80fd5b50565b5f81359050611f8481611f60565b92915050565b5f60208284031215611f9f57611f9e611f2d565b5b5f611fac84828501611f76565b91505092915050565b5f8115159050919050565b611fc981611fb5565b82525050565b5f602082019050611fe25f830184611fc0565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61202a82611fe8565b6120348185611ff2565b9350612044818560208601612002565b61204d81612010565b840191505092915050565b5f6020820190508181035f8301526120708184612020565b905092915050565b5f819050919050565b61208a81612078565b8114612094575f80fd5b50565b5f813590506120a581612081565b92915050565b5f602082840312156120c0576120bf611f2d565b5b5f6120cd84828501612097565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6120ff826120d6565b9050919050565b61210f816120f5565b82525050565b5f6020820190506121285f830184612106565b92915050565b612137816120f5565b8114612141575f80fd5b50565b5f813590506121528161212e565b92915050565b5f806040838503121561216e5761216d611f2d565b5b5f61217b85828601612144565b925050602061218c85828601612097565b9150509250929050565b61219f81612078565b82525050565b5f6020820190506121b85f830184612196565b92915050565b5f805f606084860312156121d5576121d4611f2d565b5b5f6121e286828701612144565b93505060206121f386828701612144565b925050604061220486828701612097565b9150509250925092565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61224c82612010565b810181811067ffffffffffffffff8211171561226b5761226a612216565b5b80604052505050565b5f61227d611f24565b90506122898282612243565b919050565b5f67ffffffffffffffff8211156122a8576122a7612216565b5b6122b182612010565b9050602081019050919050565b828183375f83830152505050565b5f6122de6122d98461228e565b612274565b9050828152602081018484840111156122fa576122f9612212565b5b6123058482856122be565b509392505050565b5f82601f8301126123215761232061220e565b5b81356123318482602086016122cc565b91505092915050565b5f6020828403121561234f5761234e611f2d565b5b5f82013567ffffffffffffffff81111561236c5761236b611f31565b5b6123788482850161230d565b91505092915050565b5f67ffffffffffffffff82111561239b5761239a612216565b5b602082029050602081019050919050565b5f80fd5b5f6123c26123bd84612381565b612274565b905080838252602082019050602084028301858111156123e5576123e46123ac565b5b835b8181101561240e57806123fa8882612144565b8452602084019350506020810190506123e7565b5050509392505050565b5f82601f83011261242c5761242b61220e565b5b813561243c8482602086016123b0565b91505092915050565b5f67ffffffffffffffff82111561245f5761245e612216565b5b602082029050602081019050919050565b5f61248261247d84612445565b612274565b905080838252602082019050602084028301858111156124a5576124a46123ac565b5b835b818110156124ce57806124ba8882612097565b8452602084019350506020810190506124a7565b5050509392505050565b5f82601f8301126124ec576124eb61220e565b5b81356124fc848260208601612470565b91505092915050565b5f806040838503121561251b5761251a611f2d565b5b5f83013567ffffffffffffffff81111561253857612537611f31565b5b61254485828601612418565b925050602083013567ffffffffffffffff81111561256557612564611f31565b5b612571858286016124d8565b9150509250929050565b5f602082840312156125905761258f611f2d565b5b5f61259d84828501612144565b91505092915050565b6125af81611fb5565b81146125b9575f80fd5b50565b5f813590506125ca816125a6565b92915050565b5f80604083850312156125e6576125e5611f2d565b5b5f6125f385828601612144565b9250506020612604858286016125bc565b9150509250929050565b5f67ffffffffffffffff82111561262857612627612216565b5b61263182612010565b9050602081019050919050565b5f61265061264b8461260e565b612274565b90508281526020810184848401111561266c5761266b612212565b5b6126778482856122be565b509392505050565b5f82601f8301126126935761269261220e565b5b81356126a384826020860161263e565b91505092915050565b5f805f80608085870312156126c4576126c3611f2d565b5b5f6126d187828801612144565b94505060206126e287828801612144565b93505060406126f387828801612097565b925050606085013567ffffffffffffffff81111561271457612713611f31565b5b6127208782880161267f565b91505092959194509250565b5f806040838503121561274257612741611f2d565b5b5f61274f85828601612144565b925050602061276085828601612144565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806127ae57607f821691505b6020821081036127c1576127c061276a565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026128237fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826127e8565b61282d86836127e8565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61286861286361285e84612078565b612845565b612078565b9050919050565b5f819050919050565b6128818361284e565b61289561288d8261286f565b8484546127f4565b825550505050565b5f90565b6128a961289d565b6128b4818484612878565b505050565b5b818110156128d7576128cc5f826128a1565b6001810190506128ba565b5050565b601f82111561291c576128ed816127c7565b6128f6846127d9565b81016020851015612905578190505b612919612911856127d9565b8301826128b9565b50505b505050565b5f82821c905092915050565b5f61293c5f1984600802612921565b1980831691505092915050565b5f612954838361292d565b9150826002028217905092915050565b61296d82611fe8565b67ffffffffffffffff81111561298657612985612216565b5b6129908254612797565b61299b8282856128db565b5f60209050601f8311600181146129cc575f84156129ba578287015190505b6129c48582612949565b865550612a2b565b601f1984166129da866127c7565b5f5b82811015612a01578489015182556001820191506020850194506020810190506129dc565b86831015612a1e5784890151612a1a601f89168261292d565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4d696e74696e672061726520636c6f73656420210000000000000000000000005f82015250565b5f612a94601483611ff2565b9150612a9f82612a60565b602082019050919050565b5f6020820190508181035f830152612ac181612a88565b9050919050565b7f4c696d6974205472616e73616374696f6e2021000000000000000000000000005f82015250565b5f612afc601383611ff2565b9150612b0782612ac8565b602082019050919050565b5f6020820190508181035f830152612b2981612af0565b9050919050565b7f4c696d69742057616c6c657420210000000000000000000000000000000000005f82015250565b5f612b64600e83611ff2565b9150612b6f82612b30565b602082019050919050565b5f6020820190508181035f830152612b9181612b58565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612bcf82612078565b9150612bda83612078565b9250828201905080821115612bf257612bf1612b98565b5b92915050565b7f536f6c646f7574202100000000000000000000000000000000000000000000005f82015250565b5f612c2c600983611ff2565b9150612c3782612bf8565b602082019050919050565b5f6020820190508181035f830152612c5981612c20565b9050919050565b5f612c6a82612078565b9150612c7583612078565b9250828202612c8381612078565b91508282048414831517612c9a57612c99612b98565b5b5092915050565b7f496e73756666696369656e742046756e647320210000000000000000000000005f82015250565b5f612cd5601483611ff2565b9150612ce082612ca1565b602082019050919050565b5f6020820190508181035f830152612d0281612cc9565b9050919050565b5f81905092915050565b5f612d1d82611fe8565b612d278185612d09565b9350612d37818560208601612002565b80840191505092915050565b5f612d4e8285612d13565b9150612d5a8284612d13565b91508190509392505050565b5f612d7082612078565b91505f8203612d8257612d81612b98565b5b600182039050919050565b5f81519050919050565b5f82825260208201905092915050565b5f612db182612d8d565b612dbb8185612d97565b9350612dcb818560208601612002565b612dd481612010565b840191505092915050565b5f608082019050612df25f830187612106565b612dff6020830186612106565b612e0c6040830185612196565b8181036060830152612e1e8184612da7565b905095945050505050565b5f81519050612e3781611f60565b92915050565b5f60208284031215612e5257612e51611f2d565b5b5f612e5f84828501612e29565b9150509291505056fea26469706673582212208bc1cdc65f0a74995ac1a88d286fdf5408e5b979e9b13595040940d2b58b0e7664736f6c634300081a0033
Deployed Bytecode
0x608060405260043610610203575f3560e01c80636c0360eb11610117578063a22cb4651161009f578063d5abeb011161006e578063d5abeb01146106cf578063daa6b00d146106f9578063e985e9c514610723578063f19e75d41461075f578063f2fde38b1461078757610203565b8063a22cb46514610613578063a56cc4391461063b578063b88d4fde14610677578063c87b56dd1461069357610203565b80638da5cb5b116100e65780638da5cb5b1461055157806391b7f5ed1461057b57806395d89b41146105a3578063a035b1fe146105cd578063a0712d68146105f757610203565b80636c0360eb146104bf57806370a08231146104e9578063712b7b1414610525578063715018a61461053b57610203565b80633f70eb8c1161019a5780634b980d67116101695780634b980d67146103e157806355f804b31461040b57806360d3e1ae146104335780636352211e1461045b578063672434821461049757610203565b80633f70eb8c1461034957806342842e0e14610371578063453c23101461038d57806347535d7b146103b757610203565b8063108bfbfa116101d6578063108bfbfa146102c557806318160ddd146102ed57806323b872dd146103175780633ccfd60b1461033357610203565b806301ffc9a71461020757806306fdde0314610243578063081812fc1461026d578063095ea7b3146102a9575b5f80fd5b348015610212575f80fd5b5061022d60048036038101906102289190611f8a565b6107af565b60405161023a9190611fcf565b60405180910390f35b34801561024e575f80fd5b50610257610840565b6040516102649190612058565b60405180910390f35b348015610278575f80fd5b50610293600480360381019061028e91906120ab565b6108d0565b6040516102a09190612115565b60405180910390f35b6102c360048036038101906102be9190612158565b610929565b005b3480156102d0575f80fd5b506102eb60048036038101906102e691906120ab565b610939565b005b3480156102f8575f80fd5b5061030161094b565b60405161030e91906121a5565b60405180910390f35b610331600480360381019061032c91906121be565b610996565b005b34801561033e575f80fd5b50610347610c41565b005b348015610354575f80fd5b5061036f600480360381019061036a919061233a565b610ca6565b005b61038b600480360381019061038691906121be565b610cc1565b005b348015610398575f80fd5b506103a1610ce0565b6040516103ae91906121a5565b60405180910390f35b3480156103c2575f80fd5b506103cb610ce6565b6040516103d89190611fcf565b60405180910390f35b3480156103ec575f80fd5b506103f5610cf8565b60405161040291906121a5565b60405180910390f35b348015610416575f80fd5b50610431600480360381019061042c919061233a565b610cfe565b005b34801561043e575f80fd5b50610459600480360381019061045491906120ab565b610d19565b005b348015610466575f80fd5b50610481600480360381019061047c91906120ab565b610d2b565b60405161048e9190612115565b60405180910390f35b3480156104a2575f80fd5b506104bd60048036038101906104b89190612505565b610d3c565b005b3480156104ca575f80fd5b506104d3610d9f565b6040516104e09190612058565b60405180910390f35b3480156104f4575f80fd5b5061050f600480360381019061050a919061257b565b610e2b565b60405161051c91906121a5565b60405180910390f35b348015610530575f80fd5b50610539610ebf565b005b348015610546575f80fd5b5061054f610ef1565b005b34801561055c575f80fd5b50610565610f04565b6040516105729190612115565b60405180910390f35b348015610586575f80fd5b506105a1600480360381019061059c91906120ab565b610f2c565b005b3480156105ae575f80fd5b506105b7610f3e565b6040516105c49190612058565b60405180910390f35b3480156105d8575f80fd5b506105e1610fce565b6040516105ee91906121a5565b60405180910390f35b610611600480360381019061060c91906120ab565b610fd4565b005b34801561061e575f80fd5b50610639600480360381019061063491906125d0565b6111f0565b005b348015610646575f80fd5b50610661600480360381019061065c919061257b565b6112f6565b60405161066e91906121a5565b60405180910390f35b610691600480360381019061068c91906126ac565b61130b565b005b34801561069e575f80fd5b506106b960048036038101906106b491906120ab565b61135c565b6040516106c69190612058565b60405180910390f35b3480156106da575f80fd5b506106e36113d6565b6040516106f091906121a5565b60405180910390f35b348015610704575f80fd5b5061070d6113dc565b60405161071a9190612058565b60405180910390f35b34801561072e575f80fd5b506107496004803603810190610744919061272c565b611468565b6040516107569190611fcf565b60405180910390f35b34801561076a575f80fd5b50610785600480360381019061078091906120ab565b6114f6565b005b348015610792575f80fd5b506107ad60048036038101906107a8919061257b565b61150b565b005b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061080957506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108395750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461084f90612797565b80601f016020809104026020016040519081016040528092919081815260200182805461087b90612797565b80156108c65780601f1061089d576101008083540402835291602001916108c6565b820191905f5260205f20905b8154815290600101906020018083116108a957829003601f168201915b5050505050905090565b5f6108da8261158f565b6108ef576108ee63cf4700e460e01b611632565b5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6109358282600161163a565b5050565b610941611764565b8060108190555050565b5f6109546117eb565b6001545f54030390507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6109866117f3565b1461099357600854810190505b90565b5f6109a08261181a565b905073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161693508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a1557610a1463a114810060e01b611632565b5b5f80610a2084611929565b91509150610a368187610a3161194c565b611953565b610a6157610a4b86610a4661194c565b611468565b610a6057610a5f6359c896be60e01b611632565b5b5b610a6e8686866001611996565b8015610a78575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f815460010191905081905550610b4085610b1c88888761199c565b7c0200000000000000000000000000000000000000000000000000000000176119c3565b60045f8681526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000841603610bbc575f6001850190505f60045f8381526020019081526020015f205403610bba575f548114610bb9578360045f8381526020019081526020015f20819055505b5b505b5f73ffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff161690508481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a45f8103610c2b57610c2a63ea553b3460e01b611632565b5b610c3887878760016119ed565b50505050505050565b610c49611764565b3373ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff163190811502906040515f60405180830381858888f19350505050158015610ca3573d5f803e3d5ffd5b50565b610cae611764565b80600b9081610cbd9190612964565b5050565b610cdb83838360405180602001604052805f81525061130b565b505050565b60115481565b600c5f9054906101000a900460ff1681565b60105481565b610d06611764565b80600e9081610d159190612964565b5050565b610d21611764565b8060118190555050565b5f610d358261181a565b9050919050565b610d44611764565b5f5b8251811015610d9a57610d8d838281518110610d6557610d64612a33565b5b6020026020010151838381518110610d8057610d7f612a33565b5b60200260200101516119f3565b8080600101915050610d46565b505050565b600e8054610dac90612797565b80601f0160208091040260200160405190810160405280929190818152602001828054610dd890612797565b8015610e235780601f10610dfa57610100808354040283529160200191610e23565b820191905f5260205f20905b815481529060010190602001808311610e0657829003601f168201915b505050505081565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610e7057610e6f638f4eb60460e01b611632565b5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b610ec7611764565b600c5f9054906101000a900460ff1615600c5f6101000a81548160ff021916908315150217905550565b610ef9611764565b610f025f611a10565b565b5f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610f34611764565b80600d8190555050565b606060038054610f4d90612797565b80601f0160208091040260200160405190810160405280929190818152602001828054610f7990612797565b8015610fc45780601f10610f9b57610100808354040283529160200191610fc4565b820191905f5260205f20905b815481529060010190602001808311610fa757829003601f168201915b5050505050905090565b600d5481565b600c5f9054906101000a900460ff16611022576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101990612aaa565b60405180910390fd5b601054811115611067576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105e90612b12565b60405180910390fd5b601054600f5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205411156110e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e090612b7a565b60405180910390fd5b601254816110f561094b565b6110ff9190612bc5565b1115611140576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113790612c42565b60405180910390fd5b600d548161114e9190612c60565b341015611190576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118790612ceb565b60405180910390fd5b80600f5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282546111dc9190612bc5565b925050819055506111ed33826119f3565b50565b8060075f6111fc61194c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166112a561194c565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516112ea9190611fcf565b60405180910390a35050565b600f602052805f5260405f205f915090505481565b611316848484610996565b5f8373ffffffffffffffffffffffffffffffffffffffff163b146113565761134084848484611ad3565b6113555761135463d1a57ed660e01b611632565b5b5b50505050565b60606113678261158f565b61137c5761137b63a14c4b5060e01b611632565b5b5f611385611bfd565b90505f8151036113a35760405180602001604052805f8152506113ce565b806113ad84611c8d565b6040516020016113be929190612d43565b6040516020818303038152906040525b915050919050565b60125481565b600b80546113e990612797565b80601f016020809104026020016040519081016040528092919081815260200182805461141590612797565b80156114605780601f1061143757610100808354040283529160200191611460565b820191905f5260205f20905b81548152906001019060200180831161144357829003601f168201915b505050505081565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b6114fe611764565b61150833826119f3565b50565b611513611764565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611583575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161157a9190612115565b60405180910390fd5b61158c81611a10565b50565b5f816115996117eb565b1161162c576115a66117f3565b8211156115ce576115c760045f8481526020019081526020015f2054611cdc565b905061162d565b5f5482101561162b575f5b5f60045f8581526020019081526020015f20549150810361160557826115fe90612d66565b92506115d9565b5f7c01000000000000000000000000000000000000000000000000000000008216149150505b5b5b919050565b805f5260045ffd5b5f61164483610d2b565b905081801561168657508073ffffffffffffffffffffffffffffffffffffffff1661166d61194c565b73ffffffffffffffffffffffffffffffffffffffff1614155b156116b25761169c8161169761194c565b611468565b6116b1576116b063cfb3b94260e01b611632565b5b5b8360065f8581526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b61176c611d1c565b73ffffffffffffffffffffffffffffffffffffffff1661178a610f04565b73ffffffffffffffffffffffffffffffffffffffff16146117e9576117ad611d1c565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016117e09190612115565b60405180910390fd5b565b5f6001905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b5f816118246117eb565b116119135760045f8381526020019081526020015f205490506118456117f3565b82111561186a5761185581611cdc565b6119245761186963df2d9b4260e01b611632565b5b5f81036118eb575f54821061188a5761188963df2d9b4260e01b611632565b5b5b60045f836001900393508381526020019081526020015f205490505f8103156118e6575f7c010000000000000000000000000000000000000000000000000000000082160315611924576118e563df2d9b4260e01b611632565b5b61188b565b5f7c010000000000000000000000000000000000000000000000000000000082160315611924575b61192363df2d9b4260e01b611632565b5b919050565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b5f8060e883901c905060e86119b2868684611d23565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b611a0c828260405180602001604052805f815250611d2b565b5050565b5f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a02611af861194c565b8786866040518563ffffffff1660e01b8152600401611b1a9493929190612ddf565b6020604051808303815f875af1925050508015611b5557506040513d601f19601f82011682018060405250810190611b529190612e3d565b60015b611baa573d805f8114611b83576040519150601f19603f3d011682016040523d82523d5f602084013e611b88565b606091505b505f815103611ba257611ba163d1a57ed660e01b611632565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600e8054611c0c90612797565b80601f0160208091040260200160405190810160405280929190818152602001828054611c3890612797565b8015611c835780601f10611c5a57610100808354040283529160200191611c83565b820191905f5260205f20905b815481529060010190602001808311611c6657829003601f168201915b5050505050905090565b606060a060405101806040526020810391505f825281835b600115611cc757600184039350600a81066030018453600a8104905080611ca5575b50828103602084039350808452505050919050565b5f7c0100000000000000000000000000000000000000000000000000000000821673ffffffffffffffffffffffffffffffffffffffff8316119050919050565b5f33905090565b5f9392505050565b611d358383611da1565b5f8373ffffffffffffffffffffffffffffffffffffffff163b14611d9c575f805490505f83820390505b611d715f868380600101945086611ad3565b611d8657611d8563d1a57ed660e01b611632565b5b818110611d5f57815f5414611d99575f80fd5b50505b505050565b5f805490505f8203611dbe57611dbd63b562e8dd60e01b611632565b5b611dca5f848385611996565b611de883611dd95f865f61199c565b611de285611f15565b176119c3565b60045f8381526020019081526020015f2081905550600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505f73ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161690505f8103611e9957611e98632e07630060e01b611632565b5b5f83830190505f839050611eab6117f3565b600183031115611ec657611ec56381647e3a60e01b611632565b5b5b80835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4818160010191508103611ec757815f81905550505050611f105f8483856119ed565b505050565b5f6001821460e11b9050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611f6981611f35565b8114611f73575f80fd5b50565b5f81359050611f8481611f60565b92915050565b5f60208284031215611f9f57611f9e611f2d565b5b5f611fac84828501611f76565b91505092915050565b5f8115159050919050565b611fc981611fb5565b82525050565b5f602082019050611fe25f830184611fc0565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61202a82611fe8565b6120348185611ff2565b9350612044818560208601612002565b61204d81612010565b840191505092915050565b5f6020820190508181035f8301526120708184612020565b905092915050565b5f819050919050565b61208a81612078565b8114612094575f80fd5b50565b5f813590506120a581612081565b92915050565b5f602082840312156120c0576120bf611f2d565b5b5f6120cd84828501612097565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6120ff826120d6565b9050919050565b61210f816120f5565b82525050565b5f6020820190506121285f830184612106565b92915050565b612137816120f5565b8114612141575f80fd5b50565b5f813590506121528161212e565b92915050565b5f806040838503121561216e5761216d611f2d565b5b5f61217b85828601612144565b925050602061218c85828601612097565b9150509250929050565b61219f81612078565b82525050565b5f6020820190506121b85f830184612196565b92915050565b5f805f606084860312156121d5576121d4611f2d565b5b5f6121e286828701612144565b93505060206121f386828701612144565b925050604061220486828701612097565b9150509250925092565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61224c82612010565b810181811067ffffffffffffffff8211171561226b5761226a612216565b5b80604052505050565b5f61227d611f24565b90506122898282612243565b919050565b5f67ffffffffffffffff8211156122a8576122a7612216565b5b6122b182612010565b9050602081019050919050565b828183375f83830152505050565b5f6122de6122d98461228e565b612274565b9050828152602081018484840111156122fa576122f9612212565b5b6123058482856122be565b509392505050565b5f82601f8301126123215761232061220e565b5b81356123318482602086016122cc565b91505092915050565b5f6020828403121561234f5761234e611f2d565b5b5f82013567ffffffffffffffff81111561236c5761236b611f31565b5b6123788482850161230d565b91505092915050565b5f67ffffffffffffffff82111561239b5761239a612216565b5b602082029050602081019050919050565b5f80fd5b5f6123c26123bd84612381565b612274565b905080838252602082019050602084028301858111156123e5576123e46123ac565b5b835b8181101561240e57806123fa8882612144565b8452602084019350506020810190506123e7565b5050509392505050565b5f82601f83011261242c5761242b61220e565b5b813561243c8482602086016123b0565b91505092915050565b5f67ffffffffffffffff82111561245f5761245e612216565b5b602082029050602081019050919050565b5f61248261247d84612445565b612274565b905080838252602082019050602084028301858111156124a5576124a46123ac565b5b835b818110156124ce57806124ba8882612097565b8452602084019350506020810190506124a7565b5050509392505050565b5f82601f8301126124ec576124eb61220e565b5b81356124fc848260208601612470565b91505092915050565b5f806040838503121561251b5761251a611f2d565b5b5f83013567ffffffffffffffff81111561253857612537611f31565b5b61254485828601612418565b925050602083013567ffffffffffffffff81111561256557612564611f31565b5b612571858286016124d8565b9150509250929050565b5f602082840312156125905761258f611f2d565b5b5f61259d84828501612144565b91505092915050565b6125af81611fb5565b81146125b9575f80fd5b50565b5f813590506125ca816125a6565b92915050565b5f80604083850312156125e6576125e5611f2d565b5b5f6125f385828601612144565b9250506020612604858286016125bc565b9150509250929050565b5f67ffffffffffffffff82111561262857612627612216565b5b61263182612010565b9050602081019050919050565b5f61265061264b8461260e565b612274565b90508281526020810184848401111561266c5761266b612212565b5b6126778482856122be565b509392505050565b5f82601f8301126126935761269261220e565b5b81356126a384826020860161263e565b91505092915050565b5f805f80608085870312156126c4576126c3611f2d565b5b5f6126d187828801612144565b94505060206126e287828801612144565b93505060406126f387828801612097565b925050606085013567ffffffffffffffff81111561271457612713611f31565b5b6127208782880161267f565b91505092959194509250565b5f806040838503121561274257612741611f2d565b5b5f61274f85828601612144565b925050602061276085828601612144565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806127ae57607f821691505b6020821081036127c1576127c061276a565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026128237fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826127e8565b61282d86836127e8565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61286861286361285e84612078565b612845565b612078565b9050919050565b5f819050919050565b6128818361284e565b61289561288d8261286f565b8484546127f4565b825550505050565b5f90565b6128a961289d565b6128b4818484612878565b505050565b5b818110156128d7576128cc5f826128a1565b6001810190506128ba565b5050565b601f82111561291c576128ed816127c7565b6128f6846127d9565b81016020851015612905578190505b612919612911856127d9565b8301826128b9565b50505b505050565b5f82821c905092915050565b5f61293c5f1984600802612921565b1980831691505092915050565b5f612954838361292d565b9150826002028217905092915050565b61296d82611fe8565b67ffffffffffffffff81111561298657612985612216565b5b6129908254612797565b61299b8282856128db565b5f60209050601f8311600181146129cc575f84156129ba578287015190505b6129c48582612949565b865550612a2b565b601f1984166129da866127c7565b5f5b82811015612a01578489015182556001820191506020850194506020810190506129dc565b86831015612a1e5784890151612a1a601f89168261292d565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4d696e74696e672061726520636c6f73656420210000000000000000000000005f82015250565b5f612a94601483611ff2565b9150612a9f82612a60565b602082019050919050565b5f6020820190508181035f830152612ac181612a88565b9050919050565b7f4c696d6974205472616e73616374696f6e2021000000000000000000000000005f82015250565b5f612afc601383611ff2565b9150612b0782612ac8565b602082019050919050565b5f6020820190508181035f830152612b2981612af0565b9050919050565b7f4c696d69742057616c6c657420210000000000000000000000000000000000005f82015250565b5f612b64600e83611ff2565b9150612b6f82612b30565b602082019050919050565b5f6020820190508181035f830152612b9181612b58565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612bcf82612078565b9150612bda83612078565b9250828201905080821115612bf257612bf1612b98565b5b92915050565b7f536f6c646f7574202100000000000000000000000000000000000000000000005f82015250565b5f612c2c600983611ff2565b9150612c3782612bf8565b602082019050919050565b5f6020820190508181035f830152612c5981612c20565b9050919050565b5f612c6a82612078565b9150612c7583612078565b9250828202612c8381612078565b91508282048414831517612c9a57612c99612b98565b5b5092915050565b7f496e73756666696369656e742046756e647320210000000000000000000000005f82015250565b5f612cd5601483611ff2565b9150612ce082612ca1565b602082019050919050565b5f6020820190508181035f830152612d0281612cc9565b9050919050565b5f81905092915050565b5f612d1d82611fe8565b612d278185612d09565b9350612d37818560208601612002565b80840191505092915050565b5f612d4e8285612d13565b9150612d5a8284612d13565b91508190509392505050565b5f612d7082612078565b91505f8203612d8257612d81612b98565b5b600182039050919050565b5f81519050919050565b5f82825260208201905092915050565b5f612db182612d8d565b612dbb8185612d97565b9350612dcb818560208601612002565b612dd481612010565b840191505092915050565b5f608082019050612df25f830187612106565b612dff6020830186612106565b612e0c6040830185612196565b8181036060830152612e1e8184612da7565b905095945050505050565b5f81519050612e3781611f60565b92915050565b5f60208284031215612e5257612e51611f2d565b5b5f612e5f84828501612e29565b9150509291505056fea26469706673582212208bc1cdc65f0a74995ac1a88d286fdf5408e5b979e9b13595040940d2b58b0e7664736f6c634300081a0033
Deployed Bytecode Sourcemap
299:2251:5:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10689:630:6;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;11573:98;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18636:223;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18364:122;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2167:134:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;6890:564:6;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22796:3447;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2431:116:5;;;;;;;;;;;;;:::i;:::-;;1764:106;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;26334:187:6;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;604:33:5;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;408:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;557:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1965:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2309:114;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;12934:150:6;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1427:220:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;478:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8570:239:6;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1878:75:5;;;;;;;;;;;;;:::i;:::-;;2293:101:0;;;;;;;;;;;;;:::i;:::-;;1638:85;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2073:86:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;11742:102:6;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;441:30:5;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;847:456;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;19186:231:6;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;508:42:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;27102:405:6;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;11945:322;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;646:32:5;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;374:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;19567:162:6;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1655:101:5;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2543:215:0;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;10689:630:6;10774:4;11107:10;11092:25;;:11;:25;;;;:101;;;;11183:10;11168:25;;:11;:25;;;;11092:101;:177;;;;11259:10;11244:25;;:11;:25;;;;11092:177;11073:196;;10689:630;;;:::o;11573:98::-;11627:13;11659:5;11652:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11573:98;:::o;18636:223::-;18712:7;18736:16;18744:7;18736;:16::i;:::-;18731:73;;18754:50;18762:41;;;18754:7;:50::i;:::-;18731:73;18822:15;:24;18838:7;18822:24;;;;;;;;;;;:30;;;;;;;;;;;;18815:37;;18636:223;;;:::o;18364:122::-;18452:27;18461:2;18465:7;18474:4;18452:8;:27::i;:::-;18364:122;;:::o;2167:134:5:-;1531:13:0;:11;:13::i;:::-;2275:18:5::1;2255:17;:38;;;;2167:134:::0;:::o;6890:564:6:-;6951:14;7343:15;:13;:15::i;:::-;7328:12;;7312:13;;:28;:46;7303:55;;7397:17;7376;:15;:17::i;:::-;:38;7372:65;;7426:11;;7416:21;;;;7372:65;6890:564;:::o;22796:3447::-;22933:27;22963;22982:7;22963:18;:27::i;:::-;22933:57;;2943:14;23131:4;23115:22;;:41;23092:66;;23214:4;23173:45;;23189:19;23173:45;;;23169:95;;23220:44;23228:35;;;23220:7;:44::i;:::-;23169:95;23276:27;23305:23;23332:35;23359:7;23332:26;:35::i;:::-;23275:92;;;;23464:68;23489:15;23506:4;23512:19;:17;:19::i;:::-;23464:24;:68::i;:::-;23459:188;;23551:43;23568:4;23574:19;:17;:19::i;:::-;23551:16;:43::i;:::-;23546:101;;23596:51;23604:42;;;23596:7;:51::i;:::-;23546:101;23459:188;23658:43;23680:4;23686:2;23690:7;23699:1;23658:21;:43::i;:::-;23790:15;23787:157;;;23928:1;23907:19;23900:30;23787:157;24316:18;:24;24335:4;24316:24;;;;;;;;;;;;;;;;24314:26;;;;;;;;;;;;24384:18;:22;24403:2;24384:22;;;;;;;;;;;;;;;;24382:24;;;;;;;;;;;24699:143;24735:2;24783:45;24798:4;24804:2;24808:19;24783:14;:45::i;:::-;2550:8;24755:73;24699:18;:143::i;:::-;24670:17;:26;24688:7;24670:26;;;;;;;;;;;:172;;;;25010:1;2550:8;24959:19;:47;:52;24955:617;;25031:19;25063:1;25053:7;:11;25031:33;;25218:1;25184:17;:30;25202:11;25184:30;;;;;;;;;;;;:35;25180:378;;25320:13;;25305:11;:28;25301:239;;25498:19;25465:17;:30;25483:11;25465:30;;;;;;;;;;;:52;;;;25301:239;25180:378;25013:559;24955:617;25681:16;2943:14;25716:2;25700:20;;:39;25681:58;;26071:7;26036:8;26003:4;25946:25;25892:1;25836;25814:292;26141:1;26129:8;:13;26125:58;;26144:39;26152:30;;;26144:7;:39::i;:::-;26125:58;26194:42;26215:4;26221:2;26225:7;26234:1;26194:20;:42::i;:::-;22923:3320;;;;22796:3447;;;:::o;2431:116:5:-;1531:13:0;:11;:13::i;:::-;2487:10:5::1;2479:28;;:60;2524:4;2508:30;;;2479:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;2431:116::o:0;1764:106::-;1531:13:0;:11;:13::i;:::-;1851:11:5::1;1840:8;:22;;;;;;:::i;:::-;;1764:106:::0;:::o;26334:187:6:-;26475:39;26492:4;26498:2;26502:7;26475:39;;;;;;;;;;;;:16;:39::i;:::-;26334:187;;;:::o;604:33:5:-;;;;:::o;408:26::-;;;;;;;;;;;;;:::o;557:38::-;;;;:::o;1965:100::-;1531:13:0;:11;:13::i;:::-;2049:8:5::1;2039:7;:18;;;;;;:::i;:::-;;1965:100:::0;:::o;2309:114::-;1531:13:0;:11;:13::i;:::-;2402::5::1;2387:12;:28;;;;2309:114:::0;:::o;12934:150:6:-;13006:7;13048:27;13067:7;13048:18;:27::i;:::-;13025:52;;12934:150;;;:::o;1427:220:5:-;1531:13:0;:11;:13::i;:::-;1533:9:5::1;1528:112;1552:13;:20;1548:1;:24;1528:112;;;1593:35;1603:13;1617:1;1603:16;;;;;;;;:::i;:::-;;;;;;;;1621:3;1625:1;1621:6;;;;;;;;:::i;:::-;;;;;;;;1593:9;:35::i;:::-;1574:3;;;;;;;1528:112;;;;1427:220:::0;;:::o;478:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;8570:239:6:-;8642:7;8682:1;8665:19;;:5;:19;;;8661:69;;8686:44;8694:35;;;8686:7;:44::i;:::-;8661:69;1518:13;8747:18;:25;8766:5;8747:25;;;;;;;;;;;;;;;;:55;8740:62;;8570:239;;;:::o;1878:75:5:-;1531:13:0;:11;:13::i;:::-;1938:6:5::1;;;;;;;;;;;1937:7;1927:6;;:17;;;;;;;;;;;;;;;;;;1878:75::o:0;2293:101:0:-;1531:13;:11;:13::i;:::-;2357:30:::1;2384:1;2357:18;:30::i;:::-;2293:101::o:0;1638:85::-;1684:7;1710:6;;;;;;;;;;;1703:13;;1638:85;:::o;2073:86:5:-;1531:13:0;:11;:13::i;:::-;2145:6:5::1;2137:5;:14;;;;2073:86:::0;:::o;11742:102:6:-;11798:13;11830:7;11823:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11742:102;:::o;441:30:5:-;;;;:::o;847:456::-;915:6;;;;;;;;;;;907:40;;;;;;;;;;;;:::i;:::-;;;;;;;;;973:17;;966:3;:24;;958:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;1055:17;;1033:6;:18;1040:10;1033:18;;;;;;;;;;;;;;;;:39;;1025:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;1133:9;;1126:3;1110:13;:11;:13::i;:::-;:19;;;;:::i;:::-;:32;;1102:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;1193:5;;1187:3;:11;;;;:::i;:::-;1174:9;:24;;1166:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;1255:3;1233:6;:18;1240:10;1233:18;;;;;;;;;;;;;;;;:25;;;;;;;:::i;:::-;;;;;;;;1269:26;1279:10;1291:3;1269:9;:26::i;:::-;847:456;:::o;19186:231:6:-;19332:8;19280:18;:39;19299:19;:17;:19::i;:::-;19280:39;;;;;;;;;;;;;;;:49;19320:8;19280:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;19391:8;19355:55;;19370:19;:17;:19::i;:::-;19355:55;;;19401:8;19355:55;;;;;;:::i;:::-;;;;;;;;19186:231;;:::o;508:42:5:-;;;;;;;;;;;;;;;;;:::o;27102:405:6:-;27271:31;27284:4;27290:2;27294:7;27271:12;:31::i;:::-;27334:1;27316:2;:14;;;:19;27312:189;;27354:56;27385:4;27391:2;27395:7;27404:5;27354:30;:56::i;:::-;27349:152;;27430:56;27438:47;;;27430:7;:56::i;:::-;27349:152;27312:189;27102:405;;;;:::o;11945:322::-;12018:13;12048:16;12056:7;12048;:16::i;:::-;12043:68;;12066:45;12074:36;;;12066:7;:45::i;:::-;12043:68;12122:21;12146:10;:8;:10::i;:::-;12122:34;;12198:1;12179:7;12173:21;:26;:87;;;;;;;;;;;;;;;;;12226:7;12235:18;12245:7;12235:9;:18::i;:::-;12209:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;12173:87;12166:94;;;11945:322;;;:::o;646:32:5:-;;;;:::o;374:27::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;19567:162:6:-;19664:4;19687:18;:25;19706:5;19687:25;;;;;;;;;;;;;;;:35;19713:8;19687:35;;;;;;;;;;;;;;;;;;;;;;;;;19680:42;;19567:162;;;;:::o;1655:101:5:-;1531:13:0;:11;:13::i;:::-;1722:26:5::1;1732:10;1744:3;1722:9;:26::i;:::-;1655:101:::0;:::o;2543:215:0:-;1531:13;:11;:13::i;:::-;2647:1:::1;2627:22;;:8;:22;;::::0;2623:91:::1;;2700:1;2672:31;;;;;;;;;;;:::i;:::-;;;;;;;;2623:91;2723:28;2742:8;2723:18;:28::i;:::-;2543:215:::0;:::o;19978:465:6:-;20043:11;20089:7;20070:15;:13;:15::i;:::-;:26;20066:371;;20126:17;:15;:17::i;:::-;20116:7;:27;20112:90;;;20152:50;20175:17;:26;20193:7;20175:26;;;;;;;;;;;;20152:22;:50::i;:::-;20145:57;;;;20112:90;20231:13;;20221:7;:23;20217:210;;;20264:14;20296:60;20344:1;20313:17;:26;20331:7;20313:26;;;;;;;;;;;;20304:35;;;20303:42;20296:60;;20347:9;;;;:::i;:::-;;;20296:60;;;20411:1;2276:8;20383:6;:24;:29;20374:38;;20246:181;20217:210;20066:371;19978:465;;;;:::o;49703:160::-;49802:13;49796:4;49789:27;49842:4;49836;49829:18;41333:460;41457:13;41473:16;41481:7;41473;:16::i;:::-;41457:32;;41504:13;:45;;;;;41544:5;41521:28;;:19;:17;:19::i;:::-;:28;;;;41504:45;41500:198;;;41568:44;41585:5;41592:19;:17;:19::i;:::-;41568:16;:44::i;:::-;41563:135;;41632:51;41640:42;;;41632:7;:51::i;:::-;41563:135;41500:198;41741:2;41708:15;:24;41724:7;41708:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;41778:7;41774:2;41758:28;;41767:5;41758:28;;;;;;;;;;;;41447:346;41333:460;;;:::o;1796:162:0:-;1866:12;:10;:12::i;:::-;1855:23;;:7;:5;:7::i;:::-;:23;;;1851:101;;1928:12;:10;:12::i;:::-;1901:40;;;;;;;;;;;:::i;:::-;;;;;;;;1851:101;1796:162::o;738:101:5:-;803:7;830:1;823:8;;738:101;:::o;6404:108:6:-;6462:7;6488:17;6481:24;;6404:108;:::o;14380:2173::-;14447:14;14496:7;14477:15;:13;:15::i;:::-;:26;14473:2017;;14528:17;:26;14546:7;14528:26;;;;;;;;;;;;14519:35;;14583:17;:15;:17::i;:::-;14573:7;:27;14569:180;;;14624:30;14647:6;14624:22;:30::i;:::-;14656:13;14620:49;14687:47;14695:38;;;14687:7;:47::i;:::-;14569:180;14857:1;14847:6;:11;14843:1270;;14893:13;;14882:7;:24;14878:77;;14908:47;14916:38;;;14908:7;:47::i;:::-;14878:77;15502:597;15578:17;:28;15596:9;;;;;;;15578:28;;;;;;;;;;;;15569:37;;15664:1;15654:6;:11;15650:25;15667:8;15650:25;15729:1;2276:8;15701:6;:24;:29;15697:48;15732:13;15697:48;16033:47;16041:38;;;16033:7;:47::i;:::-;15502:597;;;14843:1270;16463:1;2276:8;16435:6;:24;:29;16431:48;16466:13;16431:48;14473:2017;16499:47;16507:38;;;16499:7;:47::i;:::-;14380:2173;;;;:::o;21721:474::-;21820:27;21849:23;21888:38;21929:15;:24;21945:7;21929:24;;;;;;;;;;;21888:65;;22103:18;22080:41;;22159:19;22153:26;22134:45;;22066:123;21721:474;;;:::o;47733:103::-;47793:7;47819:10;47812:17;;47733:103;:::o;20967:646::-;21112:11;21274:16;21267:5;21263:28;21254:37;;21432:16;21421:9;21417:32;21404:45;;21580:15;21569:9;21566:30;21558:5;21547:9;21544:20;21541:56;21531:66;;20967:646;;;;;:::o;28151:154::-;;;;;:::o;47060:304::-;47191:7;47210:16;2671:3;47236:19;:41;;47210:68;;2671:3;47303:31;47314:4;47320:2;47324:9;47303:10;:31::i;:::-;47295:40;;:62;;47288:69;;;47060:304;;;;;:::o;17086:443::-;17166:14;17331:16;17324:5;17320:28;17311:37;;17506:5;17492:11;17467:23;17463:41;17460:52;17453:5;17450:63;17440:73;;17086:443;;;;:::o;28952:153::-;;;;;:::o;36661:110::-;36737:27;36747:2;36751:8;36737:27;;;;;;;;;;;;:9;:27::i;:::-;36661:110;;:::o;2912:187:0:-;2985:16;3004:6;;;;;;;;;;;2985:25;;3029:8;3020:6;;:17;;;;;;;;;;;;;;;;;;3083:8;3052:40;;3073:8;3052:40;;;;;;;;;;;;2975:124;2912:187;:::o;29533:673:6:-;29691:4;29736:2;29711:45;;;29757:19;:17;:19::i;:::-;29778:4;29784:7;29793:5;29711:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;29707:493;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30006:1;29989:6;:13;:18;29985:113;;30027:56;30035:47;;;30027:7;:56::i;:::-;29985:113;30168:6;30162:13;30153:6;30149:2;30145:15;30138:38;29707:493;29877:54;;;29867:64;;;:6;:64;;;;29860:71;;;29533:673;;;;;;:::o;1311:108:5:-;1371:13;1404:7;1397:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1311:108;:::o;47933:1708:6:-;47998:17;48426:4;48419;48413:11;48409:22;48516:1;48510:4;48503:15;48589:4;48586:1;48582:12;48575:19;;48669:1;48664:3;48657:14;48770:3;49004:5;48986:419;49012:1;48986:419;;;49051:1;49046:3;49042:11;49035:18;;49219:2;49213:4;49209:13;49205:2;49201:22;49196:3;49188:36;49311:2;49305:4;49301:13;49293:21;;49376:4;48986:419;49366:25;48986:419;48990:21;49442:3;49437;49433:13;49555:4;49550:3;49546:14;49539:21;;49618:6;49613:3;49606:19;48036:1599;;;47933:1708;;;:::o;20534:329::-;20604:11;20830:15;20822:6;20818:28;20799:16;20791:6;20787:29;20784:63;20774:73;;20534:329;;;:::o;656:96:2:-;709:7;735:10;728:17;;656:96;:::o;46771:143:6:-;46904:6;46771:143;;;;;:::o;35816:766::-;35942:19;35948:2;35952:8;35942:5;:19::i;:::-;36018:1;36000:2;:14;;;:19;35996:570;;36039:11;36053:13;;36039:27;;36084:13;36106:8;36100:3;:14;36084:30;;36132:238;36162:62;36201:1;36205:2;36209:7;;;;;;36218:5;36162:30;:62::i;:::-;36157:174;;36252:56;36260:47;;;36252:7;:56::i;:::-;36157:174;36365:3;36357:5;:11;36132:238;;36538:3;36521:13;;:20;36517:34;;36543:8;;;36517:34;36021:545;;35996:570;35816:766;;;:::o;30652:2343::-;30724:20;30747:13;;30724:36;;30786:1;30774:8;:13;30770:53;;30789:34;30797:25;;;30789:7;:34::i;:::-;30770:53;30834:61;30864:1;30868:2;30872:12;30886:8;30834:21;:61::i;:::-;31357:136;31393:2;31446:33;31469:1;31473:2;31477:1;31446:14;:33::i;:::-;31413:30;31434:8;31413:20;:30::i;:::-;:66;31357:18;:136::i;:::-;31323:17;:31;31341:12;31323:31;;;;;;;;;;;:170;;;;31773:1;1653:2;31743:1;:26;;31742:32;31730:8;:45;31704:18;:22;31723:2;31704:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;31883:16;2943:14;31918:2;31902:20;;:39;31883:58;;31972:1;31960:8;:13;31956:54;;31975:35;31983:26;;;31975:7;:35::i;:::-;31956:54;32025:11;32054:8;32039:12;:23;32025:37;;32076:15;32094:12;32076:30;;32135:17;:15;:17::i;:::-;32131:1;32125:3;:7;:27;32121:77;;;32154:44;32162:35;;;32154:7;:44::i;:::-;32121:77;32213:662;32623:7;32580:8;32536:1;32471:25;32409:1;32345;32315:351;32870:3;32857:9;;;;;;:16;32213:662;;32905:3;32889:13;:19;;;;31078:1841;;;32928:60;32957:1;32961:2;32965:12;32979:8;32928:20;:60::i;:::-;30714:2281;30652:2343;;:::o;17626:318::-;17696:14;17925:1;17915:8;17912:15;17886:24;17882:46;17872:56;;17626:318;;;:::o;7:75:8:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:139::-;1887:6;1882:3;1877;1871:23;1928:1;1919:6;1914:3;1910:16;1903:27;1798:139;;;:::o;1943:102::-;1984:6;2035:2;2031:7;2026:2;2019:5;2015:14;2011:28;2001:38;;1943:102;;;:::o;2051:377::-;2139:3;2167:39;2200:5;2167:39;:::i;:::-;2222:71;2286:6;2281:3;2222:71;:::i;:::-;2215:78;;2302:65;2360:6;2355:3;2348:4;2341:5;2337:16;2302:65;:::i;:::-;2392:29;2414:6;2392:29;:::i;:::-;2387:3;2383:39;2376:46;;2143:285;2051:377;;;;:::o;2434:313::-;2547:4;2585:2;2574:9;2570:18;2562:26;;2634:9;2628:4;2624:20;2620:1;2609:9;2605:17;2598:47;2662:78;2735:4;2726:6;2662:78;:::i;:::-;2654:86;;2434:313;;;;:::o;2753:77::-;2790:7;2819:5;2808:16;;2753:77;;;:::o;2836:122::-;2909:24;2927:5;2909:24;:::i;:::-;2902:5;2899:35;2889:63;;2948:1;2945;2938:12;2889:63;2836:122;:::o;2964:139::-;3010:5;3048:6;3035:20;3026:29;;3064:33;3091:5;3064:33;:::i;:::-;2964:139;;;;:::o;3109:329::-;3168:6;3217:2;3205:9;3196:7;3192:23;3188:32;3185:119;;;3223:79;;:::i;:::-;3185:119;3343:1;3368:53;3413:7;3404:6;3393:9;3389:22;3368:53;:::i;:::-;3358:63;;3314:117;3109:329;;;;:::o;3444:126::-;3481:7;3521:42;3514:5;3510:54;3499:65;;3444:126;;;:::o;3576:96::-;3613:7;3642:24;3660:5;3642:24;:::i;:::-;3631:35;;3576:96;;;:::o;3678:118::-;3765:24;3783:5;3765:24;:::i;:::-;3760:3;3753:37;3678:118;;:::o;3802:222::-;3895:4;3933:2;3922:9;3918:18;3910:26;;3946:71;4014:1;4003:9;3999:17;3990:6;3946:71;:::i;:::-;3802:222;;;;:::o;4030:122::-;4103:24;4121:5;4103:24;:::i;:::-;4096:5;4093:35;4083:63;;4142:1;4139;4132:12;4083:63;4030:122;:::o;4158:139::-;4204:5;4242:6;4229:20;4220:29;;4258:33;4285:5;4258:33;:::i;:::-;4158:139;;;;:::o;4303:474::-;4371:6;4379;4428:2;4416:9;4407:7;4403:23;4399:32;4396:119;;;4434:79;;:::i;:::-;4396:119;4554:1;4579:53;4624:7;4615:6;4604:9;4600:22;4579:53;:::i;:::-;4569:63;;4525:117;4681:2;4707:53;4752:7;4743:6;4732:9;4728:22;4707:53;:::i;:::-;4697:63;;4652:118;4303:474;;;;;:::o;4783:118::-;4870:24;4888:5;4870:24;:::i;:::-;4865:3;4858:37;4783:118;;:::o;4907:222::-;5000:4;5038:2;5027:9;5023:18;5015:26;;5051:71;5119:1;5108:9;5104:17;5095:6;5051:71;:::i;:::-;4907:222;;;;:::o;5135:619::-;5212:6;5220;5228;5277:2;5265:9;5256:7;5252:23;5248:32;5245:119;;;5283:79;;:::i;:::-;5245:119;5403:1;5428:53;5473:7;5464:6;5453:9;5449:22;5428:53;:::i;:::-;5418:63;;5374:117;5530:2;5556:53;5601:7;5592:6;5581:9;5577:22;5556:53;:::i;:::-;5546:63;;5501:118;5658:2;5684:53;5729:7;5720:6;5709:9;5705:22;5684:53;:::i;:::-;5674:63;;5629:118;5135:619;;;;;:::o;5760:117::-;5869:1;5866;5859:12;5883:117;5992:1;5989;5982:12;6006:180;6054:77;6051:1;6044:88;6151:4;6148:1;6141:15;6175:4;6172:1;6165:15;6192:281;6275:27;6297:4;6275:27;:::i;:::-;6267:6;6263:40;6405:6;6393:10;6390:22;6369:18;6357:10;6354:34;6351:62;6348:88;;;6416:18;;:::i;:::-;6348:88;6456:10;6452:2;6445:22;6235:238;6192:281;;:::o;6479:129::-;6513:6;6540:20;;:::i;:::-;6530:30;;6569:33;6597:4;6589:6;6569:33;:::i;:::-;6479:129;;;:::o;6614:308::-;6676:4;6766:18;6758:6;6755:30;6752:56;;;6788:18;;:::i;:::-;6752:56;6826:29;6848:6;6826:29;:::i;:::-;6818:37;;6910:4;6904;6900:15;6892:23;;6614:308;;;:::o;6928:148::-;7026:6;7021:3;7016;7003:30;7067:1;7058:6;7053:3;7049:16;7042:27;6928:148;;;:::o;7082:425::-;7160:5;7185:66;7201:49;7243:6;7201:49;:::i;:::-;7185:66;:::i;:::-;7176:75;;7274:6;7267:5;7260:21;7312:4;7305:5;7301:16;7350:3;7341:6;7336:3;7332:16;7329:25;7326:112;;;7357:79;;:::i;:::-;7326:112;7447:54;7494:6;7489:3;7484;7447:54;:::i;:::-;7166:341;7082:425;;;;;:::o;7527:340::-;7583:5;7632:3;7625:4;7617:6;7613:17;7609:27;7599:122;;7640:79;;:::i;:::-;7599:122;7757:6;7744:20;7782:79;7857:3;7849:6;7842:4;7834:6;7830:17;7782:79;:::i;:::-;7773:88;;7589:278;7527:340;;;;:::o;7873:509::-;7942:6;7991:2;7979:9;7970:7;7966:23;7962:32;7959:119;;;7997:79;;:::i;:::-;7959:119;8145:1;8134:9;8130:17;8117:31;8175:18;8167:6;8164:30;8161:117;;;8197:79;;:::i;:::-;8161:117;8302:63;8357:7;8348:6;8337:9;8333:22;8302:63;:::i;:::-;8292:73;;8088:287;7873:509;;;;:::o;8388:311::-;8465:4;8555:18;8547:6;8544:30;8541:56;;;8577:18;;:::i;:::-;8541:56;8627:4;8619:6;8615:17;8607:25;;8687:4;8681;8677:15;8669:23;;8388:311;;;:::o;8705:117::-;8814:1;8811;8804:12;8845:710;8941:5;8966:81;8982:64;9039:6;8982:64;:::i;:::-;8966:81;:::i;:::-;8957:90;;9067:5;9096:6;9089:5;9082:21;9130:4;9123:5;9119:16;9112:23;;9183:4;9175:6;9171:17;9163:6;9159:30;9212:3;9204:6;9201:15;9198:122;;;9231:79;;:::i;:::-;9198:122;9346:6;9329:220;9363:6;9358:3;9355:15;9329:220;;;9438:3;9467:37;9500:3;9488:10;9467:37;:::i;:::-;9462:3;9455:50;9534:4;9529:3;9525:14;9518:21;;9405:144;9389:4;9384:3;9380:14;9373:21;;9329:220;;;9333:21;8947:608;;8845:710;;;;;:::o;9578:370::-;9649:5;9698:3;9691:4;9683:6;9679:17;9675:27;9665:122;;9706:79;;:::i;:::-;9665:122;9823:6;9810:20;9848:94;9938:3;9930:6;9923:4;9915:6;9911:17;9848:94;:::i;:::-;9839:103;;9655:293;9578:370;;;;:::o;9954:311::-;10031:4;10121:18;10113:6;10110:30;10107:56;;;10143:18;;:::i;:::-;10107:56;10193:4;10185:6;10181:17;10173:25;;10253:4;10247;10243:15;10235:23;;9954:311;;;:::o;10288:710::-;10384:5;10409:81;10425:64;10482:6;10425:64;:::i;:::-;10409:81;:::i;:::-;10400:90;;10510:5;10539:6;10532:5;10525:21;10573:4;10566:5;10562:16;10555:23;;10626:4;10618:6;10614:17;10606:6;10602:30;10655:3;10647:6;10644:15;10641:122;;;10674:79;;:::i;:::-;10641:122;10789:6;10772:220;10806:6;10801:3;10798:15;10772:220;;;10881:3;10910:37;10943:3;10931:10;10910:37;:::i;:::-;10905:3;10898:50;10977:4;10972:3;10968:14;10961:21;;10848:144;10832:4;10827:3;10823:14;10816:21;;10772:220;;;10776:21;10390:608;;10288:710;;;;;:::o;11021:370::-;11092:5;11141:3;11134:4;11126:6;11122:17;11118:27;11108:122;;11149:79;;:::i;:::-;11108:122;11266:6;11253:20;11291:94;11381:3;11373:6;11366:4;11358:6;11354:17;11291:94;:::i;:::-;11282:103;;11098:293;11021:370;;;;:::o;11397:894::-;11515:6;11523;11572:2;11560:9;11551:7;11547:23;11543:32;11540:119;;;11578:79;;:::i;:::-;11540:119;11726:1;11715:9;11711:17;11698:31;11756:18;11748:6;11745:30;11742:117;;;11778:79;;:::i;:::-;11742:117;11883:78;11953:7;11944:6;11933:9;11929:22;11883:78;:::i;:::-;11873:88;;11669:302;12038:2;12027:9;12023:18;12010:32;12069:18;12061:6;12058:30;12055:117;;;12091:79;;:::i;:::-;12055:117;12196:78;12266:7;12257:6;12246:9;12242:22;12196:78;:::i;:::-;12186:88;;11981:303;11397:894;;;;;:::o;12297:329::-;12356:6;12405:2;12393:9;12384:7;12380:23;12376:32;12373:119;;;12411:79;;:::i;:::-;12373:119;12531:1;12556:53;12601:7;12592:6;12581:9;12577:22;12556:53;:::i;:::-;12546:63;;12502:117;12297:329;;;;:::o;12632:116::-;12702:21;12717:5;12702:21;:::i;:::-;12695:5;12692:32;12682:60;;12738:1;12735;12728:12;12682:60;12632:116;:::o;12754:133::-;12797:5;12835:6;12822:20;12813:29;;12851:30;12875:5;12851:30;:::i;:::-;12754:133;;;;:::o;12893:468::-;12958:6;12966;13015:2;13003:9;12994:7;12990:23;12986:32;12983:119;;;13021:79;;:::i;:::-;12983:119;13141:1;13166:53;13211:7;13202:6;13191:9;13187:22;13166:53;:::i;:::-;13156:63;;13112:117;13268:2;13294:50;13336:7;13327:6;13316:9;13312:22;13294:50;:::i;:::-;13284:60;;13239:115;12893:468;;;;;:::o;13367:307::-;13428:4;13518:18;13510:6;13507:30;13504:56;;;13540:18;;:::i;:::-;13504:56;13578:29;13600:6;13578:29;:::i;:::-;13570:37;;13662:4;13656;13652:15;13644:23;;13367:307;;;:::o;13680:423::-;13757:5;13782:65;13798:48;13839:6;13798:48;:::i;:::-;13782:65;:::i;:::-;13773:74;;13870:6;13863:5;13856:21;13908:4;13901:5;13897:16;13946:3;13937:6;13932:3;13928:16;13925:25;13922:112;;;13953:79;;:::i;:::-;13922:112;14043:54;14090:6;14085:3;14080;14043:54;:::i;:::-;13763:340;13680:423;;;;;:::o;14122:338::-;14177:5;14226:3;14219:4;14211:6;14207:17;14203:27;14193:122;;14234:79;;:::i;:::-;14193:122;14351:6;14338:20;14376:78;14450:3;14442:6;14435:4;14427:6;14423:17;14376:78;:::i;:::-;14367:87;;14183:277;14122:338;;;;:::o;14466:943::-;14561:6;14569;14577;14585;14634:3;14622:9;14613:7;14609:23;14605:33;14602:120;;;14641:79;;:::i;:::-;14602:120;14761:1;14786:53;14831:7;14822:6;14811:9;14807:22;14786:53;:::i;:::-;14776:63;;14732:117;14888:2;14914:53;14959:7;14950:6;14939:9;14935:22;14914:53;:::i;:::-;14904:63;;14859:118;15016:2;15042:53;15087:7;15078:6;15067:9;15063:22;15042:53;:::i;:::-;15032:63;;14987:118;15172:2;15161:9;15157:18;15144:32;15203:18;15195:6;15192:30;15189:117;;;15225:79;;:::i;:::-;15189:117;15330:62;15384:7;15375:6;15364:9;15360:22;15330:62;:::i;:::-;15320:72;;15115:287;14466:943;;;;;;;:::o;15415:474::-;15483:6;15491;15540:2;15528:9;15519:7;15515:23;15511:32;15508:119;;;15546:79;;:::i;:::-;15508:119;15666:1;15691:53;15736:7;15727:6;15716:9;15712:22;15691:53;:::i;:::-;15681:63;;15637:117;15793:2;15819:53;15864:7;15855:6;15844:9;15840:22;15819:53;:::i;:::-;15809:63;;15764:118;15415:474;;;;;:::o;15895:180::-;15943:77;15940:1;15933:88;16040:4;16037:1;16030:15;16064:4;16061:1;16054:15;16081:320;16125:6;16162:1;16156:4;16152:12;16142:22;;16209:1;16203:4;16199:12;16230:18;16220:81;;16286:4;16278:6;16274:17;16264:27;;16220:81;16348:2;16340:6;16337:14;16317:18;16314:38;16311:84;;16367:18;;:::i;:::-;16311:84;16132:269;16081:320;;;:::o;16407:141::-;16456:4;16479:3;16471:11;;16502:3;16499:1;16492:14;16536:4;16533:1;16523:18;16515:26;;16407:141;;;:::o;16554:93::-;16591:6;16638:2;16633;16626:5;16622:14;16618:23;16608:33;;16554:93;;;:::o;16653:107::-;16697:8;16747:5;16741:4;16737:16;16716:37;;16653:107;;;;:::o;16766:393::-;16835:6;16885:1;16873:10;16869:18;16908:97;16938:66;16927:9;16908:97;:::i;:::-;17026:39;17056:8;17045:9;17026:39;:::i;:::-;17014:51;;17098:4;17094:9;17087:5;17083:21;17074:30;;17147:4;17137:8;17133:19;17126:5;17123:30;17113:40;;16842:317;;16766:393;;;;;:::o;17165:60::-;17193:3;17214:5;17207:12;;17165:60;;;:::o;17231:142::-;17281:9;17314:53;17332:34;17341:24;17359:5;17341:24;:::i;:::-;17332:34;:::i;:::-;17314:53;:::i;:::-;17301:66;;17231:142;;;:::o;17379:75::-;17422:3;17443:5;17436:12;;17379:75;;;:::o;17460:269::-;17570:39;17601:7;17570:39;:::i;:::-;17631:91;17680:41;17704:16;17680:41;:::i;:::-;17672:6;17665:4;17659:11;17631:91;:::i;:::-;17625:4;17618:105;17536:193;17460:269;;;:::o;17735:73::-;17780:3;17735:73;:::o;17814:189::-;17891:32;;:::i;:::-;17932:65;17990:6;17982;17976:4;17932:65;:::i;:::-;17867:136;17814:189;;:::o;18009:186::-;18069:120;18086:3;18079:5;18076:14;18069:120;;;18140:39;18177:1;18170:5;18140:39;:::i;:::-;18113:1;18106:5;18102:13;18093:22;;18069:120;;;18009:186;;:::o;18201:543::-;18302:2;18297:3;18294:11;18291:446;;;18336:38;18368:5;18336:38;:::i;:::-;18420:29;18438:10;18420:29;:::i;:::-;18410:8;18406:44;18603:2;18591:10;18588:18;18585:49;;;18624:8;18609:23;;18585:49;18647:80;18703:22;18721:3;18703:22;:::i;:::-;18693:8;18689:37;18676:11;18647:80;:::i;:::-;18306:431;;18291:446;18201:543;;;:::o;18750:117::-;18804:8;18854:5;18848:4;18844:16;18823:37;;18750:117;;;;:::o;18873:169::-;18917:6;18950:51;18998:1;18994:6;18986:5;18983:1;18979:13;18950:51;:::i;:::-;18946:56;19031:4;19025;19021:15;19011:25;;18924:118;18873:169;;;;:::o;19047:295::-;19123:4;19269:29;19294:3;19288:4;19269:29;:::i;:::-;19261:37;;19331:3;19328:1;19324:11;19318:4;19315:21;19307:29;;19047:295;;;;:::o;19347:1395::-;19464:37;19497:3;19464:37;:::i;:::-;19566:18;19558:6;19555:30;19552:56;;;19588:18;;:::i;:::-;19552:56;19632:38;19664:4;19658:11;19632:38;:::i;:::-;19717:67;19777:6;19769;19763:4;19717:67;:::i;:::-;19811:1;19835:4;19822:17;;19867:2;19859:6;19856:14;19884:1;19879:618;;;;20541:1;20558:6;20555:77;;;20607:9;20602:3;20598:19;20592:26;20583:35;;20555:77;20658:67;20718:6;20711:5;20658:67;:::i;:::-;20652:4;20645:81;20514:222;19849:887;;19879:618;19931:4;19927:9;19919:6;19915:22;19965:37;19997:4;19965:37;:::i;:::-;20024:1;20038:208;20052:7;20049:1;20046:14;20038:208;;;20131:9;20126:3;20122:19;20116:26;20108:6;20101:42;20182:1;20174:6;20170:14;20160:24;;20229:2;20218:9;20214:18;20201:31;;20075:4;20072:1;20068:12;20063:17;;20038:208;;;20274:6;20265:7;20262:19;20259:179;;;20332:9;20327:3;20323:19;20317:26;20375:48;20417:4;20409:6;20405:17;20394:9;20375:48;:::i;:::-;20367:6;20360:64;20282:156;20259:179;20484:1;20480;20472:6;20468:14;20464:22;20458:4;20451:36;19886:611;;;19849:887;;19439:1303;;;19347:1395;;:::o;20748:180::-;20796:77;20793:1;20786:88;20893:4;20890:1;20883:15;20917:4;20914:1;20907:15;20934:170;21074:22;21070:1;21062:6;21058:14;21051:46;20934:170;:::o;21110:366::-;21252:3;21273:67;21337:2;21332:3;21273:67;:::i;:::-;21266:74;;21349:93;21438:3;21349:93;:::i;:::-;21467:2;21462:3;21458:12;21451:19;;21110:366;;;:::o;21482:419::-;21648:4;21686:2;21675:9;21671:18;21663:26;;21735:9;21729:4;21725:20;21721:1;21710:9;21706:17;21699:47;21763:131;21889:4;21763:131;:::i;:::-;21755:139;;21482:419;;;:::o;21907:169::-;22047:21;22043:1;22035:6;22031:14;22024:45;21907:169;:::o;22082:366::-;22224:3;22245:67;22309:2;22304:3;22245:67;:::i;:::-;22238:74;;22321:93;22410:3;22321:93;:::i;:::-;22439:2;22434:3;22430:12;22423:19;;22082:366;;;:::o;22454:419::-;22620:4;22658:2;22647:9;22643:18;22635:26;;22707:9;22701:4;22697:20;22693:1;22682:9;22678:17;22671:47;22735:131;22861:4;22735:131;:::i;:::-;22727:139;;22454:419;;;:::o;22879:164::-;23019:16;23015:1;23007:6;23003:14;22996:40;22879:164;:::o;23049:366::-;23191:3;23212:67;23276:2;23271:3;23212:67;:::i;:::-;23205:74;;23288:93;23377:3;23288:93;:::i;:::-;23406:2;23401:3;23397:12;23390:19;;23049:366;;;:::o;23421:419::-;23587:4;23625:2;23614:9;23610:18;23602:26;;23674:9;23668:4;23664:20;23660:1;23649:9;23645:17;23638:47;23702:131;23828:4;23702:131;:::i;:::-;23694:139;;23421:419;;;:::o;23846:180::-;23894:77;23891:1;23884:88;23991:4;23988:1;23981:15;24015:4;24012:1;24005:15;24032:191;24072:3;24091:20;24109:1;24091:20;:::i;:::-;24086:25;;24125:20;24143:1;24125:20;:::i;:::-;24120:25;;24168:1;24165;24161:9;24154:16;;24189:3;24186:1;24183:10;24180:36;;;24196:18;;:::i;:::-;24180:36;24032:191;;;;:::o;24229:159::-;24369:11;24365:1;24357:6;24353:14;24346:35;24229:159;:::o;24394:365::-;24536:3;24557:66;24621:1;24616:3;24557:66;:::i;:::-;24550:73;;24632:93;24721:3;24632:93;:::i;:::-;24750:2;24745:3;24741:12;24734:19;;24394:365;;;:::o;24765:419::-;24931:4;24969:2;24958:9;24954:18;24946:26;;25018:9;25012:4;25008:20;25004:1;24993:9;24989:17;24982:47;25046:131;25172:4;25046:131;:::i;:::-;25038:139;;24765:419;;;:::o;25190:410::-;25230:7;25253:20;25271:1;25253:20;:::i;:::-;25248:25;;25287:20;25305:1;25287:20;:::i;:::-;25282:25;;25342:1;25339;25335:9;25364:30;25382:11;25364:30;:::i;:::-;25353:41;;25543:1;25534:7;25530:15;25527:1;25524:22;25504:1;25497:9;25477:83;25454:139;;25573:18;;:::i;:::-;25454:139;25238:362;25190:410;;;;:::o;25606:170::-;25746:22;25742:1;25734:6;25730:14;25723:46;25606:170;:::o;25782:366::-;25924:3;25945:67;26009:2;26004:3;25945:67;:::i;:::-;25938:74;;26021:93;26110:3;26021:93;:::i;:::-;26139:2;26134:3;26130:12;26123:19;;25782:366;;;:::o;26154:419::-;26320:4;26358:2;26347:9;26343:18;26335:26;;26407:9;26401:4;26397:20;26393:1;26382:9;26378:17;26371:47;26435:131;26561:4;26435:131;:::i;:::-;26427:139;;26154:419;;;:::o;26579:148::-;26681:11;26718:3;26703:18;;26579:148;;;;:::o;26733:390::-;26839:3;26867:39;26900:5;26867:39;:::i;:::-;26922:89;27004:6;26999:3;26922:89;:::i;:::-;26915:96;;27020:65;27078:6;27073:3;27066:4;27059:5;27055:16;27020:65;:::i;:::-;27110:6;27105:3;27101:16;27094:23;;26843:280;26733:390;;;;:::o;27129:435::-;27309:3;27331:95;27422:3;27413:6;27331:95;:::i;:::-;27324:102;;27443:95;27534:3;27525:6;27443:95;:::i;:::-;27436:102;;27555:3;27548:10;;27129:435;;;;;:::o;27570:171::-;27609:3;27632:24;27650:5;27632:24;:::i;:::-;27623:33;;27678:4;27671:5;27668:15;27665:41;;27686:18;;:::i;:::-;27665:41;27733:1;27726:5;27722:13;27715:20;;27570:171;;;:::o;27747:98::-;27798:6;27832:5;27826:12;27816:22;;27747:98;;;:::o;27851:168::-;27934:11;27968:6;27963:3;27956:19;28008:4;28003:3;27999:14;27984:29;;27851:168;;;;:::o;28025:373::-;28111:3;28139:38;28171:5;28139:38;:::i;:::-;28193:70;28256:6;28251:3;28193:70;:::i;:::-;28186:77;;28272:65;28330:6;28325:3;28318:4;28311:5;28307:16;28272:65;:::i;:::-;28362:29;28384:6;28362:29;:::i;:::-;28357:3;28353:39;28346:46;;28115:283;28025:373;;;;:::o;28404:640::-;28599:4;28637:3;28626:9;28622:19;28614:27;;28651:71;28719:1;28708:9;28704:17;28695:6;28651:71;:::i;:::-;28732:72;28800:2;28789:9;28785:18;28776:6;28732:72;:::i;:::-;28814;28882:2;28871:9;28867:18;28858:6;28814:72;:::i;:::-;28933:9;28927:4;28923:20;28918:2;28907:9;28903:18;28896:48;28961:76;29032:4;29023:6;28961:76;:::i;:::-;28953:84;;28404:640;;;;;;;:::o;29050:141::-;29106:5;29137:6;29131:13;29122:22;;29153:32;29179:5;29153:32;:::i;:::-;29050:141;;;;:::o;29197:349::-;29266:6;29315:2;29303:9;29294:7;29290:23;29286:32;29283:119;;;29321:79;;:::i;:::-;29283:119;29441:1;29466:63;29521:7;29512:6;29501:9;29497:22;29466:63;:::i;:::-;29456:73;;29412:127;29197:349;;;;:::o
Swarm Source
ipfs://8bc1cdc65f0a74995ac1a88d286fdf5408e5b979e9b13595040940d2b58b0e76
[ 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.