ERC-721
NFT
Overview
Max Total Supply
10,000 FDS
Holders
1,755
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
7 FDSLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
MainFD
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-12-28 */ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.4; interface IOperatorFilterRegistry { function isOperatorAllowed(address registrant, address operator) external view returns (bool); function register(address registrant) external; function registerAndSubscribe(address registrant, address subscription) external; function registerAndCopyEntries(address registrant, address registrantToCopy) external; function unregister(address addr) external; function updateOperator(address registrant, address operator, bool filtered) external; function updateOperators(address registrant, address[] calldata operators, bool filtered) external; function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external; function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external; function subscribe(address registrant, address registrantToSubscribe) external; function unsubscribe(address registrant, bool copyExistingEntries) external; function subscriptionOf(address addr) external returns (address registrant); function subscribers(address registrant) external returns (address[] memory); function subscriberAt(address registrant, uint256 index) external returns (address); function copyEntriesOf(address registrant, address registrantToCopy) external; function isOperatorFiltered(address registrant, address operator) external returns (bool); function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool); function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool); function filteredOperators(address addr) external returns (address[] memory); function filteredCodeHashes(address addr) external returns (bytes32[] memory); function filteredOperatorAt(address registrant, uint256 index) external returns (address); function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32); function isRegistered(address addr) external returns (bool); function codeHashOf(address addr) external returns (bytes32); } /** * @title OperatorFilterer * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another * registrant's entries in the OperatorFilterRegistry. * @dev This smart contract is meant to be inherited by token contracts so they can use the following: * - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods. * - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods. */ abstract contract OperatorFilterer { error OperatorNotAllowed(address operator); IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); constructor(address subscriptionOrRegistrantToCopy, bool subscribe) { // If an inheriting token contract is deployed to a network without the registry deployed, the modifier // will not revert, but the contract will need to be registered with the registry once it is deployed in // order for the modifier to filter addresses. if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { if (subscribe) { OPERATOR_FILTER_REGISTRY.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy); } else { if (subscriptionOrRegistrantToCopy != address(0)) { OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy); } else { OPERATOR_FILTER_REGISTRY.register(address(this)); } } } } modifier onlyAllowedOperator(address from) virtual { // Allow spending tokens from addresses with balance // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred // from an EOA. if (from != msg.sender) { _checkFilterOperator(msg.sender); } _; } modifier onlyAllowedOperatorApproval(address operator) virtual { _checkFilterOperator(operator); _; } function _checkFilterOperator(address operator) internal view virtual { // Check registry code length to facilitate testing in environments without a deployed registry. if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) { revert OperatorNotAllowed(operator); } } } } /** * @title DefaultOperatorFilterer * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription. */ abstract contract DefaultOperatorFilterer is OperatorFilterer { address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {} } /** * @dev Interface of ERC721A. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables * (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, * checking first that contract recipients are aware of the ERC721 protocol * to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move * this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external payable; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Transfers `tokenId` from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} * whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external payable; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) external view returns (bool); // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to); } /** * @dev Interface of ERC721 token receiver. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC721A * * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721) * Non-Fungible Token Standard, including the Metadata extension. * Optimized for lower gas during batch mints. * * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...) * starting from `_startTokenId()`. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364). struct TokenApprovalRef { address value; } // ============================================================= // CONSTANTS // ============================================================= // Mask of an entry in packed address data. uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant _BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant _BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant _BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant _BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant _BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant _BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225; // The bit position of `extraData` in packed ownership. uint256 private constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with {_mintERC2309}. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309} // is required to cause an overflow, which is unrealistic. uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // ============================================================= // STORAGE // ============================================================= // The next token ID to be minted. uint256 private _currentIndex; // The number of tokens burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See {_packedOwnershipOf} implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => TokenApprovalRef) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // ============================================================= // CONSTRUCTOR // ============================================================= constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); } // ============================================================= // TOKEN COUNTING OPERATIONS // ============================================================= /** * @dev Returns the starting token ID. * To change the starting token ID, please override this function. */ function _startTokenId() internal view virtual returns (uint256) { return 1; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view virtual returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() public view virtual override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than `_currentIndex - _startTokenId()` times. unchecked { return _currentIndex - _burnCounter - _startTokenId(); } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view virtual returns (uint256) { // Counter underflow is impossible as `_currentIndex` does not decrement, // and it is initialized to `_startTokenId()`. unchecked { return _currentIndex - _startTokenId(); } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return _burnCounter; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(0)) revert BalanceQueryForZeroAddress(); return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes // of the XOR of all function selectors in the interface. // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165) // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`) return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ''; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) { uint256 curr = tokenId; unchecked { if (_startTokenId() <= curr) if (curr < _currentIndex) { uint256 packed = _packedOwnerships[curr]; // If not burned. if (packed & _BITMASK_BURNED == 0) { // Invariant: // There will always be an initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `curr` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. while (packed == 0) { packed = _packedOwnerships[--curr]; } return packed; } } } revert OwnerQueryForNonexistentToken(); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags)) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) public payable virtual override { address owner = ownerOf(tokenId); if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } _tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId].value; } /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) public virtual override { _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _startTokenId() <= tokenId && tokenId < _currentIndex && // If within bounds, _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned. } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].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); if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner(); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); if (to == address(0)) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public 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(); } } /** * @dev Hook that is called before a set of serially-ordered token IDs * are about to be transferred. This includes minting. * And also called before burning one token. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token IDs * have been transferred. This includes minting. * And also called after one token has been burned. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns whether the call correctly returned the expected magic value. */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns ( bytes4 retval ) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); uint256 toMasked; uint256 end = startTokenId + quantity; // Use assembly to loop and emit the `Transfer` event for gas savings. // The duplicated `log4` removes an extra check and reduces stack juggling. // The assembly, together with the surrounding Solidity code, have been // delicately arranged to nudge the compiler into producing optimized opcodes. assembly { // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. toMasked := and(to, _BITMASK_ADDRESS) // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. startTokenId // `tokenId`. ) // The `iszero(eq(,))` check ensures that large values of `quantity` // that overflows uint256 will make the loop run out of gas. // The compiler will optimize the `iszero` away for performance. for { let tokenId := add(startTokenId, 1) } iszero(eq(tokenId, end)) { tokenId := add(tokenId, 1) } { // Emit the `Transfer` event. Similar to above. log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId) } } if (toMasked == 0) revert MintToZeroAddress(); _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to); _currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = _currentIndex; uint256 index = end - quantity; do { if (!_checkContractOnERC721Received(address(0), to, index++, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } while (index < end); // Reentrancy protection. if (_currentIndex != end) revert(); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ''); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { _burnCounter++; } } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) revert OwnershipNotInitializedForExtraData(); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory 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 These functions deal with verification of Merkle Tree proofs. * * The tree and the proofs can be generated using our * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. * You will find a quickstart guide in the readme. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the merkle tree could be reinterpreted as a leaf value. * OpenZeppelin's JavaScript library generates merkle trees that are safe * against this attack out of the box. */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify( bytes32[] memory proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} * * _Available since v4.7._ */ function verifyCalldata( bytes32[] calldata proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _Available since v4.4._ */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} * * _Available since v4.7._ */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). * * _Available since v4.7._ */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } } /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } } /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } interface IEIP2981 { /// ERC165 bytes to add to interface array - set in parent contract /// implementing this standard /// /// bytes4(keccak256("royaltyInfo(uint256,uint256)")) == 0x2a55205a /// @notice Called with the sale price to determine how much royalty // is owed and to whom. /// @param _tokenId - the NFT asset queried for royalty information /// @param _salePrice - the sale price of the NFT asset specified by _tokenId /// @return receiver - address of who should be sent the royalty payment /// @return royaltyAmount - the royalty payment amount for _salePrice function royaltyInfo(uint256 _tokenId, uint256 _salePrice) external view returns (address receiver,uint256 royaltyAmount); } interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } contract AnleiUtils { using Strings for uint256; event Log(string); function random(uint number) public view returns(uint) { return uint(keccak256(abi.encodePacked(block.timestamp,block.difficulty, msg.sender))) % number; } function addressArrayEq(address[] memory arr, address addr) internal pure returns(string memory) { for(uint256 i=0; i<arr.length; i++) { if(arr[i] == addr) { return i.toString(); } } return "-1"; } function isEqual(string memory a, string memory b) public pure returns (bool) { bytes memory aa = bytes(a); bytes memory bb = bytes(b); // 如果长度不等,直接返回 if (aa.length != bb.length) return false; // 按位比较 for(uint i = 0; i < aa.length; i ++) { if(aa[i] != bb[i]) return false; } return true; } function parseInt(string memory _a) internal pure returns (uint _parsedInt) { return parseInt(_a, 0); } function parseInt(string memory _a, uint _b) internal pure returns (uint _parsedInt) { bytes memory bresult = bytes(_a); uint mint = 0; bool decimals = false; for (uint i = 0; i < bresult.length; i++) { if ((uint(uint8(bresult[i])) >= 48) && (uint(uint8(bresult[i])) <= 57)) { if (decimals) { if (_b == 0) { break; } else { _b--; } } mint *= 10; mint += uint(uint8(bresult[i])) - 48; } else if (uint(uint8(bresult[i])) == 46) { decimals = true; } } if (_b > 0) { mint *= 10 ** _b; } return mint; } /* function uint2str(uint _i) internal pure returns (string memory _uintAsString) { if (_i == 0) { return "0"; } uint j = _i; uint len; while (j != 0) { len++; j /= 10; } bytes memory bstr = new bytes(len); uint k = len - 1; while (_i != 0) { bstr[k--] = bytes1(uint8(48 + _i % 10)); _i /= 10; } return string(bstr); } function strConcat(string memory _a, string memory _b) internal pure returns (string memory _concatenatedString) { return strConcat(_a, _b, "", "", ""); } function strConcat(string memory _a, string memory _b, string memory _c) internal pure returns (string memory _concatenatedString) { return strConcat(_a, _b, _c, "", ""); } function strConcat(string memory _a, string memory _b, string memory _c, string memory _d) internal pure returns (string memory _concatenatedString) { return strConcat(_a, _b, _c, _d, ""); } function strConcat(string memory _a, string memory _b, string memory _c, string memory _d, string memory _e) internal pure returns (string memory _concatenatedString) { bytes memory _ba = bytes(_a); bytes memory _bb = bytes(_b); bytes memory _bc = bytes(_c); bytes memory _bd = bytes(_d); bytes memory _be = bytes(_e); string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length); bytes memory babcde = bytes(abcde); uint k = 0; uint i = 0; for (i = 0; i < _ba.length; i++) { babcde[k++] = _ba[i]; } for (i = 0; i < _bb.length; i++) { babcde[k++] = _bb[i]; } for (i = 0; i < _bc.length; i++) { babcde[k++] = _bc[i]; } for (i = 0; i < _bd.length; i++) { babcde[k++] = _bd[i]; } for (i = 0; i < _be.length; i++) { babcde[k++] = _be[i]; } return string(babcde); } */ } abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } abstract contract EIP2981AllToken is IEIP2981, ERC165 { address internal _royaltyAddr; uint256 internal _royaltyPerc; // percentage in basis (out of 10,000) /** * @param recipient is the royalty recipient * @param percentage is the royalty percentage */ constructor(address recipient, uint256 percentage) { _setRoyaltyInfo(recipient, percentage); } /** * @notice EIP 2981 royalty support * @dev royalty amount not dependent on _tokenId */ function royaltyInfo(uint256 _tokenId, uint256 _salePrice) external view virtual override returns (address receiver, uint256 royaltyAmount) { return (_royaltyAddr, _royaltyPerc * _salePrice / 10000); } /** * @notice override ERC 165 implementation of this function * @dev if using this contract with another contract that suppports ERC 265, will have to override in the inheriting contract */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165) returns (bool) { return interfaceId == type(IEIP2981).interfaceId || super.supportsInterface(interfaceId); } /** * @notice function to set royalty information * @dev to be called by inheriting contract * @param addr is the royalty payout address for this token id * @param perc is the royalty percentage (out of 10,000) to set for this token id */ function _setRoyaltyInfo(address addr, uint256 perc) internal virtual { require(addr != address(0), "EIP2981AllToken: Cannot set royalty receipient to the zero address"); require(perc < 10000, "EIP2981AllToken: Cannot set royalty percentage above 10000"); _royaltyAddr = addr; _royaltyPerc = perc; } } contract OwnerBase { address public owner; constructor(){ owner = msg.sender; } modifier onlyOwner { require(msg.sender == owner); _; } } contract PayAbstruct is OwnerBase { constructor() { } ////// ////// Pay ////// ////// //pay eth to this /*function paytocontract() external payable { }*/ //this eth to owner function withdraw() onlyOwner external payable { payable(msg.sender).transfer(address(this).balance); } //get eth total function getBalance() public view returns(uint256 num) { return address(this).balance; } /* function withdraw2(address to) public onlyOwner payable{ uint256 balance = address(this).balance; payable(to).transfer(balance); }*/ } contract NFTClass is ERC721A,EIP2981AllToken,OwnerBase,PayAbstruct,DefaultOperatorFilterer { using Strings for uint256; //NFT json head url string private IPFS_URL = "https://nftstorage.link/ipfs/bafybeif6fnkyl4ku2ymuxezc55km2d7hin6oeyi4catmwfnsrvbhm3v644/"; //Mint param uint256 public MAX_SUPPLY = 8888;//total number uint256 public USER_LIMIT = 2;//user mint total //uint256 public Mint_Price = 0.008 ether; uint256 public Mint_Price_normal = 0.008 ether; uint256 public Mint_Price_wl = 0.003 ether; //white list root - need pay eth bytes32 public merkleRoot_wlValue = 0x16858b4922a790eed48063950aba13c87bdf99655bebe69dfcb34ace38c66d70; //white list root - free bytes32 public merkleRoot_wlFree = 0x3e3e5716f9628f37b1a844c398168372cd96a1043377fc3b6051a452acf77e4e; //true = open wl time bool public whitelist_switch = true; bool private isAirdrop = false; //open blind //bool public isOpenBlind = false;//true = open blind //string public Blind_JSON_URL = "https://bafybeiheymbs6ze7nra3pgwahe2zifq4374v2j3v2zztqdbcufwwxgzppy.ipfs.nftstorage.link/FashionDucksBlindbox.json"; constructor( address royaltyPayout, uint256 royaltyPerc, string memory nft_name, string memory nft_symbol ) ERC721A(nft_name, nft_symbol) EIP2981AllToken(royaltyPayout, royaltyPerc) { //setNFTClass(this); } ////// ////// NFT ////// ////// function verify_wlValue(bytes32[] memory proof) public view returns(bool result) { bytes32 leaf = keccak256(abi.encodePacked(msg.sender)); return MerkleProof.verify(proof, merkleRoot_wlValue, leaf); } function verify_wlFree(bytes32[] memory proof) public view returns(bool result) { bytes32 leaf = keccak256(abi.encodePacked(msg.sender)); return MerkleProof.verify(proof, merkleRoot_wlFree, leaf); } // function getPokerList(address addr) public view returns(uint256[] memory) { uint256[] memory arr = new uint256[](balanceOf(addr)); uint256 len = totalSupply(); uint256 j=0; for (uint256 i = _startTokenId(); i <= len; i++) { if (ownerOf(i) == addr) { arr[j++] = i; } } return arr; } //mint after /*function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual override { //owner not play game if(owner != to) { for(uint256 i=startTokenId; i<startTokenId+quantity; i++) { createPoker(to, i); } } }*/ //user mint function mint(uint256 quantity, bytes32[] memory proof) external payable { bool wlv = verify_wlValue(proof); bool wlf = verify_wlFree(proof); //wl onf if(whitelist_switch) { require(wlv || wlf, "white list time."); } //not wl if(!wlv && !wlf) { require(msg.value >= Mint_Price_normal * quantity, "wrong price"); } //is wl if(wlv){ require(msg.value >= Mint_Price_wl * quantity, "wrong price (wl)"); } //go to pay require(_totalMinted() + quantity <= MAX_SUPPLY, "Not more supply left"); require(_numberMinted(msg.sender) + quantity <= USER_LIMIT, "User limit reached"); //require(balanceOf(msg.sender) + quantity <= USER_LIMIT, "User limit reached"); _safeMint(msg.sender, quantity); } //owner mint function creatorMint(address minter, uint256 quantity) onlyOwner public payable { _safeMint(minter, quantity); } //airdrop my team function airdrop() onlyOwner public payable { require(isAirdrop == false); _safeMint(owner, 300); isAirdrop = true; } //function _baseURI() internal view virtual returns (string memory) { function _baseURI() internal view virtual override returns (string memory) { return IPFS_URL; } //return json file to platform function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { //if not open blind, return cover gif. /*if(isOpenBlind == false){ return Blind_JSON_URL; }*/ //if open blind, return nft png. require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory currentBaseURI = _baseURI(); return bytes(currentBaseURI).length > 0 ? string(abi.encodePacked(currentBaseURI, tokenId.toString(), ".json")) : ""; } ////// ////// setting ////// ////// function SET_IPFS_URL(string memory uri) onlyOwner public { IPFS_URL = uri; } function SET_USER_LIMIT(uint256 val) onlyOwner public { USER_LIMIT = val; } function SET_Mint_Price_normal(uint256 val) onlyOwner public { Mint_Price_normal = val; } function SET_Mint_Price_wl(uint256 val) onlyOwner public { Mint_Price_wl = val; } function SET_MAX_SUPPLY(uint256 val) onlyOwner public { MAX_SUPPLY = val; } function SET_merkleRoot_wlValue(bytes32 val) onlyOwner public { merkleRoot_wlValue = val; } function SET_merkleRoot_wlFree(bytes32 val) onlyOwner public { merkleRoot_wlFree = val; } function SET_whitelist_switch(bool val) onlyOwner public { whitelist_switch = val; } /*function SET_OpenBlind_switch(bool val) onlyOwner public { isOpenBlind = val; } function SET_Blind_JSON_URL(string memory uri) onlyOwner public { Blind_JSON_URL = uri; }*/ //// ////opensea function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) { super.setApprovalForAll(operator, approved); } function approve(address operator, uint256 tokenId) public payable override onlyAllowedOperatorApproval(operator) { super.approve(operator, tokenId); } function transferFrom(address from, address to, uint256 tokenId) public payable override onlyAllowedOperator(from) { super.transferFrom(from, to, tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId) public payable override onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public payable override onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId, data); } ///// function setRoyaltyAddr(address addr) onlyOwner public { _royaltyAddr = addr; } // percentage in basis (out of 10,000) // -> 10000/10000=100%=1 // -> 750/10000 = 0.075*100 = 7.5% function setRoyaltyPerc(uint256 val) onlyOwner public { _royaltyPerc = val; } /// @dev see {ERC165.supportsInterface} function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721A, EIP2981AllToken) returns (bool) { return ERC721A.supportsInterface(interfaceId) || EIP2981AllToken.supportsInterface(interfaceId); } } contract MainFD is NFTClass { constructor() NFTClass(msg.sender, 750, "FashionDucks", "FDS") { } }
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":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"Mint_Price_normal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"Mint_Price_wl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"SET_IPFS_URL","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"SET_MAX_SUPPLY","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"SET_Mint_Price_normal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"SET_Mint_Price_wl","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"SET_USER_LIMIT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"val","type":"bytes32"}],"name":"SET_merkleRoot_wlFree","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"val","type":"bytes32"}],"name":"SET_merkleRoot_wlValue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"val","type":"bool"}],"name":"SET_whitelist_switch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"USER_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"airdrop","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","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":[{"internalType":"address","name":"minter","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"creatorMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBalance","outputs":[{"internalType":"uint256","name":"num","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getPokerList","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"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":"merkleRoot_wlFree","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot_wlValue","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","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":"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":"address","name":"addr","type":"address"}],"name":"setRoyaltyAddr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"val","type":"uint256"}],"name":"setRoyaltyPerc","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"verify_wlFree","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"verify_wlValue","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelist_switch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
60806040526040518060800160405280605981526020016200497160599139600b90816200002e919062000787565b506122b8600c556002600d55661c6bf526340000600e55660aa87bee538000600f557f16858b4922a790eed48063950aba13c87bdf99655bebe69dfcb34ace38c66d7060001b6010557f3e3e5716f9628f37b1a844c398168372cd96a1043377fc3b6051a452acf77e4e60001b6011556001601260006101000a81548160ff0219169083151502179055506000601260016101000a81548160ff021916908315150217905550348015620000e157600080fd5b50336102ee6040518060400160405280600c81526020017f46617368696f6e4475636b7300000000000000000000000000000000000000008152506040518060400160405280600381526020017f4644530000000000000000000000000000000000000000000000000000000000815250733cc6cdda760b79bafa08df41ecfa224f810dceb660018585858581600290816200017e919062000787565b50806003908162000190919062000787565b50620001a1620003ff60201b60201c565b6000819055505050620001bb82826200040860201b60201c565b505033600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115620003f3578015620002b9576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b81526004016200027f929190620008b3565b600060405180830381600087803b1580156200029a57600080fd5b505af1158015620002af573d6000803e3d6000fd5b50505050620003f2565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161462000373576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b815260040162000339929190620008b3565b600060405180830381600087803b1580156200035457600080fd5b505af115801562000369573d6000803e3d6000fd5b50505050620003f1565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b8152600401620003bc9190620008e0565b600060405180830381600087803b158015620003d757600080fd5b505af1158015620003ec573d6000803e3d6000fd5b505050505b5b5b50505050505062000a64565b60006001905090565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036200047a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200047190620009aa565b60405180910390fd5b6127108110620004c1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004b89062000a42565b60405180910390fd5b81600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806009819055505050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200058f57607f821691505b602082108103620005a557620005a462000547565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026200060f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620005d0565b6200061b8683620005d0565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b600062000668620006626200065c8462000633565b6200063d565b62000633565b9050919050565b6000819050919050565b620006848362000647565b6200069c62000693826200066f565b848454620005dd565b825550505050565b600090565b620006b3620006a4565b620006c081848462000679565b505050565b5b81811015620006e857620006dc600082620006a9565b600181019050620006c6565b5050565b601f82111562000737576200070181620005ab565b6200070c84620005c0565b810160208510156200071c578190505b620007346200072b85620005c0565b830182620006c5565b50505b505050565b600082821c905092915050565b60006200075c600019846008026200073c565b1980831691505092915050565b600062000777838362000749565b9150826002028217905092915050565b62000792826200050d565b67ffffffffffffffff811115620007ae57620007ad62000518565b5b620007ba825462000576565b620007c7828285620006ec565b600060209050601f831160018114620007ff5760008415620007ea578287015190505b620007f6858262000769565b86555062000866565b601f1984166200080f86620005ab565b60005b82811015620008395784890151825560018201915060208501945060208101905062000812565b8683101562000859578489015162000855601f89168262000749565b8355505b6001600288020188555050505b505050505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200089b826200086e565b9050919050565b620008ad816200088e565b82525050565b6000604082019050620008ca6000830185620008a2565b620008d96020830184620008a2565b9392505050565b6000602082019050620008f76000830184620008a2565b92915050565b600082825260208201905092915050565b7f45495032393831416c6c546f6b656e3a2043616e6e6f742073657420726f796160008201527f6c74792072656365697069656e7420746f20746865207a65726f20616464726560208201527f7373000000000000000000000000000000000000000000000000000000000000604082015250565b600062000992604283620008fd565b91506200099f826200090e565b606082019050919050565b60006020820190508181036000830152620009c58162000983565b9050919050565b7f45495032393831416c6c546f6b656e3a2043616e6e6f742073657420726f796160008201527f6c74792070657263656e746167652061626f7665203130303030000000000000602082015250565b600062000a2a603a83620008fd565b915062000a3782620009cc565b604082019050919050565b6000602082019050818103600083015262000a5d8162000a1b565b9050919050565b613efd8062000a746000396000f3fe6080604052600436106102515760003560e01c8063649a545411610139578063a87b98ad116100b6578063d13ed0251161007a578063d13ed02514610859578063ddaa2f6f14610882578063e471ae0a146108ab578063e985e9c5146108d6578063f704038c14610913578063fcd61a231461093e57610251565b8063a87b98ad14610792578063b88d4fde146107bb578063ba41b0c6146107d7578063c87b56dd146107f3578063ccea96ac1461083057610251565b80637c467166116100fd5780637c467166146106995780638da5cb5b146106d657806395d89b4114610701578063a21e49181461072c578063a22cb4651461076957610251565b8063649a5454146105a057806370a08231146105cb5780637282d833146106085780637a2eba8e146106455780637c3d495c1461067057610251565b806332aebda0116101d25780633f6b6312116101965780633f6b63121461049f57806341f43434146104ca57806342842e0e146104f557806345874017146105115780636352211e1461053a57806363f944de1461057757610251565b806332aebda01461040c57806332cb6b0c146104375780633884d63514610462578063390e81cb1461046c5780633ccfd60b1461049557610251565b806318160ddd1161021957806318160ddd14610342578063182ee4851461036d57806323b872dd1461038957806328dad116146103a55780632a55205a146103ce57610251565b806301ffc9a71461025657806306fdde0314610293578063081812fc146102be578063095ea7b3146102fb57806312065fe014610317575b600080fd5b34801561026257600080fd5b5061027d60048036038101906102789190612b3f565b610967565b60405161028a9190612b87565b60405180910390f35b34801561029f57600080fd5b506102a8610989565b6040516102b59190612c32565b60405180910390f35b3480156102ca57600080fd5b506102e560048036038101906102e09190612c8a565b610a1b565b6040516102f29190612cf8565b60405180910390f35b61031560048036038101906103109190612d3f565b610a9a565b005b34801561032357600080fd5b5061032c610ab3565b6040516103399190612d8e565b60405180910390f35b34801561034e57600080fd5b50610357610abb565b6040516103649190612d8e565b60405180910390f35b61038760048036038101906103829190612d3f565b610ad2565b005b6103a3600480360381019061039e9190612da9565b610b3a565b005b3480156103b157600080fd5b506103cc60048036038101906103c79190612c8a565b610b89565b005b3480156103da57600080fd5b506103f560048036038101906103f09190612dfc565b610bed565b604051610403929190612e3c565b60405180910390f35b34801561041857600080fd5b50610421610c39565b60405161042e9190612b87565b60405180910390f35b34801561044357600080fd5b5061044c610c4c565b6040516104599190612d8e565b60405180910390f35b61046a610c52565b005b34801561047857600080fd5b50610493600480360381019061048e9190612e9b565b610d17565b005b61049d610d7b565b005b3480156104ab57600080fd5b506104b4610e1e565b6040516104c19190612d8e565b60405180910390f35b3480156104d657600080fd5b506104df610e24565b6040516104ec9190612f27565b60405180910390f35b61050f600480360381019061050a9190612da9565b610e36565b005b34801561051d57600080fd5b5061053860048036038101906105339190612f42565b610e85565b005b34801561054657600080fd5b50610561600480360381019061055c9190612c8a565b610f23565b60405161056e9190612cf8565b60405180910390f35b34801561058357600080fd5b5061059e60048036038101906105999190612c8a565b610f35565b005b3480156105ac57600080fd5b506105b5610f99565b6040516105c29190612d8e565b60405180910390f35b3480156105d757600080fd5b506105f260048036038101906105ed9190612f42565b610f9f565b6040516105ff9190612d8e565b60405180910390f35b34801561061457600080fd5b5061062f600480360381019061062a91906130b7565b611057565b60405161063c9190612b87565b60405180910390f35b34801561065157600080fd5b5061065a611098565b604051610667919061310f565b60405180910390f35b34801561067c57600080fd5b5061069760048036038101906106929190612c8a565b61109e565b005b3480156106a557600080fd5b506106c060048036038101906106bb91906130b7565b611102565b6040516106cd9190612b87565b60405180910390f35b3480156106e257600080fd5b506106eb611143565b6040516106f89190612cf8565b60405180910390f35b34801561070d57600080fd5b50610716611169565b6040516107239190612c32565b60405180910390f35b34801561073857600080fd5b50610753600480360381019061074e9190612f42565b6111fb565b60405161076091906131e8565b60405180910390f35b34801561077557600080fd5b50610790600480360381019061078b9190613236565b6112fa565b005b34801561079e57600080fd5b506107b960048036038101906107b49190612c8a565b611313565b005b6107d560048036038101906107d0919061332b565b611377565b005b6107f160048036038101906107ec91906133ae565b6113c8565b005b3480156107ff57600080fd5b5061081a60048036038101906108159190612c8a565b6115b8565b6040516108279190612c32565b60405180910390f35b34801561083c57600080fd5b506108576004803603810190610852919061340a565b61165f565b005b34801561086557600080fd5b50610880600480360381019061087b9190612e9b565b6116d6565b005b34801561088e57600080fd5b506108a960048036038101906108a491906134d8565b61173a565b005b3480156108b757600080fd5b506108c06117a7565b6040516108cd9190612d8e565b60405180910390f35b3480156108e257600080fd5b506108fd60048036038101906108f89190613521565b6117ad565b60405161090a9190612b87565b60405180910390f35b34801561091f57600080fd5b50610928611841565b604051610935919061310f565b60405180910390f35b34801561094a57600080fd5b5061096560048036038101906109609190612c8a565b611847565b005b6000610972826118ab565b8061098257506109818261193d565b5b9050919050565b60606002805461099890613590565b80601f01602080910402602001604051908101604052809291908181526020018280546109c490613590565b8015610a115780601f106109e657610100808354040283529160200191610a11565b820191906000526020600020905b8154815290600101906020018083116109f457829003601f168201915b5050505050905090565b6000610a26826119b7565b610a5c576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610aa481611a16565b610aae8383611b13565b505050565b600047905090565b6000610ac5611c57565b6001546000540303905090565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b2c57600080fd5b610b368282611c60565b5050565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b7857610b7733611a16565b5b610b83848484611c7e565b50505050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610be357600080fd5b80600c8190555050565b600080600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661271084600954610c2491906135f0565b610c2e9190613661565b915091509250929050565b601260009054906101000a900460ff1681565b600c5481565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610cac57600080fd5b60001515601260019054906101000a900460ff16151514610ccc57600080fd5b610cfa600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661012c611c60565b6001601260016101000a81548160ff021916908315150217905550565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d7157600080fd5b8060108190555050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610dd557600080fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015610e1b573d6000803e3d6000fd5b50565b600f5481565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610e7457610e7333611a16565b5b610e7f848484611fa0565b50505050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610edf57600080fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000610f2e82611fc0565b9050919050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f8f57600080fd5b80600e8190555050565b600e5481565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611006576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6000803360405160200161106b91906136da565b604051602081830303815290604052805190602001209050611090836011548361208c565b915050919050565b60105481565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110f857600080fd5b80600f8190555050565b6000803360405160200161111691906136da565b60405160208183030381529060405280519060200120905061113b836010548361208c565b915050919050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60606003805461117890613590565b80601f01602080910402602001604051908101604052809291908181526020018280546111a490613590565b80156111f15780601f106111c6576101008083540402835291602001916111f1565b820191906000526020600020905b8154815290600101906020018083116111d457829003601f168201915b5050505050905090565b6060600061120883610f9f565b67ffffffffffffffff81111561122157611220612f74565b5b60405190808252806020026020018201604052801561124f5781602001602082028036833780820191505090505b509050600061125c610abb565b9050600080611269611c57565b90505b8281116112ee578573ffffffffffffffffffffffffffffffffffffffff1661129382610f23565b73ffffffffffffffffffffffffffffffffffffffff16036112db57808483806112bb906136f5565b9450815181106112ce576112cd61373d565b5b6020026020010181815250505b80806112e6906136f5565b91505061126c565b50829350505050919050565b8161130481611a16565b61130e83836120a3565b505050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461136d57600080fd5b8060098190555050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146113b5576113b433611a16565b5b6113c1858585856121ae565b5050505050565b60006113d382611102565b905060006113e083611057565b9050601260009054906101000a900460ff16156114405781806114005750805b61143f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611436906137b8565b60405180910390fd5b5b8115801561144c575080155b156114a25783600e5461145f91906135f0565b3410156114a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161149890613824565b60405180910390fd5b5b81156114f95783600f546114b691906135f0565b3410156114f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ef90613890565b60405180910390fd5b5b600c5484611505612221565b61150f91906138b0565b1115611550576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161154790613930565b60405180910390fd5b600d548461155d33612234565b61156791906138b0565b11156115a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159f9061399c565b60405180910390fd5b6115b23385611c60565b50505050565b60606115c3826119b7565b611602576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115f990613a2e565b60405180910390fd5b600061160c61228b565b9050600081511161162c5760405180602001604052806000815250611657565b806116368461231d565b604051602001611647929190613ad6565b6040516020818303038152906040525b915050919050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116b957600080fd5b80601260006101000a81548160ff02191690831515021790555050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461173057600080fd5b8060118190555050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461179457600080fd5b80600b90816117a39190613ca7565b5050565b600d5481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60115481565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146118a157600080fd5b80600d8190555050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061190657506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806119365750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806119b057506119af826123eb565b5b9050919050565b6000816119c2611c57565b111580156119d1575060005482105b8015611a0f575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611b10576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401611a8d929190613d79565b602060405180830381865afa158015611aaa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ace9190613db7565b611b0f57806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611b069190612cf8565b60405180910390fd5b5b50565b6000611b1e82610f23565b90508073ffffffffffffffffffffffffffffffffffffffff16611b3f612455565b73ffffffffffffffffffffffffffffffffffffffff1614611ba257611b6b81611b66612455565b6117ad565b611ba1576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60006001905090565b611c7a82826040518060200160405280600081525061245d565b5050565b6000611c8982611fc0565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611cf0576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080611cfc846124fa565b91509150611d128187611d0d612455565b612521565b611d5e57611d2786611d22612455565b6117ad565b611d5d576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611dc4576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dd18686866001612565565b8015611ddc57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550611eaa85611e8688888761256b565b7c020000000000000000000000000000000000000000000000000000000017612593565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603611f305760006001850190506000600460008381526020019081526020016000205403611f2e576000548114611f2d578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611f9886868660016125be565b505050505050565b611fbb83838360405180602001604052806000815250611377565b505050565b60008082905080611fcf611c57565b11612055576000548110156120545760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603612052575b6000810361204857600460008360019003935083815260200190815260200160002054905061201e565b8092505050612087565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008261209985846125c4565b1490509392505050565b80600760006120b0612455565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661215d612455565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516121a29190612b87565b60405180910390a35050565b6121b9848484610b3a565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461221b576121e48484848461261a565b61221a576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b600061222b611c57565b60005403905090565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b6060600b805461229a90613590565b80601f01602080910402602001604051908101604052809291908181526020018280546122c690613590565b80156123135780601f106122e857610100808354040283529160200191612313565b820191906000526020600020905b8154815290600101906020018083116122f657829003601f168201915b5050505050905090565b60606000600161232c8461276a565b01905060008167ffffffffffffffff81111561234b5761234a612f74565b5b6040519080825280601f01601f19166020018201604052801561237d5781602001600182028036833780820191505090505b509050600082602001820190505b6001156123e0578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816123d4576123d3613632565b5b0494506000850361238b575b819350505050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b61246783836128bd565b60008373ffffffffffffffffffffffffffffffffffffffff163b146124f557600080549050600083820390505b6124a7600086838060010194508661261a565b6124dd576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181106124945781600054146124f257600080fd5b50505b505050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8612582868684612a78565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b60008082905060005b845181101561260f576125fa828683815181106125ed576125ec61373d565b5b6020026020010151612a81565b91508080612607906136f5565b9150506125cd565b508091505092915050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612640612455565b8786866040518563ffffffff1660e01b81526004016126629493929190613e39565b6020604051808303816000875af192505050801561269e57506040513d601f19601f8201168201806040525081019061269b9190613e9a565b60015b612717573d80600081146126ce576040519150601f19603f3d011682016040523d82523d6000602084013e6126d3565b606091505b50600081510361270f576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106127c8577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816127be576127bd613632565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612805576d04ee2d6d415b85acef810000000083816127fb576127fa613632565b5b0492506020810190505b662386f26fc10000831061283457662386f26fc10000838161282a57612829613632565b5b0492506010810190505b6305f5e100831061285d576305f5e100838161285357612852613632565b5b0492506008810190505b612710831061288257612710838161287857612877613632565b5b0492506004810190505b606483106128a5576064838161289b5761289a613632565b5b0492506002810190505b600a83106128b4576001810190505b80915050919050565b600080549050600082036128fd576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61290a6000848385612565565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061298183612972600086600061256b565b61297b85612aac565b17612593565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114612a2257808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a46001810190506129e7565b5060008203612a5d576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000819055505050612a7360008483856125be565b505050565b60009392505050565b6000818310612a9957612a948284612abc565b612aa4565b612aa38383612abc565b5b905092915050565b60006001821460e11b9050919050565b600082600052816020526040600020905092915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612b1c81612ae7565b8114612b2757600080fd5b50565b600081359050612b3981612b13565b92915050565b600060208284031215612b5557612b54612add565b5b6000612b6384828501612b2a565b91505092915050565b60008115159050919050565b612b8181612b6c565b82525050565b6000602082019050612b9c6000830184612b78565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612bdc578082015181840152602081019050612bc1565b60008484015250505050565b6000601f19601f8301169050919050565b6000612c0482612ba2565b612c0e8185612bad565b9350612c1e818560208601612bbe565b612c2781612be8565b840191505092915050565b60006020820190508181036000830152612c4c8184612bf9565b905092915050565b6000819050919050565b612c6781612c54565b8114612c7257600080fd5b50565b600081359050612c8481612c5e565b92915050565b600060208284031215612ca057612c9f612add565b5b6000612cae84828501612c75565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612ce282612cb7565b9050919050565b612cf281612cd7565b82525050565b6000602082019050612d0d6000830184612ce9565b92915050565b612d1c81612cd7565b8114612d2757600080fd5b50565b600081359050612d3981612d13565b92915050565b60008060408385031215612d5657612d55612add565b5b6000612d6485828601612d2a565b9250506020612d7585828601612c75565b9150509250929050565b612d8881612c54565b82525050565b6000602082019050612da36000830184612d7f565b92915050565b600080600060608486031215612dc257612dc1612add565b5b6000612dd086828701612d2a565b9350506020612de186828701612d2a565b9250506040612df286828701612c75565b9150509250925092565b60008060408385031215612e1357612e12612add565b5b6000612e2185828601612c75565b9250506020612e3285828601612c75565b9150509250929050565b6000604082019050612e516000830185612ce9565b612e5e6020830184612d7f565b9392505050565b6000819050919050565b612e7881612e65565b8114612e8357600080fd5b50565b600081359050612e9581612e6f565b92915050565b600060208284031215612eb157612eb0612add565b5b6000612ebf84828501612e86565b91505092915050565b6000819050919050565b6000612eed612ee8612ee384612cb7565b612ec8565b612cb7565b9050919050565b6000612eff82612ed2565b9050919050565b6000612f1182612ef4565b9050919050565b612f2181612f06565b82525050565b6000602082019050612f3c6000830184612f18565b92915050565b600060208284031215612f5857612f57612add565b5b6000612f6684828501612d2a565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612fac82612be8565b810181811067ffffffffffffffff82111715612fcb57612fca612f74565b5b80604052505050565b6000612fde612ad3565b9050612fea8282612fa3565b919050565b600067ffffffffffffffff82111561300a57613009612f74565b5b602082029050602081019050919050565b600080fd5b600061303361302e84612fef565b612fd4565b905080838252602082019050602084028301858111156130565761305561301b565b5b835b8181101561307f578061306b8882612e86565b845260208401935050602081019050613058565b5050509392505050565b600082601f83011261309e5761309d612f6f565b5b81356130ae848260208601613020565b91505092915050565b6000602082840312156130cd576130cc612add565b5b600082013567ffffffffffffffff8111156130eb576130ea612ae2565b5b6130f784828501613089565b91505092915050565b61310981612e65565b82525050565b60006020820190506131246000830184613100565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61315f81612c54565b82525050565b60006131718383613156565b60208301905092915050565b6000602082019050919050565b60006131958261312a565b61319f8185613135565b93506131aa83613146565b8060005b838110156131db5781516131c28882613165565b97506131cd8361317d565b9250506001810190506131ae565b5085935050505092915050565b60006020820190508181036000830152613202818461318a565b905092915050565b61321381612b6c565b811461321e57600080fd5b50565b6000813590506132308161320a565b92915050565b6000806040838503121561324d5761324c612add565b5b600061325b85828601612d2a565b925050602061326c85828601613221565b9150509250929050565b600080fd5b600067ffffffffffffffff82111561329657613295612f74565b5b61329f82612be8565b9050602081019050919050565b82818337600083830152505050565b60006132ce6132c98461327b565b612fd4565b9050828152602081018484840111156132ea576132e9613276565b5b6132f58482856132ac565b509392505050565b600082601f83011261331257613311612f6f565b5b81356133228482602086016132bb565b91505092915050565b6000806000806080858703121561334557613344612add565b5b600061335387828801612d2a565b945050602061336487828801612d2a565b935050604061337587828801612c75565b925050606085013567ffffffffffffffff81111561339657613395612ae2565b5b6133a2878288016132fd565b91505092959194509250565b600080604083850312156133c5576133c4612add565b5b60006133d385828601612c75565b925050602083013567ffffffffffffffff8111156133f4576133f3612ae2565b5b61340085828601613089565b9150509250929050565b6000602082840312156134205761341f612add565b5b600061342e84828501613221565b91505092915050565b600067ffffffffffffffff82111561345257613451612f74565b5b61345b82612be8565b9050602081019050919050565b600061347b61347684613437565b612fd4565b90508281526020810184848401111561349757613496613276565b5b6134a28482856132ac565b509392505050565b600082601f8301126134bf576134be612f6f565b5b81356134cf848260208601613468565b91505092915050565b6000602082840312156134ee576134ed612add565b5b600082013567ffffffffffffffff81111561350c5761350b612ae2565b5b613518848285016134aa565b91505092915050565b6000806040838503121561353857613537612add565b5b600061354685828601612d2a565b925050602061355785828601612d2a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806135a857607f821691505b6020821081036135bb576135ba613561565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006135fb82612c54565b915061360683612c54565b925082820261361481612c54565b9150828204841483151761362b5761362a6135c1565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061366c82612c54565b915061367783612c54565b92508261368757613686613632565b5b828204905092915050565b60008160601b9050919050565b60006136aa82613692565b9050919050565b60006136bc8261369f565b9050919050565b6136d46136cf82612cd7565b6136b1565b82525050565b60006136e682846136c3565b60148201915081905092915050565b600061370082612c54565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613732576137316135c1565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f7768697465206c6973742074696d652e00000000000000000000000000000000600082015250565b60006137a2601083612bad565b91506137ad8261376c565b602082019050919050565b600060208201905081810360008301526137d181613795565b9050919050565b7f77726f6e67207072696365000000000000000000000000000000000000000000600082015250565b600061380e600b83612bad565b9150613819826137d8565b602082019050919050565b6000602082019050818103600083015261383d81613801565b9050919050565b7f77726f6e672070726963652028776c2900000000000000000000000000000000600082015250565b600061387a601083612bad565b915061388582613844565b602082019050919050565b600060208201905081810360008301526138a98161386d565b9050919050565b60006138bb82612c54565b91506138c683612c54565b92508282019050808211156138de576138dd6135c1565b5b92915050565b7f4e6f74206d6f726520737570706c79206c656674000000000000000000000000600082015250565b600061391a601483612bad565b9150613925826138e4565b602082019050919050565b600060208201905081810360008301526139498161390d565b9050919050565b7f55736572206c696d697420726561636865640000000000000000000000000000600082015250565b6000613986601283612bad565b915061399182613950565b602082019050919050565b600060208201905081810360008301526139b581613979565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000613a18602f83612bad565b9150613a23826139bc565b604082019050919050565b60006020820190508181036000830152613a4781613a0b565b9050919050565b600081905092915050565b6000613a6482612ba2565b613a6e8185613a4e565b9350613a7e818560208601612bbe565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b6000613ac0600583613a4e565b9150613acb82613a8a565b600582019050919050565b6000613ae28285613a59565b9150613aee8284613a59565b9150613af982613ab3565b91508190509392505050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302613b677fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613b2a565b613b718683613b2a565b95508019841693508086168417925050509392505050565b6000613ba4613b9f613b9a84612c54565b612ec8565b612c54565b9050919050565b6000819050919050565b613bbe83613b89565b613bd2613bca82613bab565b848454613b37565b825550505050565b600090565b613be7613bda565b613bf2818484613bb5565b505050565b5b81811015613c1657613c0b600082613bdf565b600181019050613bf8565b5050565b601f821115613c5b57613c2c81613b05565b613c3584613b1a565b81016020851015613c44578190505b613c58613c5085613b1a565b830182613bf7565b50505b505050565b600082821c905092915050565b6000613c7e60001984600802613c60565b1980831691505092915050565b6000613c978383613c6d565b9150826002028217905092915050565b613cb082612ba2565b67ffffffffffffffff811115613cc957613cc8612f74565b5b613cd38254613590565b613cde828285613c1a565b600060209050601f831160018114613d115760008415613cff578287015190505b613d098582613c8b565b865550613d71565b601f198416613d1f86613b05565b60005b82811015613d4757848901518255600182019150602085019450602081019050613d22565b86831015613d645784890151613d60601f891682613c6d565b8355505b6001600288020188555050505b505050505050565b6000604082019050613d8e6000830185612ce9565b613d9b6020830184612ce9565b9392505050565b600081519050613db18161320a565b92915050565b600060208284031215613dcd57613dcc612add565b5b6000613ddb84828501613da2565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000613e0b82613de4565b613e158185613def565b9350613e25818560208601612bbe565b613e2e81612be8565b840191505092915050565b6000608082019050613e4e6000830187612ce9565b613e5b6020830186612ce9565b613e686040830185612d7f565b8181036060830152613e7a8184613e00565b905095945050505050565b600081519050613e9481612b13565b92915050565b600060208284031215613eb057613eaf612add565b5b6000613ebe84828501613e85565b9150509291505056fea2646970667358221220efbf54c1fc7e9cfea35168cb76abc67bf5a3115bd97f8a1e4437b64bb1e6bca664736f6c6343000811003368747470733a2f2f6e667473746f726167652e6c696e6b2f697066732f626166796265696636666e6b796c346b7532796d7578657a6335356b6d32643768696e366f657969346361746d77666e73727662686d33763634342f
Deployed Bytecode
0x6080604052600436106102515760003560e01c8063649a545411610139578063a87b98ad116100b6578063d13ed0251161007a578063d13ed02514610859578063ddaa2f6f14610882578063e471ae0a146108ab578063e985e9c5146108d6578063f704038c14610913578063fcd61a231461093e57610251565b8063a87b98ad14610792578063b88d4fde146107bb578063ba41b0c6146107d7578063c87b56dd146107f3578063ccea96ac1461083057610251565b80637c467166116100fd5780637c467166146106995780638da5cb5b146106d657806395d89b4114610701578063a21e49181461072c578063a22cb4651461076957610251565b8063649a5454146105a057806370a08231146105cb5780637282d833146106085780637a2eba8e146106455780637c3d495c1461067057610251565b806332aebda0116101d25780633f6b6312116101965780633f6b63121461049f57806341f43434146104ca57806342842e0e146104f557806345874017146105115780636352211e1461053a57806363f944de1461057757610251565b806332aebda01461040c57806332cb6b0c146104375780633884d63514610462578063390e81cb1461046c5780633ccfd60b1461049557610251565b806318160ddd1161021957806318160ddd14610342578063182ee4851461036d57806323b872dd1461038957806328dad116146103a55780632a55205a146103ce57610251565b806301ffc9a71461025657806306fdde0314610293578063081812fc146102be578063095ea7b3146102fb57806312065fe014610317575b600080fd5b34801561026257600080fd5b5061027d60048036038101906102789190612b3f565b610967565b60405161028a9190612b87565b60405180910390f35b34801561029f57600080fd5b506102a8610989565b6040516102b59190612c32565b60405180910390f35b3480156102ca57600080fd5b506102e560048036038101906102e09190612c8a565b610a1b565b6040516102f29190612cf8565b60405180910390f35b61031560048036038101906103109190612d3f565b610a9a565b005b34801561032357600080fd5b5061032c610ab3565b6040516103399190612d8e565b60405180910390f35b34801561034e57600080fd5b50610357610abb565b6040516103649190612d8e565b60405180910390f35b61038760048036038101906103829190612d3f565b610ad2565b005b6103a3600480360381019061039e9190612da9565b610b3a565b005b3480156103b157600080fd5b506103cc60048036038101906103c79190612c8a565b610b89565b005b3480156103da57600080fd5b506103f560048036038101906103f09190612dfc565b610bed565b604051610403929190612e3c565b60405180910390f35b34801561041857600080fd5b50610421610c39565b60405161042e9190612b87565b60405180910390f35b34801561044357600080fd5b5061044c610c4c565b6040516104599190612d8e565b60405180910390f35b61046a610c52565b005b34801561047857600080fd5b50610493600480360381019061048e9190612e9b565b610d17565b005b61049d610d7b565b005b3480156104ab57600080fd5b506104b4610e1e565b6040516104c19190612d8e565b60405180910390f35b3480156104d657600080fd5b506104df610e24565b6040516104ec9190612f27565b60405180910390f35b61050f600480360381019061050a9190612da9565b610e36565b005b34801561051d57600080fd5b5061053860048036038101906105339190612f42565b610e85565b005b34801561054657600080fd5b50610561600480360381019061055c9190612c8a565b610f23565b60405161056e9190612cf8565b60405180910390f35b34801561058357600080fd5b5061059e60048036038101906105999190612c8a565b610f35565b005b3480156105ac57600080fd5b506105b5610f99565b6040516105c29190612d8e565b60405180910390f35b3480156105d757600080fd5b506105f260048036038101906105ed9190612f42565b610f9f565b6040516105ff9190612d8e565b60405180910390f35b34801561061457600080fd5b5061062f600480360381019061062a91906130b7565b611057565b60405161063c9190612b87565b60405180910390f35b34801561065157600080fd5b5061065a611098565b604051610667919061310f565b60405180910390f35b34801561067c57600080fd5b5061069760048036038101906106929190612c8a565b61109e565b005b3480156106a557600080fd5b506106c060048036038101906106bb91906130b7565b611102565b6040516106cd9190612b87565b60405180910390f35b3480156106e257600080fd5b506106eb611143565b6040516106f89190612cf8565b60405180910390f35b34801561070d57600080fd5b50610716611169565b6040516107239190612c32565b60405180910390f35b34801561073857600080fd5b50610753600480360381019061074e9190612f42565b6111fb565b60405161076091906131e8565b60405180910390f35b34801561077557600080fd5b50610790600480360381019061078b9190613236565b6112fa565b005b34801561079e57600080fd5b506107b960048036038101906107b49190612c8a565b611313565b005b6107d560048036038101906107d0919061332b565b611377565b005b6107f160048036038101906107ec91906133ae565b6113c8565b005b3480156107ff57600080fd5b5061081a60048036038101906108159190612c8a565b6115b8565b6040516108279190612c32565b60405180910390f35b34801561083c57600080fd5b506108576004803603810190610852919061340a565b61165f565b005b34801561086557600080fd5b50610880600480360381019061087b9190612e9b565b6116d6565b005b34801561088e57600080fd5b506108a960048036038101906108a491906134d8565b61173a565b005b3480156108b757600080fd5b506108c06117a7565b6040516108cd9190612d8e565b60405180910390f35b3480156108e257600080fd5b506108fd60048036038101906108f89190613521565b6117ad565b60405161090a9190612b87565b60405180910390f35b34801561091f57600080fd5b50610928611841565b604051610935919061310f565b60405180910390f35b34801561094a57600080fd5b5061096560048036038101906109609190612c8a565b611847565b005b6000610972826118ab565b8061098257506109818261193d565b5b9050919050565b60606002805461099890613590565b80601f01602080910402602001604051908101604052809291908181526020018280546109c490613590565b8015610a115780601f106109e657610100808354040283529160200191610a11565b820191906000526020600020905b8154815290600101906020018083116109f457829003601f168201915b5050505050905090565b6000610a26826119b7565b610a5c576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610aa481611a16565b610aae8383611b13565b505050565b600047905090565b6000610ac5611c57565b6001546000540303905090565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b2c57600080fd5b610b368282611c60565b5050565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b7857610b7733611a16565b5b610b83848484611c7e565b50505050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610be357600080fd5b80600c8190555050565b600080600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661271084600954610c2491906135f0565b610c2e9190613661565b915091509250929050565b601260009054906101000a900460ff1681565b600c5481565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610cac57600080fd5b60001515601260019054906101000a900460ff16151514610ccc57600080fd5b610cfa600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661012c611c60565b6001601260016101000a81548160ff021916908315150217905550565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d7157600080fd5b8060108190555050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610dd557600080fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015610e1b573d6000803e3d6000fd5b50565b600f5481565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610e7457610e7333611a16565b5b610e7f848484611fa0565b50505050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610edf57600080fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000610f2e82611fc0565b9050919050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f8f57600080fd5b80600e8190555050565b600e5481565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611006576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6000803360405160200161106b91906136da565b604051602081830303815290604052805190602001209050611090836011548361208c565b915050919050565b60105481565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110f857600080fd5b80600f8190555050565b6000803360405160200161111691906136da565b60405160208183030381529060405280519060200120905061113b836010548361208c565b915050919050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60606003805461117890613590565b80601f01602080910402602001604051908101604052809291908181526020018280546111a490613590565b80156111f15780601f106111c6576101008083540402835291602001916111f1565b820191906000526020600020905b8154815290600101906020018083116111d457829003601f168201915b5050505050905090565b6060600061120883610f9f565b67ffffffffffffffff81111561122157611220612f74565b5b60405190808252806020026020018201604052801561124f5781602001602082028036833780820191505090505b509050600061125c610abb565b9050600080611269611c57565b90505b8281116112ee578573ffffffffffffffffffffffffffffffffffffffff1661129382610f23565b73ffffffffffffffffffffffffffffffffffffffff16036112db57808483806112bb906136f5565b9450815181106112ce576112cd61373d565b5b6020026020010181815250505b80806112e6906136f5565b91505061126c565b50829350505050919050565b8161130481611a16565b61130e83836120a3565b505050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461136d57600080fd5b8060098190555050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146113b5576113b433611a16565b5b6113c1858585856121ae565b5050505050565b60006113d382611102565b905060006113e083611057565b9050601260009054906101000a900460ff16156114405781806114005750805b61143f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611436906137b8565b60405180910390fd5b5b8115801561144c575080155b156114a25783600e5461145f91906135f0565b3410156114a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161149890613824565b60405180910390fd5b5b81156114f95783600f546114b691906135f0565b3410156114f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ef90613890565b60405180910390fd5b5b600c5484611505612221565b61150f91906138b0565b1115611550576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161154790613930565b60405180910390fd5b600d548461155d33612234565b61156791906138b0565b11156115a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159f9061399c565b60405180910390fd5b6115b23385611c60565b50505050565b60606115c3826119b7565b611602576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115f990613a2e565b60405180910390fd5b600061160c61228b565b9050600081511161162c5760405180602001604052806000815250611657565b806116368461231d565b604051602001611647929190613ad6565b6040516020818303038152906040525b915050919050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116b957600080fd5b80601260006101000a81548160ff02191690831515021790555050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461173057600080fd5b8060118190555050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461179457600080fd5b80600b90816117a39190613ca7565b5050565b600d5481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60115481565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146118a157600080fd5b80600d8190555050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061190657506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806119365750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806119b057506119af826123eb565b5b9050919050565b6000816119c2611c57565b111580156119d1575060005482105b8015611a0f575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611b10576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401611a8d929190613d79565b602060405180830381865afa158015611aaa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ace9190613db7565b611b0f57806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611b069190612cf8565b60405180910390fd5b5b50565b6000611b1e82610f23565b90508073ffffffffffffffffffffffffffffffffffffffff16611b3f612455565b73ffffffffffffffffffffffffffffffffffffffff1614611ba257611b6b81611b66612455565b6117ad565b611ba1576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60006001905090565b611c7a82826040518060200160405280600081525061245d565b5050565b6000611c8982611fc0565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611cf0576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080611cfc846124fa565b91509150611d128187611d0d612455565b612521565b611d5e57611d2786611d22612455565b6117ad565b611d5d576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611dc4576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611dd18686866001612565565b8015611ddc57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550611eaa85611e8688888761256b565b7c020000000000000000000000000000000000000000000000000000000017612593565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603611f305760006001850190506000600460008381526020019081526020016000205403611f2e576000548114611f2d578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611f9886868660016125be565b505050505050565b611fbb83838360405180602001604052806000815250611377565b505050565b60008082905080611fcf611c57565b11612055576000548110156120545760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603612052575b6000810361204857600460008360019003935083815260200190815260200160002054905061201e565b8092505050612087565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008261209985846125c4565b1490509392505050565b80600760006120b0612455565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661215d612455565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516121a29190612b87565b60405180910390a35050565b6121b9848484610b3a565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461221b576121e48484848461261a565b61221a576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b600061222b611c57565b60005403905090565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b6060600b805461229a90613590565b80601f01602080910402602001604051908101604052809291908181526020018280546122c690613590565b80156123135780601f106122e857610100808354040283529160200191612313565b820191906000526020600020905b8154815290600101906020018083116122f657829003601f168201915b5050505050905090565b60606000600161232c8461276a565b01905060008167ffffffffffffffff81111561234b5761234a612f74565b5b6040519080825280601f01601f19166020018201604052801561237d5781602001600182028036833780820191505090505b509050600082602001820190505b6001156123e0578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816123d4576123d3613632565b5b0494506000850361238b575b819350505050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b61246783836128bd565b60008373ffffffffffffffffffffffffffffffffffffffff163b146124f557600080549050600083820390505b6124a7600086838060010194508661261a565b6124dd576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181106124945781600054146124f257600080fd5b50505b505050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8612582868684612a78565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b60008082905060005b845181101561260f576125fa828683815181106125ed576125ec61373d565b5b6020026020010151612a81565b91508080612607906136f5565b9150506125cd565b508091505092915050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612640612455565b8786866040518563ffffffff1660e01b81526004016126629493929190613e39565b6020604051808303816000875af192505050801561269e57506040513d601f19601f8201168201806040525081019061269b9190613e9a565b60015b612717573d80600081146126ce576040519150601f19603f3d011682016040523d82523d6000602084013e6126d3565b606091505b50600081510361270f576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106127c8577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816127be576127bd613632565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612805576d04ee2d6d415b85acef810000000083816127fb576127fa613632565b5b0492506020810190505b662386f26fc10000831061283457662386f26fc10000838161282a57612829613632565b5b0492506010810190505b6305f5e100831061285d576305f5e100838161285357612852613632565b5b0492506008810190505b612710831061288257612710838161287857612877613632565b5b0492506004810190505b606483106128a5576064838161289b5761289a613632565b5b0492506002810190505b600a83106128b4576001810190505b80915050919050565b600080549050600082036128fd576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61290a6000848385612565565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061298183612972600086600061256b565b61297b85612aac565b17612593565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114612a2257808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a46001810190506129e7565b5060008203612a5d576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000819055505050612a7360008483856125be565b505050565b60009392505050565b6000818310612a9957612a948284612abc565b612aa4565b612aa38383612abc565b5b905092915050565b60006001821460e11b9050919050565b600082600052816020526040600020905092915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612b1c81612ae7565b8114612b2757600080fd5b50565b600081359050612b3981612b13565b92915050565b600060208284031215612b5557612b54612add565b5b6000612b6384828501612b2a565b91505092915050565b60008115159050919050565b612b8181612b6c565b82525050565b6000602082019050612b9c6000830184612b78565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612bdc578082015181840152602081019050612bc1565b60008484015250505050565b6000601f19601f8301169050919050565b6000612c0482612ba2565b612c0e8185612bad565b9350612c1e818560208601612bbe565b612c2781612be8565b840191505092915050565b60006020820190508181036000830152612c4c8184612bf9565b905092915050565b6000819050919050565b612c6781612c54565b8114612c7257600080fd5b50565b600081359050612c8481612c5e565b92915050565b600060208284031215612ca057612c9f612add565b5b6000612cae84828501612c75565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612ce282612cb7565b9050919050565b612cf281612cd7565b82525050565b6000602082019050612d0d6000830184612ce9565b92915050565b612d1c81612cd7565b8114612d2757600080fd5b50565b600081359050612d3981612d13565b92915050565b60008060408385031215612d5657612d55612add565b5b6000612d6485828601612d2a565b9250506020612d7585828601612c75565b9150509250929050565b612d8881612c54565b82525050565b6000602082019050612da36000830184612d7f565b92915050565b600080600060608486031215612dc257612dc1612add565b5b6000612dd086828701612d2a565b9350506020612de186828701612d2a565b9250506040612df286828701612c75565b9150509250925092565b60008060408385031215612e1357612e12612add565b5b6000612e2185828601612c75565b9250506020612e3285828601612c75565b9150509250929050565b6000604082019050612e516000830185612ce9565b612e5e6020830184612d7f565b9392505050565b6000819050919050565b612e7881612e65565b8114612e8357600080fd5b50565b600081359050612e9581612e6f565b92915050565b600060208284031215612eb157612eb0612add565b5b6000612ebf84828501612e86565b91505092915050565b6000819050919050565b6000612eed612ee8612ee384612cb7565b612ec8565b612cb7565b9050919050565b6000612eff82612ed2565b9050919050565b6000612f1182612ef4565b9050919050565b612f2181612f06565b82525050565b6000602082019050612f3c6000830184612f18565b92915050565b600060208284031215612f5857612f57612add565b5b6000612f6684828501612d2a565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612fac82612be8565b810181811067ffffffffffffffff82111715612fcb57612fca612f74565b5b80604052505050565b6000612fde612ad3565b9050612fea8282612fa3565b919050565b600067ffffffffffffffff82111561300a57613009612f74565b5b602082029050602081019050919050565b600080fd5b600061303361302e84612fef565b612fd4565b905080838252602082019050602084028301858111156130565761305561301b565b5b835b8181101561307f578061306b8882612e86565b845260208401935050602081019050613058565b5050509392505050565b600082601f83011261309e5761309d612f6f565b5b81356130ae848260208601613020565b91505092915050565b6000602082840312156130cd576130cc612add565b5b600082013567ffffffffffffffff8111156130eb576130ea612ae2565b5b6130f784828501613089565b91505092915050565b61310981612e65565b82525050565b60006020820190506131246000830184613100565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61315f81612c54565b82525050565b60006131718383613156565b60208301905092915050565b6000602082019050919050565b60006131958261312a565b61319f8185613135565b93506131aa83613146565b8060005b838110156131db5781516131c28882613165565b97506131cd8361317d565b9250506001810190506131ae565b5085935050505092915050565b60006020820190508181036000830152613202818461318a565b905092915050565b61321381612b6c565b811461321e57600080fd5b50565b6000813590506132308161320a565b92915050565b6000806040838503121561324d5761324c612add565b5b600061325b85828601612d2a565b925050602061326c85828601613221565b9150509250929050565b600080fd5b600067ffffffffffffffff82111561329657613295612f74565b5b61329f82612be8565b9050602081019050919050565b82818337600083830152505050565b60006132ce6132c98461327b565b612fd4565b9050828152602081018484840111156132ea576132e9613276565b5b6132f58482856132ac565b509392505050565b600082601f83011261331257613311612f6f565b5b81356133228482602086016132bb565b91505092915050565b6000806000806080858703121561334557613344612add565b5b600061335387828801612d2a565b945050602061336487828801612d2a565b935050604061337587828801612c75565b925050606085013567ffffffffffffffff81111561339657613395612ae2565b5b6133a2878288016132fd565b91505092959194509250565b600080604083850312156133c5576133c4612add565b5b60006133d385828601612c75565b925050602083013567ffffffffffffffff8111156133f4576133f3612ae2565b5b61340085828601613089565b9150509250929050565b6000602082840312156134205761341f612add565b5b600061342e84828501613221565b91505092915050565b600067ffffffffffffffff82111561345257613451612f74565b5b61345b82612be8565b9050602081019050919050565b600061347b61347684613437565b612fd4565b90508281526020810184848401111561349757613496613276565b5b6134a28482856132ac565b509392505050565b600082601f8301126134bf576134be612f6f565b5b81356134cf848260208601613468565b91505092915050565b6000602082840312156134ee576134ed612add565b5b600082013567ffffffffffffffff81111561350c5761350b612ae2565b5b613518848285016134aa565b91505092915050565b6000806040838503121561353857613537612add565b5b600061354685828601612d2a565b925050602061355785828601612d2a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806135a857607f821691505b6020821081036135bb576135ba613561565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006135fb82612c54565b915061360683612c54565b925082820261361481612c54565b9150828204841483151761362b5761362a6135c1565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061366c82612c54565b915061367783612c54565b92508261368757613686613632565b5b828204905092915050565b60008160601b9050919050565b60006136aa82613692565b9050919050565b60006136bc8261369f565b9050919050565b6136d46136cf82612cd7565b6136b1565b82525050565b60006136e682846136c3565b60148201915081905092915050565b600061370082612c54565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613732576137316135c1565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f7768697465206c6973742074696d652e00000000000000000000000000000000600082015250565b60006137a2601083612bad565b91506137ad8261376c565b602082019050919050565b600060208201905081810360008301526137d181613795565b9050919050565b7f77726f6e67207072696365000000000000000000000000000000000000000000600082015250565b600061380e600b83612bad565b9150613819826137d8565b602082019050919050565b6000602082019050818103600083015261383d81613801565b9050919050565b7f77726f6e672070726963652028776c2900000000000000000000000000000000600082015250565b600061387a601083612bad565b915061388582613844565b602082019050919050565b600060208201905081810360008301526138a98161386d565b9050919050565b60006138bb82612c54565b91506138c683612c54565b92508282019050808211156138de576138dd6135c1565b5b92915050565b7f4e6f74206d6f726520737570706c79206c656674000000000000000000000000600082015250565b600061391a601483612bad565b9150613925826138e4565b602082019050919050565b600060208201905081810360008301526139498161390d565b9050919050565b7f55736572206c696d697420726561636865640000000000000000000000000000600082015250565b6000613986601283612bad565b915061399182613950565b602082019050919050565b600060208201905081810360008301526139b581613979565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000613a18602f83612bad565b9150613a23826139bc565b604082019050919050565b60006020820190508181036000830152613a4781613a0b565b9050919050565b600081905092915050565b6000613a6482612ba2565b613a6e8185613a4e565b9350613a7e818560208601612bbe565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b6000613ac0600583613a4e565b9150613acb82613a8a565b600582019050919050565b6000613ae28285613a59565b9150613aee8284613a59565b9150613af982613ab3565b91508190509392505050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302613b677fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613b2a565b613b718683613b2a565b95508019841693508086168417925050509392505050565b6000613ba4613b9f613b9a84612c54565b612ec8565b612c54565b9050919050565b6000819050919050565b613bbe83613b89565b613bd2613bca82613bab565b848454613b37565b825550505050565b600090565b613be7613bda565b613bf2818484613bb5565b505050565b5b81811015613c1657613c0b600082613bdf565b600181019050613bf8565b5050565b601f821115613c5b57613c2c81613b05565b613c3584613b1a565b81016020851015613c44578190505b613c58613c5085613b1a565b830182613bf7565b50505b505050565b600082821c905092915050565b6000613c7e60001984600802613c60565b1980831691505092915050565b6000613c978383613c6d565b9150826002028217905092915050565b613cb082612ba2565b67ffffffffffffffff811115613cc957613cc8612f74565b5b613cd38254613590565b613cde828285613c1a565b600060209050601f831160018114613d115760008415613cff578287015190505b613d098582613c8b565b865550613d71565b601f198416613d1f86613b05565b60005b82811015613d4757848901518255600182019150602085019450602081019050613d22565b86831015613d645784890151613d60601f891682613c6d565b8355505b6001600288020188555050505b505050505050565b6000604082019050613d8e6000830185612ce9565b613d9b6020830184612ce9565b9392505050565b600081519050613db18161320a565b92915050565b600060208284031215613dcd57613dcc612add565b5b6000613ddb84828501613da2565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000613e0b82613de4565b613e158185613def565b9350613e25818560208601612bbe565b613e2e81612be8565b840191505092915050565b6000608082019050613e4e6000830187612ce9565b613e5b6020830186612ce9565b613e686040830185612d7f565b8181036060830152613e7a8184613e00565b905095945050505050565b600081519050613e9481612b13565b92915050565b600060208284031215613eb057613eaf612add565b5b6000613ebe84828501613e85565b9150509291505056fea2646970667358221220efbf54c1fc7e9cfea35168cb76abc67bf5a3115bd97f8a1e4437b64bb1e6bca664736f6c63430008110033
Deployed Bytecode Sourcemap
96498:141:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96258:231;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24248:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30739:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95115:165;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;88633:107;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;19999:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92684:132;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;95286:171;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94267:89;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;86760:215;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;89791:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;89221:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92845:154;;;:::i;:::-;;94362:105;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;88484:122;;;:::i;:::-;;89428:42;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2802:143;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95463:179;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;95903:93;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;25641:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94057:103;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;89375:46;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21183:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90696:226;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;89517:102;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94166:95;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;90462:228;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88063:20;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24424:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90936:398;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94933:176;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;96116:91;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;95648:236;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;91770:890;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;93231:569;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94582:98;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94473:103;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;93865:91;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;89274:29;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31688:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;89656:101;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93962:89;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;96258:231;96369:4;96393:38;96419:11;96393:25;:38::i;:::-;:88;;;;96435:46;96469:11;96435:33;:46::i;:::-;96393:88;96386:95;;96258:231;;;:::o;24248:100::-;24302:13;24335:5;24328:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24248:100;:::o;30739:218::-;30815:7;30840:16;30848:7;30840;:16::i;:::-;30835:64;;30865:34;;;;;;;;;;;;;;30835:64;30919:15;:24;30935:7;30919:24;;;;;;;;;;;:30;;;;;;;;;;;;30912:37;;30739:218;;;:::o;95115:165::-;95219:8;4323:30;4344:8;4323:20;:30::i;:::-;95240:32:::1;95254:8;95264:7;95240:13;:32::i;:::-;95115:165:::0;;;:::o;88633:107::-;88675:11;88711:21;88704:28;;88633:107;:::o;19999:323::-;20060:7;20288:15;:13;:15::i;:::-;20273:12;;20257:13;;:28;:46;20250:53;;19999:323;:::o;92684:132::-;88206:5;;;;;;;;;;;88192:19;;:10;:19;;;88184:28;;;;;;92781:27:::1;92791:6;92799:8;92781:9;:27::i;:::-;92684:132:::0;;:::o;95286:171::-;95395:4;4151:10;4143:18;;:4;:18;;;4139:83;;4178:32;4199:10;4178:20;:32::i;:::-;4139:83;95412:37:::1;95431:4;95437:2;95441:7;95412:18;:37::i;:::-;95286:171:::0;;;;:::o;94267:89::-;88206:5;;;;;;;;;;;88192:19;;:10;:19;;;88184:28;;;;;;94345:3:::1;94332:10;:16;;;;94267:89:::0;:::o;86760:215::-;86859:16;86877:21;86919:12;;;;;;;;;;;86961:5;86948:10;86933:12;;:25;;;;:::i;:::-;:33;;;;:::i;:::-;86911:56;;;;86760:215;;;;;:::o;89791:35::-;;;;;;;;;;;;;:::o;89221:32::-;;;;:::o;92845:154::-;88206:5;;;;;;;;;;;88192:19;;:10;:19;;;88184:28;;;;;;92926:5:::1;92913:18;;:9;;;;;;;;;;;:18;;;92905:27;;;::::0;::::1;;92943:21;92953:5;;;;;;;;;;;92960:3;92943:9;:21::i;:::-;92987:4;92975:9;;:16;;;;;;;;;;;;;;;;;;92845:154::o:0;94362:105::-;88206:5;;;;;;;;;;;88192:19;;:10;:19;;;88184:28;;;;;;94456:3:::1;94435:18;:24;;;;94362:105:::0;:::o;88484:122::-;88206:5;;;;;;;;;;;88192:19;;:10;:19;;;88184:28;;;;;;88555:10:::1;88547:28;;:51;88576:21;88547:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;88484:122::o:0;89428:42::-;;;;:::o;2802:143::-;2902:42;2802:143;:::o;95463:179::-;95576:4;4151:10;4143:18;;:4;:18;;;4139:83;;4178:32;4199:10;4178:20;:32::i;:::-;4139:83;95593:41:::1;95616:4;95622:2;95626:7;95593:22;:41::i;:::-;95463:179:::0;;;;:::o;95903:93::-;88206:5;;;;;;;;;;;88192:19;;:10;:19;;;88184:28;;;;;;95984:4:::1;95969:12;;:19;;;;;;;;;;;;;;;;;;95903:93:::0;:::o;25641:152::-;25713:7;25756:27;25775:7;25756:18;:27::i;:::-;25733:52;;25641:152;;;:::o;94057:103::-;88206:5;;;;;;;;;;;88192:19;;:10;:19;;;88184:28;;;;;;94149:3:::1;94129:17;:23;;;;94057:103:::0;:::o;89375:46::-;;;;:::o;21183:233::-;21255:7;21296:1;21279:19;;:5;:19;;;21275:60;;21307:28;;;;;;;;;;;;;;21275:60;15342:13;21353:18;:25;21372:5;21353:25;;;;;;;;;;;;;;;;:55;21346:62;;21183:233;;;:::o;90696:226::-;90763:11;90792:12;90834:10;90817:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;90807:39;;;;;;90792:54;;90864:50;90883:5;90890:17;;90909:4;90864:18;:50::i;:::-;90857:57;;;90696:226;;;:::o;89517:102::-;;;;:::o;94166:95::-;88206:5;;;;;;;;;;;88192:19;;:10;:19;;;88184:28;;;;;;94250:3:::1;94234:13;:19;;;;94166:95:::0;:::o;90462:228::-;90530:11;90559:12;90601:10;90584:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;90574:39;;;;;;90559:54;;90631:51;90650:5;90657:18;;90677:4;90631:18;:51::i;:::-;90624:58;;;90462:228;;;:::o;88063:20::-;;;;;;;;;;;;;:::o;24424:104::-;24480:13;24513:7;24506:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24424:104;:::o;90936:398::-;90992:16;91026:20;91063:15;91073:4;91063:9;:15::i;:::-;91049:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91026:53;;91090:11;91104:13;:11;:13::i;:::-;91090:27;;91128:9;91155;91167:15;:13;:15::i;:::-;91155:27;;91150:146;91189:3;91184:1;:8;91150:146;;91232:4;91218:18;;:10;91226:1;91218:7;:10::i;:::-;:18;;;91214:71;;91268:1;91257:3;91261;;;;;:::i;:::-;;;91257:8;;;;;;;;:::i;:::-;;;;;;;:12;;;;;91214:71;91194:3;;;;;:::i;:::-;;;;91150:146;;;;91323:3;91316:10;;;;;90936:398;;;:::o;94933:176::-;95037:8;4323:30;4344:8;4323:20;:30::i;:::-;95058:43:::1;95082:8;95092;95058:23;:43::i;:::-;94933:176:::0;;;:::o;96116:91::-;88206:5;;;;;;;;;;;88192:19;;:10;:19;;;88184:28;;;;;;96196:3:::1;96181:12;:18;;;;96116:91:::0;:::o;95648:236::-;95807:4;4151:10;4143:18;;:4;:18;;;4139:83;;4178:32;4199:10;4178:20;:32::i;:::-;4139:83;95829:47:::1;95852:4;95858:2;95862:7;95871:4;95829:22;:47::i;:::-;95648:236:::0;;;;;:::o;91770:890::-;91859:8;91870:21;91885:5;91870:14;:21::i;:::-;91859:32;;91902:8;91913:20;91927:5;91913:13;:20::i;:::-;91902:31;;91965:16;;;;;;;;;;;91962:87;;;92006:3;:10;;;;92013:3;92006:10;91998:39;;;;;;;;;;;;:::i;:::-;;;;;;;;;91962:87;92081:3;92080:4;:12;;;;;92089:3;92088:4;92080:12;92077:109;;;92150:8;92130:17;;:28;;;;:::i;:::-;92117:9;:41;;92109:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;92077:109;92216:3;92213:100;;;92272:8;92256:13;;:24;;;;:::i;:::-;92243:9;:37;;92235:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;92213:100;92381:10;;92369:8;92352:14;:12;:14::i;:::-;:25;;;;:::i;:::-;:39;;92344:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;92475:10;;92463:8;92435:25;92449:10;92435:13;:25::i;:::-;:36;;;;:::i;:::-;:50;;92427:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;92621:31;92631:10;92643:8;92621:9;:31::i;:::-;91848:812;;91770:890;;:::o;93231:569::-;93304:13;93519:16;93527:7;93519;:16::i;:::-;93511:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;93598:28;93629:10;:8;:10::i;:::-;93598:41;;93688:1;93663:14;93657:28;:32;:135;;;;;;;;;;;;;;;;;93729:14;93745:18;:7;:16;:18::i;:::-;93712:61;;;;;;;;;:::i;:::-;;;;;;;;;;;;;93657:135;93650:142;;;93231:569;;;:::o;94582:98::-;88206:5;;;;;;;;;;;88192:19;;:10;:19;;;88184:28;;;;;;94669:3:::1;94650:16;;:22;;;;;;;;;;;;;;;;;;94582:98:::0;:::o;94473:103::-;88206:5;;;;;;;;;;;88192:19;;:10;:19;;;88184:28;;;;;;94565:3:::1;94545:17;:23;;;;94473:103:::0;:::o;93865:91::-;88206:5;;;;;;;;;;;88192:19;;:10;:19;;;88184:28;;;;;;93945:3:::1;93934:8;:14;;;;;;:::i;:::-;;93865:91:::0;:::o;89274:29::-;;;;:::o;31688:164::-;31785:4;31809:18;:25;31828:5;31809:25;;;;;;;;;;;;;;;:35;31835:8;31809:35;;;;;;;;;;;;;;;;;;;;;;;;;31802:42;;31688:164;;;;:::o;89656:101::-;;;;:::o;93962:89::-;88206:5;;;;;;;;;;;88192:19;;:10;:19;;;88184:28;;;;;;94040:3:::1;94027:10;:16;;;;93962:89:::0;:::o;23346:639::-;23431:4;23770:10;23755:25;;:11;:25;;;;:102;;;;23847:10;23832:25;;:11;:25;;;;23755:102;:179;;;;23924:10;23909:25;;:11;:25;;;;23755:179;23735:199;;23346:639;;;:::o;87198:206::-;87291:4;87330:26;87315:41;;;:11;:41;;;;:81;;;;87360:36;87384:11;87360:23;:36::i;:::-;87315:81;87308:88;;87198:206;;;:::o;32110:282::-;32175:4;32231:7;32212:15;:13;:15::i;:::-;:26;;:66;;;;;32265:13;;32255:7;:23;32212:66;:153;;;;;32364:1;16118:8;32316:17;:26;32334:7;32316:26;;;;;;;;;;;;:44;:49;32212:153;32192:173;;32110:282;;;:::o;4381:419::-;4620:1;2902:42;4572:45;;;:49;4568:225;;;2902:42;4643;;;4694:4;4701:8;4643:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4638:144;;4757:8;4738:28;;;;;;;;;;;:::i;:::-;;;;;;;;4638:144;4568:225;4381:419;:::o;30172:408::-;30261:13;30277:16;30285:7;30277;:16::i;:::-;30261:32;;30333:5;30310:28;;:19;:17;:19::i;:::-;:28;;;30306:175;;30358:44;30375:5;30382:19;:17;:19::i;:::-;30358:16;:44::i;:::-;30353:128;;30430:35;;;;;;;;;;;;;;30353:128;30306:175;30526:2;30493:15;:24;30509:7;30493:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;30564:7;30560:2;30544:28;;30553:5;30544:28;;;;;;;;;;;;30250:330;30172:408;;:::o;19515:92::-;19571:7;19598:1;19591:8;;19515:92;:::o;48250:112::-;48327:27;48337:2;48341:8;48327:27;;;;;;;;;;;;:9;:27::i;:::-;48250:112;;:::o;34378:2825::-;34520:27;34550;34569:7;34550:18;:27::i;:::-;34520:57;;34635:4;34594:45;;34610:19;34594:45;;;34590:86;;34648:28;;;;;;;;;;;;;;34590:86;34690:27;34719:23;34746:35;34773:7;34746:26;:35::i;:::-;34689:92;;;;34881:68;34906:15;34923:4;34929:19;:17;:19::i;:::-;34881:24;:68::i;:::-;34876:180;;34969:43;34986:4;34992:19;:17;:19::i;:::-;34969:16;:43::i;:::-;34964:92;;35021:35;;;;;;;;;;;;;;34964:92;34876:180;35087:1;35073:16;;:2;:16;;;35069:52;;35098:23;;;;;;;;;;;;;;35069:52;35134:43;35156:4;35162:2;35166:7;35175:1;35134:21;:43::i;:::-;35270:15;35267:160;;;35410:1;35389:19;35382:30;35267:160;35807:18;:24;35826:4;35807:24;;;;;;;;;;;;;;;;35805:26;;;;;;;;;;;;35876:18;:22;35895:2;35876:22;;;;;;;;;;;;;;;;35874:24;;;;;;;;;;;36198:146;36235:2;36284:45;36299:4;36305:2;36309:19;36284:14;:45::i;:::-;16398:8;36256:73;36198:18;:146::i;:::-;36169:17;:26;36187:7;36169:26;;;;;;;;;;;:175;;;;36515:1;16398:8;36464:19;:47;:52;36460:627;;36537:19;36569:1;36559:7;:11;36537:33;;36726:1;36692:17;:30;36710:11;36692:30;;;;;;;;;;;;:35;36688:384;;36830:13;;36815:11;:28;36811:242;;37010:19;36977:17;:30;36995:11;36977:30;;;;;;;;;;;:52;;;;36811:242;36688:384;36518:569;36460:627;37134:7;37130:2;37115:27;;37124:4;37115:27;;;;;;;;;;;;37153:42;37174:4;37180:2;37184:7;37193:1;37153:20;:42::i;:::-;34509:2694;;;34378:2825;;;:::o;37299:193::-;37445:39;37462:4;37468:2;37472:7;37445:39;;;;;;;;;;;;:16;:39::i;:::-;37299:193;;;:::o;26796:1275::-;26863:7;26883:12;26898:7;26883:22;;26966:4;26947:15;:13;:15::i;:::-;:23;26943:1061;;27000:13;;26993:4;:20;26989:1015;;;27038:14;27055:17;:23;27073:4;27055:23;;;;;;;;;;;;27038:40;;27172:1;16118:8;27144:6;:24;:29;27140:845;;27809:113;27826:1;27816:6;:11;27809:113;;27869:17;:25;27887:6;;;;;;;27869:25;;;;;;;;;;;;27860:34;;27809:113;;;27955:6;27948:13;;;;;;27140:845;27015:989;26989:1015;26943:1061;28032:31;;;;;;;;;;;;;;26796:1275;;;;:::o;57411:190::-;57536:4;57589;57560:25;57573:5;57580:4;57560:12;:25::i;:::-;:33;57553:40;;57411:190;;;;;:::o;31297:234::-;31444:8;31392:18;:39;31411:19;:17;:19::i;:::-;31392:39;;;;;;;;;;;;;;;:49;31432:8;31392:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;31504:8;31468:55;;31483:19;:17;:19::i;:::-;31468:55;;;31514:8;31468:55;;;;;;:::i;:::-;;;;;;;;31297:234;;:::o;38090:407::-;38265:31;38278:4;38284:2;38288:7;38265:12;:31::i;:::-;38329:1;38311:2;:14;;;:19;38307:183;;38350:56;38381:4;38387:2;38391:7;38400:5;38350:30;:56::i;:::-;38345:145;;38434:40;;;;;;;;;;;;;;38345:145;38307:183;38090:407;;;;:::o;20420:296::-;20475:7;20682:15;:13;:15::i;:::-;20666:13;;:31;20659:38;;20420:296;:::o;21498:178::-;21559:7;15342:13;15480:2;21587:18;:25;21606:5;21587:25;;;;;;;;;;;;;;;;:50;;21586:82;21579:89;;21498:178;;;:::o;93080:109::-;93140:13;93173:8;93166:15;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93080:109;:::o;78741:716::-;78797:13;78848:14;78885:1;78865:17;78876:5;78865:10;:17::i;:::-;:21;78848:38;;78901:20;78935:6;78924:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78901:41;;78957:11;79086:6;79082:2;79078:15;79070:6;79066:28;79059:35;;79123:288;79130:4;79123:288;;;79155:5;;;;;;;;79297:8;79292:2;79285:5;79281:14;79276:30;79271:3;79263:44;79353:2;79344:11;;;;;;:::i;:::-;;;;;79387:1;79378:5;:10;79123:288;79374:21;79123:288;79432:6;79425:13;;;;;78741:716;;;:::o;86067:157::-;86152:4;86191:25;86176:40;;;:11;:40;;;;86169:47;;86067:157;;;:::o;54418:105::-;54478:7;54505:10;54498:17;;54418:105;:::o;47477:689::-;47608:19;47614:2;47618:8;47608:5;:19::i;:::-;47687:1;47669:2;:14;;;:19;47665:483;;47709:11;47723:13;;47709:27;;47755:13;47777:8;47771:3;:14;47755:30;;47804:233;47835:62;47874:1;47878:2;47882:7;;;;;;47891:5;47835:30;:62::i;:::-;47830:167;;47933:40;;;;;;;;;;;;;;47830:167;48032:3;48024:5;:11;47804:233;;48119:3;48102:13;;:20;48098:34;;48124:8;;;48098:34;47690:458;;47665:483;47477:689;;;:::o;33273:485::-;33375:27;33404:23;33445:38;33486:15;:24;33502:7;33486:24;;;;;;;;;;;33445:65;;33663:18;33640:41;;33720:19;33714:26;33695:45;;33625:126;33273:485;;;:::o;32501:659::-;32650:11;32815:16;32808:5;32804:28;32795:37;;32975:16;32964:9;32960:32;32947:45;;33125:15;33114:9;33111:30;33103:5;33092:9;33089:20;33086:56;33076:66;;32501:659;;;;;:::o;39159:159::-;;;;;:::o;53727:311::-;53862:7;53882:16;16522:3;53908:19;:41;;53882:68;;16522:3;53976:31;53987:4;53993:2;53997:9;53976:10;:31::i;:::-;53968:40;;:62;;53961:69;;;53727:311;;;;;:::o;28619:450::-;28699:14;28867:16;28860:5;28856:28;28847:37;;29044:5;29030:11;29005:23;29001:41;28998:52;28991:5;28988:63;28978:73;;28619:450;;;;:::o;39983:158::-;;;;;:::o;58278:296::-;58361:7;58381:20;58404:4;58381:27;;58424:9;58419:118;58443:5;:12;58439:1;:16;58419:118;;;58492:33;58502:12;58516:5;58522:1;58516:8;;;;;;;;:::i;:::-;;;;;;;;58492:9;:33::i;:::-;58477:48;;58457:3;;;;;:::i;:::-;;;;58419:118;;;;58554:12;58547:19;;;58278:296;;;;:::o;40581:716::-;40744:4;40790:2;40765:45;;;40811:19;:17;:19::i;:::-;40832:4;40838:7;40847:5;40765:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;40761:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41065:1;41048:6;:13;:18;41044:235;;41094:40;;;;;;;;;;;;;;41044:235;41237:6;41231:13;41222:6;41218:2;41214:15;41207:38;40761:529;40934:54;;;40924:64;;;:6;:64;;;;40917:71;;;40581:716;;;;;;:::o;75763:922::-;75816:7;75836:14;75853:1;75836:18;;75903:6;75894:5;:15;75890:102;;75939:6;75930:15;;;;;;:::i;:::-;;;;;75974:2;75964:12;;;;75890:102;76019:6;76010:5;:15;76006:102;;76055:6;76046:15;;;;;;:::i;:::-;;;;;76090:2;76080:12;;;;76006:102;76135:6;76126:5;:15;76122:102;;76171:6;76162:15;;;;;;:::i;:::-;;;;;76206:2;76196:12;;;;76122:102;76251:5;76242;:14;76238:99;;76286:5;76277:14;;;;;;:::i;:::-;;;;;76320:1;76310:11;;;;76238:99;76364:5;76355;:14;76351:99;;76399:5;76390:14;;;;;;:::i;:::-;;;;;76433:1;76423:11;;;;76351:99;76477:5;76468;:14;76464:99;;76512:5;76503:14;;;;;;:::i;:::-;;;;;76546:1;76536:11;;;;76464:99;76590:5;76581;:14;76577:66;;76626:1;76616:11;;;;76577:66;76671:6;76664:13;;;75763:922;;;:::o;41759:2966::-;41832:20;41855:13;;41832:36;;41895:1;41883:8;:13;41879:44;;41905:18;;;;;;;;;;;;;;41879:44;41936:61;41966:1;41970:2;41974:12;41988:8;41936:21;:61::i;:::-;42480:1;15480:2;42450:1;:26;;42449:32;42437:8;:45;42411:18;:22;42430:2;42411:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;42759:139;42796:2;42850:33;42873:1;42877:2;42881:1;42850:14;:33::i;:::-;42817:30;42838:8;42817:20;:30::i;:::-;:66;42759:18;:139::i;:::-;42725:17;:31;42743:12;42725:31;;;;;;;;;;;:173;;;;42915:16;42946:11;42975:8;42960:12;:23;42946:37;;43496:16;43492:2;43488:25;43476:37;;43868:12;43828:8;43787:1;43725:25;43666:1;43605;43578:335;44239:1;44225:12;44221:20;44179:346;44280:3;44271:7;44268:16;44179:346;;44498:7;44488:8;44485:1;44458:25;44455:1;44452;44447:59;44333:1;44324:7;44320:15;44309:26;;44179:346;;;44183:77;44570:1;44558:8;:13;44554:45;;44580:19;;;;;;;;;;;;;;44554:45;44632:3;44616:13;:19;;;;42185:2462;;44657:60;44686:1;44690:2;44694:12;44708:8;44657:20;:60::i;:::-;41821:2904;41759:2966;;:::o;53428:147::-;53565:6;53428:147;;;;;:::o;65318:149::-;65381:7;65412:1;65408;:5;:51;;65439:20;65454:1;65457;65439:14;:20::i;:::-;65408:51;;;65416:20;65431:1;65434;65416:14;:20::i;:::-;65408:51;65401:58;;65318:149;;;;:::o;29171:324::-;29241:14;29474:1;29464:8;29461:15;29435:24;29431:46;29421:56;;29171:324;;;:::o;65475:268::-;65543:13;65650:1;65644:4;65637:15;65679:1;65673:4;65666:15;65720:4;65714;65704:21;65695:30;;65475:268;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:77::-;2897:7;2926:5;2915:16;;2860:77;;;:::o;2943:122::-;3016:24;3034:5;3016:24;:::i;:::-;3009:5;3006:35;2996:63;;3055:1;3052;3045:12;2996:63;2943:122;:::o;3071:139::-;3117:5;3155:6;3142:20;3133:29;;3171:33;3198:5;3171:33;:::i;:::-;3071:139;;;;:::o;3216:329::-;3275:6;3324:2;3312:9;3303:7;3299:23;3295:32;3292:119;;;3330:79;;:::i;:::-;3292:119;3450:1;3475:53;3520:7;3511:6;3500:9;3496:22;3475:53;:::i;:::-;3465:63;;3421:117;3216:329;;;;:::o;3551:126::-;3588:7;3628:42;3621:5;3617:54;3606:65;;3551:126;;;:::o;3683:96::-;3720:7;3749:24;3767:5;3749:24;:::i;:::-;3738:35;;3683:96;;;:::o;3785:118::-;3872:24;3890:5;3872:24;:::i;:::-;3867:3;3860:37;3785:118;;:::o;3909:222::-;4002:4;4040:2;4029:9;4025:18;4017:26;;4053:71;4121:1;4110:9;4106:17;4097:6;4053:71;:::i;:::-;3909:222;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:474::-;4478:6;4486;4535:2;4523:9;4514:7;4510:23;4506:32;4503:119;;;4541:79;;:::i;:::-;4503:119;4661:1;4686:53;4731:7;4722:6;4711:9;4707:22;4686:53;:::i;:::-;4676:63;;4632:117;4788:2;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4759:118;4410:474;;;;;:::o;4890:118::-;4977:24;4995:5;4977:24;:::i;:::-;4972:3;4965:37;4890:118;;:::o;5014:222::-;5107:4;5145:2;5134:9;5130:18;5122:26;;5158:71;5226:1;5215:9;5211:17;5202:6;5158:71;:::i;:::-;5014:222;;;;:::o;5242:619::-;5319:6;5327;5335;5384:2;5372:9;5363:7;5359:23;5355:32;5352:119;;;5390:79;;:::i;:::-;5352:119;5510:1;5535:53;5580:7;5571:6;5560:9;5556:22;5535:53;:::i;:::-;5525:63;;5481:117;5637:2;5663:53;5708:7;5699:6;5688:9;5684:22;5663:53;:::i;:::-;5653:63;;5608:118;5765:2;5791:53;5836:7;5827:6;5816:9;5812:22;5791:53;:::i;:::-;5781:63;;5736:118;5242:619;;;;;:::o;5867:474::-;5935:6;5943;5992:2;5980:9;5971:7;5967:23;5963:32;5960:119;;;5998:79;;:::i;:::-;5960:119;6118:1;6143:53;6188:7;6179:6;6168:9;6164:22;6143:53;:::i;:::-;6133:63;;6089:117;6245:2;6271:53;6316:7;6307:6;6296:9;6292:22;6271:53;:::i;:::-;6261:63;;6216:118;5867:474;;;;;:::o;6347:332::-;6468:4;6506:2;6495:9;6491:18;6483:26;;6519:71;6587:1;6576:9;6572:17;6563:6;6519:71;:::i;:::-;6600:72;6668:2;6657:9;6653:18;6644:6;6600:72;:::i;:::-;6347:332;;;;;:::o;6685:77::-;6722:7;6751:5;6740:16;;6685:77;;;:::o;6768:122::-;6841:24;6859:5;6841:24;:::i;:::-;6834:5;6831:35;6821:63;;6880:1;6877;6870:12;6821:63;6768:122;:::o;6896:139::-;6942:5;6980:6;6967:20;6958:29;;6996:33;7023:5;6996:33;:::i;:::-;6896:139;;;;:::o;7041:329::-;7100:6;7149:2;7137:9;7128:7;7124:23;7120:32;7117:119;;;7155:79;;:::i;:::-;7117:119;7275:1;7300:53;7345:7;7336:6;7325:9;7321:22;7300:53;:::i;:::-;7290:63;;7246:117;7041:329;;;;:::o;7376:60::-;7404:3;7425:5;7418:12;;7376:60;;;:::o;7442:142::-;7492:9;7525:53;7543:34;7552:24;7570:5;7552:24;:::i;:::-;7543:34;:::i;:::-;7525:53;:::i;:::-;7512:66;;7442:142;;;:::o;7590:126::-;7640:9;7673:37;7704:5;7673:37;:::i;:::-;7660:50;;7590:126;;;:::o;7722:157::-;7803:9;7836:37;7867:5;7836:37;:::i;:::-;7823:50;;7722:157;;;:::o;7885:193::-;8003:68;8065:5;8003:68;:::i;:::-;7998:3;7991:81;7885:193;;:::o;8084:284::-;8208:4;8246:2;8235:9;8231:18;8223:26;;8259:102;8358:1;8347:9;8343:17;8334:6;8259:102;:::i;:::-;8084:284;;;;:::o;8374:329::-;8433:6;8482:2;8470:9;8461:7;8457:23;8453:32;8450:119;;;8488:79;;:::i;:::-;8450:119;8608:1;8633:53;8678:7;8669:6;8658:9;8654:22;8633:53;:::i;:::-;8623:63;;8579:117;8374:329;;;;:::o;8709:117::-;8818:1;8815;8808:12;8832:180;8880:77;8877:1;8870:88;8977:4;8974:1;8967:15;9001:4;8998:1;8991:15;9018:281;9101:27;9123:4;9101:27;:::i;:::-;9093:6;9089:40;9231:6;9219:10;9216:22;9195:18;9183:10;9180:34;9177:62;9174:88;;;9242:18;;:::i;:::-;9174:88;9282:10;9278:2;9271:22;9061:238;9018:281;;:::o;9305:129::-;9339:6;9366:20;;:::i;:::-;9356:30;;9395:33;9423:4;9415:6;9395:33;:::i;:::-;9305:129;;;:::o;9440:311::-;9517:4;9607:18;9599:6;9596:30;9593:56;;;9629:18;;:::i;:::-;9593:56;9679:4;9671:6;9667:17;9659:25;;9739:4;9733;9729:15;9721:23;;9440:311;;;:::o;9757:117::-;9866:1;9863;9856:12;9897:710;9993:5;10018:81;10034:64;10091:6;10034:64;:::i;:::-;10018:81;:::i;:::-;10009:90;;10119:5;10148:6;10141:5;10134:21;10182:4;10175:5;10171:16;10164:23;;10235:4;10227:6;10223:17;10215:6;10211:30;10264:3;10256:6;10253:15;10250:122;;;10283:79;;:::i;:::-;10250:122;10398:6;10381:220;10415:6;10410:3;10407:15;10381:220;;;10490:3;10519:37;10552:3;10540:10;10519:37;:::i;:::-;10514:3;10507:50;10586:4;10581:3;10577:14;10570:21;;10457:144;10441:4;10436:3;10432:14;10425:21;;10381:220;;;10385:21;9999:608;;9897:710;;;;;:::o;10630:370::-;10701:5;10750:3;10743:4;10735:6;10731:17;10727:27;10717:122;;10758:79;;:::i;:::-;10717:122;10875:6;10862:20;10900:94;10990:3;10982:6;10975:4;10967:6;10963:17;10900:94;:::i;:::-;10891:103;;10707:293;10630:370;;;;:::o;11006:539::-;11090:6;11139:2;11127:9;11118:7;11114:23;11110:32;11107:119;;;11145:79;;:::i;:::-;11107:119;11293:1;11282:9;11278:17;11265:31;11323:18;11315:6;11312:30;11309:117;;;11345:79;;:::i;:::-;11309:117;11450:78;11520:7;11511:6;11500:9;11496:22;11450:78;:::i;:::-;11440:88;;11236:302;11006:539;;;;:::o;11551:118::-;11638:24;11656:5;11638:24;:::i;:::-;11633:3;11626:37;11551:118;;:::o;11675:222::-;11768:4;11806:2;11795:9;11791:18;11783:26;;11819:71;11887:1;11876:9;11872:17;11863:6;11819:71;:::i;:::-;11675:222;;;;:::o;11903:114::-;11970:6;12004:5;11998:12;11988:22;;11903:114;;;:::o;12023:184::-;12122:11;12156:6;12151:3;12144:19;12196:4;12191:3;12187:14;12172:29;;12023:184;;;;:::o;12213:132::-;12280:4;12303:3;12295:11;;12333:4;12328:3;12324:14;12316:22;;12213:132;;;:::o;12351:108::-;12428:24;12446:5;12428:24;:::i;:::-;12423:3;12416:37;12351:108;;:::o;12465:179::-;12534:10;12555:46;12597:3;12589:6;12555:46;:::i;:::-;12633:4;12628:3;12624:14;12610:28;;12465:179;;;;:::o;12650:113::-;12720:4;12752;12747:3;12743:14;12735:22;;12650:113;;;:::o;12799:732::-;12918:3;12947:54;12995:5;12947:54;:::i;:::-;13017:86;13096:6;13091:3;13017:86;:::i;:::-;13010:93;;13127:56;13177:5;13127:56;:::i;:::-;13206:7;13237:1;13222:284;13247:6;13244:1;13241:13;13222:284;;;13323:6;13317:13;13350:63;13409:3;13394:13;13350:63;:::i;:::-;13343:70;;13436:60;13489:6;13436:60;:::i;:::-;13426:70;;13282:224;13269:1;13266;13262:9;13257:14;;13222:284;;;13226:14;13522:3;13515:10;;12923:608;;;12799:732;;;;:::o;13537:373::-;13680:4;13718:2;13707:9;13703:18;13695:26;;13767:9;13761:4;13757:20;13753:1;13742:9;13738:17;13731:47;13795:108;13898:4;13889:6;13795:108;:::i;:::-;13787:116;;13537:373;;;;:::o;13916:116::-;13986:21;14001:5;13986:21;:::i;:::-;13979:5;13976:32;13966:60;;14022:1;14019;14012:12;13966:60;13916:116;:::o;14038:133::-;14081:5;14119:6;14106:20;14097:29;;14135:30;14159:5;14135:30;:::i;:::-;14038:133;;;;:::o;14177:468::-;14242:6;14250;14299:2;14287:9;14278:7;14274:23;14270:32;14267:119;;;14305:79;;:::i;:::-;14267:119;14425:1;14450:53;14495:7;14486:6;14475:9;14471:22;14450:53;:::i;:::-;14440:63;;14396:117;14552:2;14578:50;14620:7;14611:6;14600:9;14596:22;14578:50;:::i;:::-;14568:60;;14523:115;14177:468;;;;;:::o;14651:117::-;14760:1;14757;14750:12;14774:307;14835:4;14925:18;14917:6;14914:30;14911:56;;;14947:18;;:::i;:::-;14911:56;14985:29;15007:6;14985:29;:::i;:::-;14977:37;;15069:4;15063;15059:15;15051:23;;14774:307;;;:::o;15087:146::-;15184:6;15179:3;15174;15161:30;15225:1;15216:6;15211:3;15207:16;15200:27;15087:146;;;:::o;15239:423::-;15316:5;15341:65;15357:48;15398:6;15357:48;:::i;:::-;15341:65;:::i;:::-;15332:74;;15429:6;15422:5;15415:21;15467:4;15460:5;15456:16;15505:3;15496:6;15491:3;15487:16;15484:25;15481:112;;;15512:79;;:::i;:::-;15481:112;15602:54;15649:6;15644:3;15639;15602:54;:::i;:::-;15322:340;15239:423;;;;;:::o;15681:338::-;15736:5;15785:3;15778:4;15770:6;15766:17;15762:27;15752:122;;15793:79;;:::i;:::-;15752:122;15910:6;15897:20;15935:78;16009:3;16001:6;15994:4;15986:6;15982:17;15935:78;:::i;:::-;15926:87;;15742:277;15681:338;;;;:::o;16025:943::-;16120:6;16128;16136;16144;16193:3;16181:9;16172:7;16168:23;16164:33;16161:120;;;16200:79;;:::i;:::-;16161:120;16320:1;16345:53;16390:7;16381:6;16370:9;16366:22;16345:53;:::i;:::-;16335:63;;16291:117;16447:2;16473:53;16518:7;16509:6;16498:9;16494:22;16473:53;:::i;:::-;16463:63;;16418:118;16575:2;16601:53;16646:7;16637:6;16626:9;16622:22;16601:53;:::i;:::-;16591:63;;16546:118;16731:2;16720:9;16716:18;16703:32;16762:18;16754:6;16751:30;16748:117;;;16784:79;;:::i;:::-;16748:117;16889:62;16943:7;16934:6;16923:9;16919:22;16889:62;:::i;:::-;16879:72;;16674:287;16025:943;;;;;;;:::o;16974:684::-;17067:6;17075;17124:2;17112:9;17103:7;17099:23;17095:32;17092:119;;;17130:79;;:::i;:::-;17092:119;17250:1;17275:53;17320:7;17311:6;17300:9;17296:22;17275:53;:::i;:::-;17265:63;;17221:117;17405:2;17394:9;17390:18;17377:32;17436:18;17428:6;17425:30;17422:117;;;17458:79;;:::i;:::-;17422:117;17563:78;17633:7;17624:6;17613:9;17609:22;17563:78;:::i;:::-;17553:88;;17348:303;16974:684;;;;;:::o;17664:323::-;17720:6;17769:2;17757:9;17748:7;17744:23;17740:32;17737:119;;;17775:79;;:::i;:::-;17737:119;17895:1;17920:50;17962:7;17953:6;17942:9;17938:22;17920:50;:::i;:::-;17910:60;;17866:114;17664:323;;;;:::o;17993:308::-;18055:4;18145:18;18137:6;18134:30;18131:56;;;18167:18;;:::i;:::-;18131:56;18205:29;18227:6;18205:29;:::i;:::-;18197:37;;18289:4;18283;18279:15;18271:23;;17993:308;;;:::o;18307:425::-;18385:5;18410:66;18426:49;18468:6;18426:49;:::i;:::-;18410:66;:::i;:::-;18401:75;;18499:6;18492:5;18485:21;18537:4;18530:5;18526:16;18575:3;18566:6;18561:3;18557:16;18554:25;18551:112;;;18582:79;;:::i;:::-;18551:112;18672:54;18719:6;18714:3;18709;18672:54;:::i;:::-;18391:341;18307:425;;;;;:::o;18752:340::-;18808:5;18857:3;18850:4;18842:6;18838:17;18834:27;18824:122;;18865:79;;:::i;:::-;18824:122;18982:6;18969:20;19007:79;19082:3;19074:6;19067:4;19059:6;19055:17;19007:79;:::i;:::-;18998:88;;18814:278;18752:340;;;;:::o;19098:509::-;19167:6;19216:2;19204:9;19195:7;19191:23;19187:32;19184:119;;;19222:79;;:::i;:::-;19184:119;19370:1;19359:9;19355:17;19342:31;19400:18;19392:6;19389:30;19386:117;;;19422:79;;:::i;:::-;19386:117;19527:63;19582:7;19573:6;19562:9;19558:22;19527:63;:::i;:::-;19517:73;;19313:287;19098:509;;;;:::o;19613:474::-;19681:6;19689;19738:2;19726:9;19717:7;19713:23;19709:32;19706:119;;;19744:79;;:::i;:::-;19706:119;19864:1;19889:53;19934:7;19925:6;19914:9;19910:22;19889:53;:::i;:::-;19879:63;;19835:117;19991:2;20017:53;20062:7;20053:6;20042:9;20038:22;20017:53;:::i;:::-;20007:63;;19962:118;19613:474;;;;;:::o;20093:180::-;20141:77;20138:1;20131:88;20238:4;20235:1;20228:15;20262:4;20259:1;20252:15;20279:320;20323:6;20360:1;20354:4;20350:12;20340:22;;20407:1;20401:4;20397:12;20428:18;20418:81;;20484:4;20476:6;20472:17;20462:27;;20418:81;20546:2;20538:6;20535:14;20515:18;20512:38;20509:84;;20565:18;;:::i;:::-;20509:84;20330:269;20279:320;;;:::o;20605:180::-;20653:77;20650:1;20643:88;20750:4;20747:1;20740:15;20774:4;20771:1;20764:15;20791:410;20831:7;20854:20;20872:1;20854:20;:::i;:::-;20849:25;;20888:20;20906:1;20888:20;:::i;:::-;20883:25;;20943:1;20940;20936:9;20965:30;20983:11;20965:30;:::i;:::-;20954:41;;21144:1;21135:7;21131:15;21128:1;21125:22;21105:1;21098:9;21078:83;21055:139;;21174:18;;:::i;:::-;21055:139;20839:362;20791:410;;;;:::o;21207:180::-;21255:77;21252:1;21245:88;21352:4;21349:1;21342:15;21376:4;21373:1;21366:15;21393:185;21433:1;21450:20;21468:1;21450:20;:::i;:::-;21445:25;;21484:20;21502:1;21484:20;:::i;:::-;21479:25;;21523:1;21513:35;;21528:18;;:::i;:::-;21513:35;21570:1;21567;21563:9;21558:14;;21393:185;;;;:::o;21584:94::-;21617:8;21665:5;21661:2;21657:14;21636:35;;21584:94;;;:::o;21684:::-;21723:7;21752:20;21766:5;21752:20;:::i;:::-;21741:31;;21684:94;;;:::o;21784:100::-;21823:7;21852:26;21872:5;21852:26;:::i;:::-;21841:37;;21784:100;;;:::o;21890:157::-;21995:45;22015:24;22033:5;22015:24;:::i;:::-;21995:45;:::i;:::-;21990:3;21983:58;21890:157;;:::o;22053:256::-;22165:3;22180:75;22251:3;22242:6;22180:75;:::i;:::-;22280:2;22275:3;22271:12;22264:19;;22300:3;22293:10;;22053:256;;;;:::o;22315:233::-;22354:3;22377:24;22395:5;22377:24;:::i;:::-;22368:33;;22423:66;22416:5;22413:77;22410:103;;22493:18;;:::i;:::-;22410:103;22540:1;22533:5;22529:13;22522:20;;22315:233;;;:::o;22554:180::-;22602:77;22599:1;22592:88;22699:4;22696:1;22689:15;22723:4;22720:1;22713:15;22740:166;22880:18;22876:1;22868:6;22864:14;22857:42;22740:166;:::o;22912:366::-;23054:3;23075:67;23139:2;23134:3;23075:67;:::i;:::-;23068:74;;23151:93;23240:3;23151:93;:::i;:::-;23269:2;23264:3;23260:12;23253:19;;22912:366;;;:::o;23284:419::-;23450:4;23488:2;23477:9;23473:18;23465:26;;23537:9;23531:4;23527:20;23523:1;23512:9;23508:17;23501:47;23565:131;23691:4;23565:131;:::i;:::-;23557:139;;23284:419;;;:::o;23709:161::-;23849:13;23845:1;23837:6;23833:14;23826:37;23709:161;:::o;23876:366::-;24018:3;24039:67;24103:2;24098:3;24039:67;:::i;:::-;24032:74;;24115:93;24204:3;24115:93;:::i;:::-;24233:2;24228:3;24224:12;24217:19;;23876:366;;;:::o;24248:419::-;24414:4;24452:2;24441:9;24437:18;24429:26;;24501:9;24495:4;24491:20;24487:1;24476:9;24472:17;24465:47;24529:131;24655:4;24529:131;:::i;:::-;24521:139;;24248:419;;;:::o;24673:166::-;24813:18;24809:1;24801:6;24797:14;24790:42;24673:166;:::o;24845:366::-;24987:3;25008:67;25072:2;25067:3;25008:67;:::i;:::-;25001:74;;25084:93;25173:3;25084:93;:::i;:::-;25202:2;25197:3;25193:12;25186:19;;24845:366;;;:::o;25217:419::-;25383:4;25421:2;25410:9;25406:18;25398:26;;25470:9;25464:4;25460:20;25456:1;25445:9;25441:17;25434:47;25498:131;25624:4;25498:131;:::i;:::-;25490:139;;25217:419;;;:::o;25642:191::-;25682:3;25701:20;25719:1;25701:20;:::i;:::-;25696:25;;25735:20;25753:1;25735:20;:::i;:::-;25730:25;;25778:1;25775;25771:9;25764:16;;25799:3;25796:1;25793:10;25790:36;;;25806:18;;:::i;:::-;25790:36;25642:191;;;;:::o;25839:170::-;25979:22;25975:1;25967:6;25963:14;25956:46;25839:170;:::o;26015:366::-;26157:3;26178:67;26242:2;26237:3;26178:67;:::i;:::-;26171:74;;26254:93;26343:3;26254:93;:::i;:::-;26372:2;26367:3;26363:12;26356:19;;26015:366;;;:::o;26387:419::-;26553:4;26591:2;26580:9;26576:18;26568:26;;26640:9;26634:4;26630:20;26626:1;26615:9;26611:17;26604:47;26668:131;26794:4;26668:131;:::i;:::-;26660:139;;26387:419;;;:::o;26812:168::-;26952:20;26948:1;26940:6;26936:14;26929:44;26812:168;:::o;26986:366::-;27128:3;27149:67;27213:2;27208:3;27149:67;:::i;:::-;27142:74;;27225:93;27314:3;27225:93;:::i;:::-;27343:2;27338:3;27334:12;27327:19;;26986:366;;;:::o;27358:419::-;27524:4;27562:2;27551:9;27547:18;27539:26;;27611:9;27605:4;27601:20;27597:1;27586:9;27582:17;27575:47;27639:131;27765:4;27639:131;:::i;:::-;27631:139;;27358:419;;;:::o;27783:234::-;27923:34;27919:1;27911:6;27907:14;27900:58;27992:17;27987:2;27979:6;27975:15;27968:42;27783:234;:::o;28023:366::-;28165:3;28186:67;28250:2;28245:3;28186:67;:::i;:::-;28179:74;;28262:93;28351:3;28262:93;:::i;:::-;28380:2;28375:3;28371:12;28364:19;;28023:366;;;:::o;28395:419::-;28561:4;28599:2;28588:9;28584:18;28576:26;;28648:9;28642:4;28638:20;28634:1;28623:9;28619:17;28612:47;28676:131;28802:4;28676:131;:::i;:::-;28668:139;;28395:419;;;:::o;28820:148::-;28922:11;28959:3;28944:18;;28820:148;;;;:::o;28974:390::-;29080:3;29108:39;29141:5;29108:39;:::i;:::-;29163:89;29245:6;29240:3;29163:89;:::i;:::-;29156:96;;29261:65;29319:6;29314:3;29307:4;29300:5;29296:16;29261:65;:::i;:::-;29351:6;29346:3;29342:16;29335:23;;29084:280;28974:390;;;;:::o;29370:155::-;29510:7;29506:1;29498:6;29494:14;29487:31;29370:155;:::o;29531:400::-;29691:3;29712:84;29794:1;29789:3;29712:84;:::i;:::-;29705:91;;29805:93;29894:3;29805:93;:::i;:::-;29923:1;29918:3;29914:11;29907:18;;29531:400;;;:::o;29937:701::-;30218:3;30240:95;30331:3;30322:6;30240:95;:::i;:::-;30233:102;;30352:95;30443:3;30434:6;30352:95;:::i;:::-;30345:102;;30464:148;30608:3;30464:148;:::i;:::-;30457:155;;30629:3;30622:10;;29937:701;;;;;:::o;30644:141::-;30693:4;30716:3;30708:11;;30739:3;30736:1;30729:14;30773:4;30770:1;30760:18;30752:26;;30644:141;;;:::o;30791:93::-;30828:6;30875:2;30870;30863:5;30859:14;30855:23;30845:33;;30791:93;;;:::o;30890:107::-;30934:8;30984:5;30978:4;30974:16;30953:37;;30890:107;;;;:::o;31003:393::-;31072:6;31122:1;31110:10;31106:18;31145:97;31175:66;31164:9;31145:97;:::i;:::-;31263:39;31293:8;31282:9;31263:39;:::i;:::-;31251:51;;31335:4;31331:9;31324:5;31320:21;31311:30;;31384:4;31374:8;31370:19;31363:5;31360:30;31350:40;;31079:317;;31003:393;;;;;:::o;31402:142::-;31452:9;31485:53;31503:34;31512:24;31530:5;31512:24;:::i;:::-;31503:34;:::i;:::-;31485:53;:::i;:::-;31472:66;;31402:142;;;:::o;31550:75::-;31593:3;31614:5;31607:12;;31550:75;;;:::o;31631:269::-;31741:39;31772:7;31741:39;:::i;:::-;31802:91;31851:41;31875:16;31851:41;:::i;:::-;31843:6;31836:4;31830:11;31802:91;:::i;:::-;31796:4;31789:105;31707:193;31631:269;;;:::o;31906:73::-;31951:3;31906:73;:::o;31985:189::-;32062:32;;:::i;:::-;32103:65;32161:6;32153;32147:4;32103:65;:::i;:::-;32038:136;31985:189;;:::o;32180:186::-;32240:120;32257:3;32250:5;32247:14;32240:120;;;32311:39;32348:1;32341:5;32311:39;:::i;:::-;32284:1;32277:5;32273:13;32264:22;;32240:120;;;32180:186;;:::o;32372:543::-;32473:2;32468:3;32465:11;32462:446;;;32507:38;32539:5;32507:38;:::i;:::-;32591:29;32609:10;32591:29;:::i;:::-;32581:8;32577:44;32774:2;32762:10;32759:18;32756:49;;;32795:8;32780:23;;32756:49;32818:80;32874:22;32892:3;32874:22;:::i;:::-;32864:8;32860:37;32847:11;32818:80;:::i;:::-;32477:431;;32462:446;32372:543;;;:::o;32921:117::-;32975:8;33025:5;33019:4;33015:16;32994:37;;32921:117;;;;:::o;33044:169::-;33088:6;33121:51;33169:1;33165:6;33157:5;33154:1;33150:13;33121:51;:::i;:::-;33117:56;33202:4;33196;33192:15;33182:25;;33095:118;33044:169;;;;:::o;33218:295::-;33294:4;33440:29;33465:3;33459:4;33440:29;:::i;:::-;33432:37;;33502:3;33499:1;33495:11;33489:4;33486:21;33478:29;;33218:295;;;;:::o;33518:1395::-;33635:37;33668:3;33635:37;:::i;:::-;33737:18;33729:6;33726:30;33723:56;;;33759:18;;:::i;:::-;33723:56;33803:38;33835:4;33829:11;33803:38;:::i;:::-;33888:67;33948:6;33940;33934:4;33888:67;:::i;:::-;33982:1;34006:4;33993:17;;34038:2;34030:6;34027:14;34055:1;34050:618;;;;34712:1;34729:6;34726:77;;;34778:9;34773:3;34769:19;34763:26;34754:35;;34726:77;34829:67;34889:6;34882:5;34829:67;:::i;:::-;34823:4;34816:81;34685:222;34020:887;;34050:618;34102:4;34098:9;34090:6;34086:22;34136:37;34168:4;34136:37;:::i;:::-;34195:1;34209:208;34223:7;34220:1;34217:14;34209:208;;;34302:9;34297:3;34293:19;34287:26;34279:6;34272:42;34353:1;34345:6;34341:14;34331:24;;34400:2;34389:9;34385:18;34372:31;;34246:4;34243:1;34239:12;34234:17;;34209:208;;;34445:6;34436:7;34433:19;34430:179;;;34503:9;34498:3;34494:19;34488:26;34546:48;34588:4;34580:6;34576:17;34565:9;34546:48;:::i;:::-;34538:6;34531:64;34453:156;34430:179;34655:1;34651;34643:6;34639:14;34635:22;34629:4;34622:36;34057:611;;;34020:887;;33610:1303;;;33518:1395;;:::o;34919:332::-;35040:4;35078:2;35067:9;35063:18;35055:26;;35091:71;35159:1;35148:9;35144:17;35135:6;35091:71;:::i;:::-;35172:72;35240:2;35229:9;35225:18;35216:6;35172:72;:::i;:::-;34919:332;;;;;:::o;35257:137::-;35311:5;35342:6;35336:13;35327:22;;35358:30;35382:5;35358:30;:::i;:::-;35257:137;;;;:::o;35400:345::-;35467:6;35516:2;35504:9;35495:7;35491:23;35487:32;35484:119;;;35522:79;;:::i;:::-;35484:119;35642:1;35667:61;35720:7;35711:6;35700:9;35696:22;35667:61;:::i;:::-;35657:71;;35613:125;35400:345;;;;:::o;35751:98::-;35802:6;35836:5;35830:12;35820:22;;35751:98;;;:::o;35855:168::-;35938:11;35972:6;35967:3;35960:19;36012:4;36007:3;36003:14;35988:29;;35855:168;;;;:::o;36029:373::-;36115:3;36143:38;36175:5;36143:38;:::i;:::-;36197:70;36260:6;36255:3;36197:70;:::i;:::-;36190:77;;36276:65;36334:6;36329:3;36322:4;36315:5;36311:16;36276:65;:::i;:::-;36366:29;36388:6;36366:29;:::i;:::-;36361:3;36357:39;36350:46;;36119:283;36029:373;;;;:::o;36408:640::-;36603:4;36641:3;36630:9;36626:19;36618:27;;36655:71;36723:1;36712:9;36708:17;36699:6;36655:71;:::i;:::-;36736:72;36804:2;36793:9;36789:18;36780:6;36736:72;:::i;:::-;36818;36886:2;36875:9;36871:18;36862:6;36818:72;:::i;:::-;36937:9;36931:4;36927:20;36922:2;36911:9;36907:18;36900:48;36965:76;37036:4;37027:6;36965:76;:::i;:::-;36957:84;;36408:640;;;;;;;:::o;37054:141::-;37110:5;37141:6;37135:13;37126:22;;37157:32;37183:5;37157:32;:::i;:::-;37054:141;;;;:::o;37201:349::-;37270:6;37319:2;37307:9;37298:7;37294:23;37290:32;37287:119;;;37325:79;;:::i;:::-;37287:119;37445:1;37470:63;37525:7;37516:6;37505:9;37501:22;37470:63;:::i;:::-;37460:73;;37416:127;37201:349;;;;:::o
Swarm Source
ipfs://efbf54c1fc7e9cfea35168cb76abc67bf5a3115bd97f8a1e4437b64bb1e6bca6
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.