Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
TokenRun
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-06-24 */ // SPDX-License-Identifier: GPL-3.0 // File: contracts/tokenrun/ERC721x/IERC721x.sol pragma solidity ^0.8.14; interface IERC721x { /** * @dev Returns if the token is locked (non-transferrable) or not. */ function isUnlocked(uint256 _id) external view returns (bool); /** * @dev Returns the amount of locks on the token. */ function lockCount(uint256 _tokenId) external view returns (uint256); /** * @dev Returns if a contract is allowed to lock/unlock tokens. */ function approvedContract(address _contract) external view returns (bool); /** * @dev Returns the contract that locked a token at a specific index in the mapping. */ function lockMap(uint256 _tokenId, uint256 _index) external view returns (address); /** * @dev Returns the mapping index of a contract that locked a token. */ function lockMapIndex(uint256 _tokenId, address _contract) external view returns (uint256); /** * @dev Locks a token, preventing it from being transferrable */ function lockId(uint256 _id) external; /** * @dev Unlocks a token. */ function unlockId(uint256 _id) external; /** * @dev Unlocks a token from a given contract if the contract is no longer approved. */ function freeId(uint256 _id, address _contract) external; } // File: @openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require( address(this).balance >= amount, "Address: insufficient balance" ); (bool success, ) = recipient.call{value: amount}(""); require( success, "Address: unable to send value, recipient may have reverted" ); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue( target, data, 0, "Address: low-level call failed" ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue( target, data, value, "Address: low-level call with value failed" ); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require( address(this).balance >= value, "Address: insufficient balance for call" ); (bool success, bytes memory returndata) = target.call{value: value}( data ); return verifyCallResultFromTarget( target, success, returndata, errorMessage ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall( target, data, "Address: low-level static call failed" ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget( target, success, returndata, errorMessage ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall( target, data, "Address: low-level delegate call failed" ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget( target, success, returndata, errorMessage ); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // File: @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require( !_initializing && _initialized < version, "Initializable: contract is already initialized" ); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } } // File: @openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing {} function __Context_init_unchained() internal onlyInitializing {} function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; } // File: @openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require( newOwner != address(0), "Ownable: new owner is the zero address" ); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; } // File: contracts/tokenrun/ERC721x/LockRegistry.sol pragma solidity ^0.8.14; abstract contract LockRegistry is OwnableUpgradeable, IERC721x { mapping(address => bool) public override approvedContract; mapping(uint256 => uint256) public override lockCount; mapping(uint256 => mapping(uint256 => address)) public override lockMap; mapping(uint256 => mapping(address => uint256)) public override lockMapIndex; event TokenLocked( uint256 indexed tokenId, address indexed approvedContract ); event TokenUnlocked( uint256 indexed tokenId, address indexed approvedContract ); function __LockRegistry_init() internal onlyInitializing { OwnableUpgradeable.__Ownable_init(); } function isUnlocked(uint256 _id) public view override returns (bool) { return lockCount[_id] == 0; } function updateApprovedContracts( address[] calldata _contracts, bool[] calldata _values ) external onlyOwner { require(_contracts.length == _values.length, "!length"); for (uint256 i = 0; i < _contracts.length; i++) approvedContract[_contracts[i]] = _values[i]; } function _lockId(uint256 _id) internal { require(approvedContract[msg.sender], "Cannot update map"); require( lockMapIndex[_id][msg.sender] == 0, "ID already locked by caller" ); uint256 count = lockCount[_id] + 1; lockMap[_id][count] = msg.sender; lockMapIndex[_id][msg.sender] = count; lockCount[_id]++; emit TokenLocked(_id, msg.sender); } function _unlockId(uint256 _id) internal { require(approvedContract[msg.sender], "Cannot update map"); uint256 index = lockMapIndex[_id][msg.sender]; require(index != 0, "ID not locked by caller"); uint256 last = lockCount[_id]; if (index != last) { address lastContract = lockMap[_id][last]; lockMap[_id][index] = lastContract; lockMap[_id][last] = address(0); lockMapIndex[_id][lastContract] = index; } else lockMap[_id][index] = address(0); lockMapIndex[_id][msg.sender] = 0; lockCount[_id]--; emit TokenUnlocked(_id, msg.sender); } function _freeId(uint256 _id, address _contract) internal { require(!approvedContract[_contract], "Cannot update map"); uint256 index = lockMapIndex[_id][_contract]; require(index != 0, "ID not locked"); uint256 last = lockCount[_id]; if (index != last) { address lastContract = lockMap[_id][last]; lockMap[_id][index] = lastContract; lockMap[_id][last] = address(0); lockMapIndex[_id][lastContract] = index; } else lockMap[_id][index] = address(0); lockMapIndex[_id][_contract] = 0; lockCount[_id]--; emit TokenUnlocked(_id, _contract); } } // File: erc721a-upgradeable/contracts/ERC721A__InitializableStorage.sol pragma solidity ^0.8.0; /** * @dev This is a base storage for the initialization function for upgradeable diamond facet contracts **/ library ERC721A__InitializableStorage { struct Layout { /* * Indicates that the contract has been initialized. */ bool _initialized; /* * Indicates that the contract is in the process of being initialized. */ bool _initializing; } bytes32 internal constant STORAGE_SLOT = keccak256("ERC721A.contracts.storage.initializable.facet"); function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } } // File: erc721a-upgradeable/contracts/ERC721A__Initializable.sol pragma solidity ^0.8.0; /** * @dev This is a base contract to aid in writing upgradeable diamond facet contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. */ abstract contract ERC721A__Initializable { using ERC721A__InitializableStorage for ERC721A__InitializableStorage.Layout; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializerERC721A() { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the // contract may have been reentered. require( ERC721A__InitializableStorage.layout()._initializing ? _isConstructor() : !ERC721A__InitializableStorage.layout()._initialized, "ERC721A__Initializable: contract is already initialized" ); bool isTopLevelCall = !ERC721A__InitializableStorage .layout() ._initializing; if (isTopLevelCall) { ERC721A__InitializableStorage.layout()._initializing = true; ERC721A__InitializableStorage.layout()._initialized = true; } _; if (isTopLevelCall) { ERC721A__InitializableStorage.layout()._initializing = false; } } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} modifier, directly or indirectly. */ modifier onlyInitializingERC721A() { require( ERC721A__InitializableStorage.layout()._initializing, "ERC721A__Initializable: contract is not initializing" ); _; } /// @dev Returns true if and only if the function is running in the constructor function _isConstructor() private view returns (bool) { // extcodesize checks the size of the code stored in an address, and // address returns the current address. Since the code is still not // deployed when running a constructor, any checks on its code size will // yield zero, making it an effective way to detect if a contract is // under construction or not. address self = address(this); uint256 cs; assembly { cs := extcodesize(self) } return cs == 0; } } // File: erc721a-upgradeable/contracts/ERC721AStorage.sol pragma solidity ^0.8.0; library ERC721AStorage { // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364). struct TokenApprovalRef { address value; } struct Layout { // ============================================================= // STORAGE // ============================================================= // The next token ID to be minted. uint256 _currentIndex; // The number of tokens burned. uint256 _burnCounter; // Token name string _name; // Token symbol string _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) _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => ERC721AStorage.TokenApprovalRef) _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) _operatorApprovals; } bytes32 internal constant STORAGE_SLOT = keccak256("ERC721A.contracts.storage.ERC721A"); function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } } // File: erc721a-upgradeable/contracts/IERC721AUpgradeable.sol // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721AUpgradeable { /** * 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 ); } // File: erc721a-upgradeable/contracts/ERC721AUpgradeable.sol // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721 token receiver. */ interface ERC721A__IERC721ReceiverUpgradeable { 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 ERC721AUpgradeable is ERC721A__Initializable, IERC721AUpgradeable { using ERC721AStorage for ERC721AStorage.Layout; // ============================================================= // 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; // ============================================================= // CONSTRUCTOR // ============================================================= function __ERC721A_init(string memory name_, string memory symbol_) internal onlyInitializingERC721A { __ERC721A_init_unchained(name_, symbol_); } function __ERC721A_init_unchained( string memory name_, string memory symbol_ ) internal onlyInitializingERC721A { ERC721AStorage.layout()._name = name_; ERC721AStorage.layout()._symbol = symbol_; ERC721AStorage.layout()._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 0; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view virtual returns (uint256) { return ERC721AStorage.layout()._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 ERC721AStorage.layout()._currentIndex - ERC721AStorage.layout()._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 ERC721AStorage.layout()._currentIndex - _startTokenId(); } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return ERC721AStorage.layout()._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 ERC721AStorage.layout()._packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (ERC721AStorage.layout()._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 (ERC721AStorage.layout()._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( ERC721AStorage.layout()._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 = ERC721AStorage.layout()._packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); ERC721AStorage.layout()._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 ERC721AStorage.layout()._name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return ERC721AStorage.layout()._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( ERC721AStorage.layout()._packedOwnerships[index] ); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (ERC721AStorage.layout()._packedOwnerships[index] == 0) { ERC721AStorage.layout()._packedOwnerships[ index ] = _packedOwnershipOf(index); } } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256 packed) { if (_startTokenId() <= tokenId) { packed = ERC721AStorage.layout()._packedOwnerships[tokenId]; // If not burned. if (packed & _BITMASK_BURNED == 0) { // If the data at the starting slot does not exist, start the scan. if (packed == 0) { if (tokenId >= ERC721AStorage.layout()._currentIndex) revert OwnerQueryForNonexistentToken(); // Invariant: // There will always be an initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `tokenId` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. for (;;) { unchecked { packed = ERC721AStorage.layout()._packedOwnerships[ --tokenId ]; } if (packed == 0) continue; return packed; } } // Otherwise, the data exists and is not burned. We can skip the scan. // This is possible because we have already achieved the target condition. // This saves 2143 gas on transfers of initialized tokens. 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. See {ERC721A-_approve}. * * Requirements: * * - The caller must own the token or be an approved operator. */ function approve(address to, uint256 tokenId) public payable virtual override { _approve(to, tokenId, true); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return ERC721AStorage.layout()._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 { ERC721AStorage.layout()._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 ERC721AStorage.layout()._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 < ERC721AStorage.layout()._currentIndex && // If within bounds, ERC721AStorage.layout()._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) { ERC721AStorage.TokenApprovalRef storage tokenApproval = ERC721AStorage .layout() ._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. --ERC721AStorage.layout()._packedAddressData[from]; // Updates: `balance -= 1`. ++ERC721AStorage.layout()._packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. ERC721AStorage.layout()._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 ( ERC721AStorage.layout()._packedOwnerships[nextTokenId] == 0 ) { // If the next slot is within bounds. if (nextTokenId != ERC721AStorage.layout()._currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. ERC721AStorage.layout()._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__IERC721ReceiverUpgradeable(to).onERC721Received( _msgSenderERC721A(), from, tokenId, _data ) returns (bytes4 retval) { return retval == ERC721A__IERC721ReceiverUpgradeable(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 = ERC721AStorage.layout()._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`. ERC721AStorage.layout()._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`. ERC721AStorage.layout()._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(); ERC721AStorage.layout()._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 = ERC721AStorage.layout()._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`. ERC721AStorage.layout()._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`. ERC721AStorage.layout()._packedOwnerships[ startTokenId ] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); emit ConsecutiveTransfer( startTokenId, startTokenId + quantity - 1, address(0), to ); ERC721AStorage.layout()._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 = ERC721AStorage.layout()._currentIndex; uint256 index = end - quantity; do { if ( !_checkContractOnERC721Received( address(0), to, index++, _data ) ) { revert TransferToNonERC721ReceiverImplementer(); } } while (index < end); // Reentrancy protection. if (ERC721AStorage.layout()._currentIndex != end) revert(); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ""); } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Equivalent to `_approve(to, tokenId, false)`. */ function _approve(address to, uint256 tokenId) internal virtual { _approve(to, tokenId, false); } /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - `tokenId` must exist. * * Emits an {Approval} event. */ function _approve( address to, uint256 tokenId, bool approvalCheck ) internal virtual { address owner = ownerOf(tokenId); if (approvalCheck) if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } ERC721AStorage.layout()._tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); ( uint256 approvedAddressSlot, address approvedAddress ) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if ( !_isSenderApprovedOrOwner( approvedAddress, from, _msgSenderERC721A() ) ) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); } _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;`. ERC721AStorage.layout()._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`. ERC721AStorage.layout()._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 ( ERC721AStorage.layout()._packedOwnerships[nextTokenId] == 0 ) { // If the next slot is within bounds. if (nextTokenId != ERC721AStorage.layout()._currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. ERC721AStorage.layout()._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 { ERC721AStorage.layout()._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 = ERC721AStorage.layout()._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); ERC721AStorage.layout()._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) } } } // File: contracts/tokenrun/ERC721x/ERC721x.sol pragma solidity ^0.8.14; contract ERC721x is Initializable, ERC721AUpgradeable, LockRegistry { /* * bytes4(keccak256('freeId(uint256,address)')) == 0x94d216d6 * bytes4(keccak256('isUnlocked(uint256)')) == 0x72abc8b7 * bytes4(keccak256('lockCount(uint256)')) == 0x650b00f6 * bytes4(keccak256('lockId(uint256)')) == 0x2799cde0 * bytes4(keccak256('lockMap(uint256,uint256)')) == 0x2cba8123 * bytes4(keccak256('lockMapIndex(uint256,address)')) == 0x09308e5d * bytes4(keccak256('unlockId(uint256)')) == 0x40a9c8df * bytes4(keccak256('approvedContract(address)')) == 0xb1a6505f * * => 0x94d216d6 ^ 0x72abc8b7 ^ 0x650b00f6 ^ 0x2799cde0 ^ * 0x2cba8123 ^ 0x09308e5d ^ 0x40a9c8df ^ 0xb1a6505f == 0x706e8489 */ bytes4 private constant _INTERFACE_ID_ERC721x = 0x706e8489; function __ERC721x_init(string memory _name, string memory _symbol) internal onlyInitializing { ERC721AUpgradeable.__ERC721A_init(_name, _symbol); LockRegistry.__LockRegistry_init(); } function supportsInterface(bytes4 _interfaceId) public view virtual override(ERC721AUpgradeable) returns (bool) { return _interfaceId == _INTERFACE_ID_ERC721x || super.supportsInterface(_interfaceId); } function transferFrom( address _from, address _to, uint256 _tokenId ) public payable virtual override(ERC721AUpgradeable) { require(isUnlocked(_tokenId), "Token is locked"); ERC721AUpgradeable.transferFrom(_from, _to, _tokenId); } function safeTransferFrom( address _from, address _to, uint256 _tokenId, bytes memory _data ) public payable virtual override(ERC721AUpgradeable) { require(isUnlocked(_tokenId), "Token is locked"); ERC721AUpgradeable.safeTransferFrom(_from, _to, _tokenId, _data); } function lockId(uint256 _id) external virtual override { require(_exists(_id), "Token !exist"); _lockId(_id); } function unlockId(uint256 _id) external virtual override { require(_exists(_id), "Token !exist"); _unlockId(_id); } function freeId(uint256 _id, address _contract) external virtual override { require(_exists(_id), "Token !exist"); _freeId(_id, _contract); } } // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/token/ERC721/IERC721.sol // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @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`. * * 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 calldata data ) external; /** * @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 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 ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * 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; /** * @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; /** * @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); } // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require( newOwner != address(0), "Ownable: new owner is the zero address" ); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: @openzeppelin/contracts/utils/StorageSlot.sol // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } } // File: @openzeppelin/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require( address(this).balance >= amount, "Address: insufficient balance" ); (bool success, ) = recipient.call{value: amount}(""); require( success, "Address: unable to send value, recipient may have reverted" ); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue( target, data, 0, "Address: low-level call failed" ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue( target, data, value, "Address: low-level call with value failed" ); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require( address(this).balance >= value, "Address: insufficient balance for call" ); (bool success, bytes memory returndata) = target.call{value: value}( data ); return verifyCallResultFromTarget( target, success, returndata, errorMessage ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall( target, data, "Address: low-level static call failed" ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget( target, success, returndata, errorMessage ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall( target, data, "Address: low-level delegate call failed" ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget( target, success, returndata, errorMessage ); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // File: @openzeppelin/contracts/interfaces/draft-IERC1822.sol // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822Proxiable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); } // File: @openzeppelin/contracts/interfaces/IERC1967.sol // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol) pragma solidity ^0.8.0; /** * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC. * * _Available since v4.8.3._ */ interface IERC1967 { /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Emitted when the beacon is changed. */ event BeaconUpgraded(address indexed beacon); } // File: @openzeppelin/contracts/proxy/beacon/IBeacon.sol // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); } // File: @openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol // OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ */ abstract contract ERC1967Upgrade is IERC1967 { // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require( Address.isContract(newImplementation), "ERC1967: new implementation is not a contract" ); StorageSlot .getAddressSlot(_IMPLEMENTATION_SLOT) .value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { Address.functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822Proxiable(newImplementation).proxiableUUID() returns ( bytes32 slot ) { require( slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID" ); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlot.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require( newAdmin != address(0), "ERC1967: new admin is the zero address" ); StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlot.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require( Address.isContract(newBeacon), "ERC1967: new beacon is not a contract" ); require( Address.isContract(IBeacon(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { Address.functionDelegateCall( IBeacon(newBeacon).implementation(), data ); } } } // File: @openzeppelin/contracts/proxy/Proxy.sol // OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol) pragma solidity ^0.8.0; /** * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to * be specified by overriding the virtual {_implementation} function. * * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a * different contract through the {_delegate} function. * * The success and return data of the delegated call will be returned back to the caller of the proxy. */ abstract contract Proxy { /** * @dev Delegates the current call to `implementation`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _delegate(address implementation) internal virtual { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall( gas(), implementation, 0, calldatasize(), 0, 0 ) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function * and {_fallback} should delegate. */ function _implementation() internal view virtual returns (address); /** * @dev Delegates the current call to the address returned by `_implementation()`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _fallback() internal virtual { _beforeFallback(); _delegate(_implementation()); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other * function in the contract matches the call data. */ fallback() external payable virtual { _fallback(); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data * is empty. */ receive() external payable virtual { _fallback(); } /** * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback` * call, or as part of the Solidity `fallback` or `receive` functions. * * If overridden should call `super._beforeFallback()`. */ function _beforeFallback() internal virtual {} } // File: @openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol // OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol) pragma solidity ^0.8.0; /** * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an * implementation address that can be changed. This address is stored in storage in the location specified by * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the * implementation behind the proxy. */ contract ERC1967Proxy is Proxy, ERC1967Upgrade { /** * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`. * * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded * function call, and allows initializing the storage of the proxy like a Solidity constructor. */ constructor(address _logic, bytes memory _data) payable { _upgradeToAndCall(_logic, _data, false); } /** * @dev Returns the current implementation address. */ function _implementation() internal view virtual override returns (address impl) { return ERC1967Upgrade._getImplementation(); } } // File: @openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol // OpenZeppelin Contracts (last updated v4.9.0) (proxy/transparent/TransparentUpgradeableProxy.sol) pragma solidity ^0.8.0; /** * @dev Interface for {TransparentUpgradeableProxy}. In order to implement transparency, {TransparentUpgradeableProxy} * does not implement this interface directly, and some of its functions are implemented by an internal dispatch * mechanism. The compiler is unaware that these functions are implemented by {TransparentUpgradeableProxy} and will not * include them in the ABI so this interface must be used to interact with it. */ interface ITransparentUpgradeableProxy is IERC1967 { function admin() external view returns (address); function implementation() external view returns (address); function changeAdmin(address) external; function upgradeTo(address) external; function upgradeToAndCall(address, bytes memory) external payable; } /** * @dev This contract implements a proxy that is upgradeable by an admin. * * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector * clashing], which can potentially be used in an attack, this contract uses the * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two * things that go hand in hand: * * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if * that call matches one of the admin functions exposed by the proxy itself. * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the * implementation. If the admin tries to call a function on the implementation it will fail with an error that says * "admin cannot fallback to proxy target". * * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due * to sudden errors when trying to call a function from the proxy implementation. * * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy. * * NOTE: The real interface of this proxy is that defined in `ITransparentUpgradeableProxy`. This contract does not * inherit from that interface, and instead the admin functions are implicitly implemented using a custom dispatch * mechanism in `_fallback`. Consequently, the compiler will not produce an ABI for this contract. This is necessary to * fully implement transparency without decoding reverts caused by selector clashes between the proxy and the * implementation. * * WARNING: It is not recommended to extend this contract to add additional external functions. If you do so, the compiler * will not check that there are no selector conflicts, due to the note above. A selector clash between any new function * and the functions declared in {ITransparentUpgradeableProxy} will be resolved in favor of the new one. This could * render the admin operations inaccessible, which could prevent upgradeability. Transparency may also be compromised. */ contract TransparentUpgradeableProxy is ERC1967Proxy { /** * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}. */ constructor( address _logic, address admin_, bytes memory _data ) payable ERC1967Proxy(_logic, _data) { _changeAdmin(admin_); } /** * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin. * * CAUTION: This modifier is deprecated, as it could cause issues if the modified function has arguments, and the * implementation provides a function with the same selector. */ modifier ifAdmin() { if (msg.sender == _getAdmin()) { _; } else { _fallback(); } } /** * @dev If caller is the admin process the call internally, otherwise transparently fallback to the proxy behavior */ function _fallback() internal virtual override { if (msg.sender == _getAdmin()) { bytes memory ret; bytes4 selector = msg.sig; if (selector == ITransparentUpgradeableProxy.upgradeTo.selector) { ret = _dispatchUpgradeTo(); } else if ( selector == ITransparentUpgradeableProxy.upgradeToAndCall.selector ) { ret = _dispatchUpgradeToAndCall(); } else if ( selector == ITransparentUpgradeableProxy.changeAdmin.selector ) { ret = _dispatchChangeAdmin(); } else if ( selector == ITransparentUpgradeableProxy.admin.selector ) { ret = _dispatchAdmin(); } else if ( selector == ITransparentUpgradeableProxy.implementation.selector ) { ret = _dispatchImplementation(); } else { revert( "TransparentUpgradeableProxy: admin cannot fallback to proxy target" ); } assembly { return(add(ret, 0x20), mload(ret)) } } else { super._fallback(); } } /** * @dev Returns the current admin. * * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103` */ function _dispatchAdmin() private returns (bytes memory) { _requireZeroValue(); address admin = _getAdmin(); return abi.encode(admin); } /** * @dev Returns the current implementation. * * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc` */ function _dispatchImplementation() private returns (bytes memory) { _requireZeroValue(); address implementation = _implementation(); return abi.encode(implementation); } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _dispatchChangeAdmin() private returns (bytes memory) { _requireZeroValue(); address newAdmin = abi.decode(msg.data[4:], (address)); _changeAdmin(newAdmin); return ""; } /** * @dev Upgrade the implementation of the proxy. */ function _dispatchUpgradeTo() private returns (bytes memory) { _requireZeroValue(); address newImplementation = abi.decode(msg.data[4:], (address)); _upgradeToAndCall(newImplementation, bytes(""), false); return ""; } /** * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the * proxied contract. */ function _dispatchUpgradeToAndCall() private returns (bytes memory) { (address newImplementation, bytes memory data) = abi.decode( msg.data[4:], (address, bytes) ); _upgradeToAndCall(newImplementation, data, true); return ""; } /** * @dev Returns the current admin. * * CAUTION: This function is deprecated. Use {ERC1967Upgrade-_getAdmin} instead. */ function _admin() internal view virtual returns (address) { return _getAdmin(); } /** * @dev To keep this contract fully transparent, all `ifAdmin` functions must be payable. This helper is here to * emulate some proxy functions being non-payable while still allowing value to pass through. */ function _requireZeroValue() private { require(msg.value == 0); } } // File: @openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol // OpenZeppelin Contracts (last updated v4.8.3) (proxy/transparent/ProxyAdmin.sol) pragma solidity ^0.8.0; /** * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}. */ contract ProxyAdmin is Ownable { /** * @dev Returns the current implementation of `proxy`. * * Requirements: * * - This contract must be the admin of `proxy`. */ function getProxyImplementation(ITransparentUpgradeableProxy proxy) public view virtual returns (address) { // We need to manually run the static call since the getter cannot be flagged as view // bytes4(keccak256("implementation()")) == 0x5c60da1b (bool success, bytes memory returndata) = address(proxy).staticcall( hex"5c60da1b" ); require(success); return abi.decode(returndata, (address)); } /** * @dev Returns the current admin of `proxy`. * * Requirements: * * - This contract must be the admin of `proxy`. */ function getProxyAdmin(ITransparentUpgradeableProxy proxy) public view virtual returns (address) { // We need to manually run the static call since the getter cannot be flagged as view // bytes4(keccak256("admin()")) == 0xf851a440 (bool success, bytes memory returndata) = address(proxy).staticcall( hex"f851a440" ); require(success); return abi.decode(returndata, (address)); } /** * @dev Changes the admin of `proxy` to `newAdmin`. * * Requirements: * * - This contract must be the current admin of `proxy`. */ function changeProxyAdmin( ITransparentUpgradeableProxy proxy, address newAdmin ) public virtual onlyOwner { proxy.changeAdmin(newAdmin); } /** * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. * * Requirements: * * - This contract must be the admin of `proxy`. */ function upgrade(ITransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner { proxy.upgradeTo(implementation); } /** * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See * {TransparentUpgradeableProxy-upgradeToAndCall}. * * Requirements: * * - This contract must be the admin of `proxy`. */ function upgradeAndCall( ITransparentUpgradeableProxy proxy, address implementation, bytes memory data ) public payable virtual onlyOwner { proxy.upgradeToAndCall{value: msg.value}(implementation, data); } } // File: contracts/tokenrun/tokenrun.sol // pragma solidity ^0.8.18; pragma solidity ^0.8.18; contract TokenRun is ERC721x { string public prefixURI; uint256 public maxPerWallet; uint256 public mintPrice; bool enableTransfer; bool enableMint; mapping(address => uint256) public mintAddr; mapping(uint256 => address) public soulBonding; mapping(uint256 => uint256) public tokensLastStakedAt; event Stake(uint256 tokenId, address by, uint256 stakedAt); event Unstake( uint256 tokenId, address by, uint256 stakedAt, uint256 unstakedAt ); constructor() { _disableInitializers(); } function initialize(string memory _prefixURI) public initializerERC721A initializer { __ERC721x_init("Tata Avatar by Julian's Editor", "TATA"); prefixURI = _prefixURI; enableTransfer = true; enableMint = false; maxPerWallet = 1; mintPrice = 0; } function adminMint(address receiver, uint256 quantity) public onlyOwner { safeMint(receiver, quantity); } function mint() public payable { require(enableMint, "mint not enabled"); require(totalSupply() < maxSupply(), "sold out"); require(msg.value >= mintPrice, "insufficient value"); require(mintAddr[msg.sender] < maxPerWallet, "reached the maximum"); mintAddr[msg.sender] += 1; safeMint(msg.sender, 1); soulBonding[totalSupply()] = msg.sender; } function safeMint(address receiver, uint256 quantity) internal { _mint(receiver, quantity); } function maxSupply() public pure returns (uint256) { return 10000; } // // =============== URI =============== function _startTokenId() internal view virtual override returns (uint256) { return 1; } function _baseURI() internal view virtual override returns (string memory) { return prefixURI; } function tokenURI(uint256 _tokenId) public view override returns (string memory) { require(_exists(_tokenId), "TOKEN NOT EXIST"); return string.concat(super.tokenURI(_tokenId), ""); } function setBaseURI(string calldata _prefixURI) external onlyOwner { prefixURI = _prefixURI; } // // =============== Stake + MARKETPLACE CONTROL =============== function setMintPrice(uint256 _price) external onlyOwner { mintPrice = _price; } function setMintStatus(bool _enableMint) external onlyOwner { enableMint = _enableMint; } function setTransferStatus(bool _enableTransfer) external onlyOwner { enableTransfer = _enableTransfer; } function stake(uint256 tokenID) external { require(msg.sender == ownerOf(tokenID), "caller must be owner"); require(tokensLastStakedAt[tokenID] == 0, "already staking"); tokensLastStakedAt[tokenID] = block.timestamp; emit Stake(tokenID, msg.sender, tokensLastStakedAt[tokenID]); } function unStake(uint256 tokenID) external { require(msg.sender == ownerOf(tokenID), "caller must be owner"); require(tokensLastStakedAt[tokenID] == 0, "already staking"); uint256 stakeTimestamp = tokensLastStakedAt[tokenID]; tokensLastStakedAt[tokenID] = 0; emit Unstake(tokenID, msg.sender, stakeTimestamp, block.timestamp); } function transferFrom( address from, address to, uint256 tokenId ) public payable override(ERC721x) { require(enableTransfer, "transfer not enabled"); require( tokensLastStakedAt[tokenId] == 0, "Cannot burn staked token" ); super.transferFrom(from, to, tokenId); } function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public payable override(ERC721x) { require(enableTransfer, "transfer not enabled"); require( tokensLastStakedAt[tokenId] == 0, "Cannot transfer staked token" ); super.safeTransferFrom(from, to, tokenId, _data); } function withdraw() public onlyOwner { uint256 sendAmount = address(this).balance; address h = payable(msg.sender); bool success; (success, ) = h.call{value: sendAmount}(""); require(success, "Transaction Unsuccessful"); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"by","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakedAt","type":"uint256"}],"name":"Stake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"approvedContract","type":"address"}],"name":"TokenLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"approvedContract","type":"address"}],"name":"TokenUnlocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"by","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakedAt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unstakedAt","type":"uint256"}],"name":"Unstake","type":"event"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"adminMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"approvedContract","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"address","name":"_contract","type":"address"}],"name":"freeId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_prefixURI","type":"string"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"isUnlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lockCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"lockId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"lockMap","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"lockMapIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mintAddr","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"prefixURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_prefixURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enableMint","type":"bool"}],"name":"setMintStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enableTransfer","type":"bool"}],"name":"setTransferStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"soulBonding","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenID","type":"uint256"}],"name":"stake","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":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokensLastStakedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenID","type":"uint256"}],"name":"unStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"unlockId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_contracts","type":"address[]"},{"internalType":"bool[]","name":"_values","type":"bool[]"}],"name":"updateApprovedContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d2565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000175565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff1614620000ec5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e39190620001b5565b60405180910390a15b565b600082825260208201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b60006200015d602783620000ee565b91506200016a82620000ff565b604082019050919050565b6000602082019050818103600083015262000190816200014e565b9050919050565b600060ff82169050919050565b620001af8162000197565b82525050565b6000602082019050620001cc6000830184620001a4565b92915050565b61565380620001e26000396000f3fe60806040526004361061025c5760003560e01c8063650b00f611610144578063ac52e644116100b6578063d5abeb011161007a578063d5abeb01146108e9578063e58306f914610914578063e985e9c51461093d578063f2fde38b1461097a578063f4a0a528146109a3578063f62d1888146109cc5761025c565b8063ac52e644146107ed578063b1a6505f14610816578063b88d4fde14610853578063c6004ed61461086f578063c87b56dd146108ac5761025c565b80638da5cb5b116101085780638da5cb5b146106f157806394d216d61461071c57806395d89b4114610745578063a0c5407814610770578063a22cb4651461079b578063a694fc3a146107c45761025c565b8063650b00f6146105f85780636817c76c1461063557806370a0823114610660578063715018a61461069d57806372abc8b7146106b45761025c565b80632cba8123116101dd578063453c2310116101a1578063453c2310146104d8578063493770cc1461050357806349a758a31461052c57806355f804b3146105695780635d3eea91146105925780636352211e146105bb5761025c565b80632cba81231461040257806335b504c51461043f5780633ccfd60b1461047c57806340a9c8df1461049357806342842e0e146104bc5761025c565b80631249c58b116102245780631249c58b1461035f57806318160ddd146103695780631f85e3ca1461039457806323b872dd146103bd5780632799cde0146103d95761025c565b806301ffc9a71461026157806306fdde031461029e578063081812fc146102c957806309308e5d14610306578063095ea7b314610343575b600080fd5b34801561026d57600080fd5b5061028860048036038101906102839190613b17565b6109f5565b6040516102959190613b5f565b60405180910390f35b3480156102aa57600080fd5b506102b3610a56565b6040516102c09190613c0a565b60405180910390f35b3480156102d557600080fd5b506102f060048036038101906102eb9190613c62565b610af1565b6040516102fd9190613cd0565b60405180910390f35b34801561031257600080fd5b5061032d60048036038101906103289190613d17565b610b79565b60405161033a9190613d66565b60405180910390f35b61035d60048036038101906103589190613d81565b610b9e565b005b610367610bae565b005b34801561037557600080fd5b5061037e610dd2565b60405161038b9190613d66565b60405180910390f35b3480156103a057600080fd5b506103bb60048036038101906103b69190613ded565b610dfb565b005b6103d760048036038101906103d29190613e1a565b610e20565b005b3480156103e557600080fd5b5061040060048036038101906103fb9190613c62565b610ed5565b005b34801561040e57600080fd5b5061042960048036038101906104249190613e6d565b610f29565b6040516104369190613cd0565b60405180910390f35b34801561044b57600080fd5b5061046660048036038101906104619190613c62565b610f6b565b6040516104739190613d66565b60405180910390f35b34801561048857600080fd5b50610491610f83565b005b34801561049f57600080fd5b506104ba60048036038101906104b59190613c62565b611048565b005b6104d660048036038101906104d19190613e1a565b61109c565b005b3480156104e457600080fd5b506104ed6110bc565b6040516104fa9190613d66565b60405180910390f35b34801561050f57600080fd5b5061052a60048036038101906105259190613ded565b6110c2565b005b34801561053857600080fd5b50610553600480360381019061054e9190613c62565b6110e7565b6040516105609190613cd0565b60405180910390f35b34801561057557600080fd5b50610590600480360381019061058b9190613f12565b61111a565b005b34801561059e57600080fd5b506105b960048036038101906105b49190613c62565b611138565b005b3480156105c757600080fd5b506105e260048036038101906105dd9190613c62565b611276565b6040516105ef9190613cd0565b60405180910390f35b34801561060457600080fd5b5061061f600480360381019061061a9190613c62565b611288565b60405161062c9190613d66565b60405180910390f35b34801561064157600080fd5b5061064a6112a0565b6040516106579190613d66565b60405180910390f35b34801561066c57600080fd5b5061068760048036038101906106829190613f5f565b6112a6565b6040516106949190613d66565b60405180910390f35b3480156106a957600080fd5b506106b2611367565b005b3480156106c057600080fd5b506106db60048036038101906106d69190613c62565b61137b565b6040516106e89190613b5f565b60405180910390f35b3480156106fd57600080fd5b5061070661139a565b6040516107139190613cd0565b60405180910390f35b34801561072857600080fd5b50610743600480360381019061073e9190613d17565b6113c4565b005b34801561075157600080fd5b5061075a61141a565b6040516107679190613c0a565b60405180910390f35b34801561077c57600080fd5b506107856114b5565b6040516107929190613c0a565b60405180910390f35b3480156107a757600080fd5b506107c260048036038101906107bd9190613f8c565b611543565b005b3480156107d057600080fd5b506107eb60048036038101906107e69190613c62565b611657565b005b3480156107f957600080fd5b50610814600480360381019061080f9190614078565b61178c565b005b34801561082257600080fd5b5061083d60048036038101906108389190613f5f565b6118a9565b60405161084a9190613b5f565b60405180910390f35b61086d60048036038101906108689190614229565b6118c9565b005b34801561087b57600080fd5b5061089660048036038101906108919190613f5f565b611980565b6040516108a39190613d66565b60405180910390f35b3480156108b857600080fd5b506108d360048036038101906108ce9190613c62565b611998565b6040516108e09190613c0a565b60405180910390f35b3480156108f557600080fd5b506108fe611a11565b60405161090b9190613d66565b60405180910390f35b34801561092057600080fd5b5061093b60048036038101906109369190613d81565b611a1b565b005b34801561094957600080fd5b50610964600480360381019061095f91906142ac565b611a31565b6040516109719190613b5f565b60405180910390f35b34801561098657600080fd5b506109a1600480360381019061099c9190613f5f565b611ace565b005b3480156109af57600080fd5b506109ca60048036038101906109c59190613c62565b611b51565b005b3480156109d857600080fd5b506109f360048036038101906109ee919061438d565b611b63565b005b600063706e848960e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a4f5750610a4e82611e81565b5b9050919050565b6060610a60611f13565b6002018054610a6e90614405565b80601f0160208091040260200160405190810160405280929190818152602001828054610a9a90614405565b8015610ae75780601f10610abc57610100808354040283529160200191610ae7565b820191906000526020600020905b815481529060010190602001808311610aca57829003601f168201915b5050505050905090565b6000610afc82611f40565b610b32576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b3a611f13565b600601600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6068602052816000526040600020602052806000526040600020600091509150505481565b610baa82826001611fb1565b5050565b606c60019054906101000a900460ff16610bfd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf490614482565b60405180910390fd5b610c05611a11565b610c0d610dd2565b10610c4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c44906144ee565b60405180910390fd5b606b54341015610c92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c899061455a565b60405180910390fd5b606a54606d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410610d15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0c906145c6565b60405180910390fd5b6001606d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610d659190614615565b92505081905550610d77336001612106565b33606e6000610d84610dd2565b815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000610ddc612114565b610de4611f13565b60010154610df0611f13565b600001540303905090565b610e0361211d565b80606c60016101000a81548160ff02191690831515021790555050565b606c60009054906101000a900460ff16610e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6690614695565b60405180910390fd5b6000606f60008381526020019081526020016000205414610ec5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ebc90614701565b60405180910390fd5b610ed083838361219b565b505050565b610ede81611f40565b610f1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f149061476d565b60405180910390fd5b610f26816121f3565b50565b60676020528160005260406000206020528060005260406000206000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606f6020528060005260406000206000915090505481565b610f8b61211d565b6000479050600033905060008173ffffffffffffffffffffffffffffffffffffffff1683604051610fbb906147be565b60006040518083038185875af1925050503d8060008114610ff8576040519150601f19603f3d011682016040523d82523d6000602084013e610ffd565b606091505b50508091505080611043576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103a9061481f565b60405180910390fd5b505050565b61105181611f40565b611090576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110879061476d565b60405180910390fd5b6110998161245f565b50565b6110b7838383604051806020016040528060008152506118c9565b505050565b606a5481565b6110ca61211d565b80606c60006101000a81548160ff02191690831515021790555050565b606e6020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61112261211d565b8181606991826111339291906149f6565b505050565b61114181611276565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146111ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a590614b12565b60405180910390fd5b6000606f60008381526020019081526020016000205414611204576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111fb90614b7e565b60405180910390fd5b6000606f60008381526020019081526020016000205490506000606f6000848152602001908152602001600020819055507fc1e00202ee2c06861d326fc6374026b751863ff64218ccbaa38c3e603a8e72c28233834260405161126a9493929190614b9e565b60405180910390a15050565b60006112818261283a565b9050919050565b60666020528060005260406000206000915090505481565b606b5481565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361130d576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff61131e611f13565b60050160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b61136f61211d565b611379600061294d565b565b6000806066600084815260200190815260200160002054149050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6113cd82611f40565b61140c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114039061476d565b60405180910390fd5b6114168282612a13565b5050565b6060611424611f13565b600301805461143290614405565b80601f016020809104026020016040519081016040528092919081815260200182805461145e90614405565b80156114ab5780601f10611480576101008083540402835291602001916114ab565b820191906000526020600020905b81548152906001019060200180831161148e57829003601f168201915b5050505050905090565b606980546114c290614405565b80601f01602080910402602001604051908101604052809291908181526020018280546114ee90614405565b801561153b5780601f106115105761010080835404028352916020019161153b565b820191906000526020600020905b81548152906001019060200180831161151e57829003601f168201915b505050505081565b8061154c611f13565b6007016000611559612df0565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611606612df0565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161164b9190613b5f565b60405180910390a35050565b61166081611276565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116c490614b12565b60405180910390fd5b6000606f60008381526020019081526020016000205414611723576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161171a90614b7e565b60405180910390fd5b42606f6000838152602001908152602001600020819055507f02567b2553aeb44e4ddd5d68462774dc3de158cb0f2c2da1740e729b22086aff8133606f60008581526020019081526020016000205460405161178193929190614be3565b60405180910390a150565b61179461211d565b8181905084849050146117dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117d390614c66565b60405180910390fd5b60005b848490508110156118a2578282828181106117fd576117fc614c86565b5b90506020020160208101906118129190613ded565b6065600087878581811061182957611828614c86565b5b905060200201602081019061183e9190613f5f565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061189a90614cb5565b9150506117df565b5050505050565b60656020528060005260406000206000915054906101000a900460ff1681565b606c60009054906101000a900460ff16611918576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161190f90614695565b60405180910390fd5b6000606f6000848152602001908152602001600020541461196e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196590614d49565b60405180910390fd5b61197a84848484612df8565b50505050565b606d6020528060005260406000206000915090505481565b60606119a382611f40565b6119e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119d990614db5565b60405180910390fd5b6119eb82612e52565b6040516020016119fb9190614e34565b6040516020818303038152906040529050919050565b6000612710905090565b611a2361211d565b611a2d8282612106565b5050565b6000611a3b611f13565b60070160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611ad661211d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611b45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3c90614ec8565b60405180910390fd5b611b4e8161294d565b50565b611b5961211d565b80606b8190555050565b611b6b612ef0565b60000160019054906101000a900460ff16611b9f57611b88612ef0565b60000160009054906101000a900460ff1615611ba8565b611ba7612f1d565b5b611be7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bde90614f5a565b60405180910390fd5b6000611bf1612ef0565b60000160019054906101000a900460ff161590508015611c54576001611c15612ef0565b60000160016101000a81548160ff0219169083151502179055506001611c39612ef0565b60000160006101000a81548160ff0219169083151502179055505b60008060019054906101000a900460ff16159050808015611c855750600160008054906101000a900460ff1660ff16105b80611cb25750611c9430612f34565b158015611cb15750600160008054906101000a900460ff1660ff16145b5b611cf1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce890614fec565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015611d2e576001600060016101000a81548160ff0219169083151502179055505b611da26040518060400160405280601e81526020017f5461746120417661746172206279204a756c69616e277320456469746f7200008152506040518060400160405280600481526020017f5441544100000000000000000000000000000000000000000000000000000000815250612f57565b8260699081611db1919061500c565b506001606c60006101000a81548160ff0219169083151502179055506000606c60016101000a81548160ff0219169083151502179055506001606a819055506000606b819055508015611e515760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986001604051611e489190615126565b60405180910390a15b508015611e7d576000611e62612ef0565b60000160016101000a81548160ff0219169083151502179055505b5050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611edc57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611f0c5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6000807f2569078dfb4b0305704d3008e7403993ae9601b85f7ae5e742de3de8f8011c4090508091505090565b600081611f4b612114565b11158015611f635750611f5c611f13565b6000015482105b8015611faa575060007c0100000000000000000000000000000000000000000000000000000000611f92611f13565b60040160008581526020019081526020016000205416145b9050919050565b6000611fbc83611276565b90508115612047578073ffffffffffffffffffffffffffffffffffffffff16611fe3612df0565b73ffffffffffffffffffffffffffffffffffffffff16146120465761200f8161200a612df0565b611a31565b612045576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b83612050611f13565b600601600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b6121108282612fbc565b5050565b60006001905090565b61212561319c565b73ffffffffffffffffffffffffffffffffffffffff1661214361139a565b73ffffffffffffffffffffffffffffffffffffffff1614612199576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121909061518d565b60405180910390fd5b565b6121a48161137b565b6121e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121da906151f9565b60405180910390fd5b6121ee8383836131a4565b505050565b606560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661227f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161227690615265565b60405180910390fd5b60006068600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414612312576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612309906152d1565b60405180910390fd5b6000600160666000848152602001908152602001600020546123349190614615565b90503360676000848152602001908152602001600020600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806068600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060666000838152602001908152602001600020600081548092919061241290614cb5565b91905055503373ffffffffffffffffffffffffffffffffffffffff16827f9ecfd70e9ff36df72989324a49559383d39f9290d700b10cf5ac10dcb68d264360405160405180910390a35050565b606560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166124eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e290615265565b60405180910390fd5b60006068600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008103612583576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161257a9061533d565b60405180910390fd5b60006066600084815260200190815260200160002054905080821461270d57600060676000858152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060676000868152602001908152602001600020600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060676000868152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826068600086815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050612772565b600060676000858152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006068600085815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506066600084815260200190815260200160002060008154809291906127ec9061535d565b91905055503373ffffffffffffffffffffffffffffffffffffffff16837f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3760405160405180910390a3505050565b600081612845612114565b1161291657612852611f13565b600401600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036129155760008103612910576128a0611f13565b6000015482106128dc576040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b6128e5611f13565b60040160008360019003935083815260200190815260200160002054905060008103612948576128dd565b612948565b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b606560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a9790615265565b60405180910390fd5b60006068600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008103612b38576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b2f906153d2565b60405180910390fd5b600060666000858152602001908152602001600020549050808214612cc257600060676000868152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060676000878152602001908152602001600020600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060676000878152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826068600087815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050612d27565b600060676000868152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006068600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550606660008581526020019081526020016000206000815480929190612da19061535d565b91905055508273ffffffffffffffffffffffffffffffffffffffff16847f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3760405160405180910390a350505050565b600033905090565b612e018261137b565b612e40576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e37906151f9565b60405180910390fd5b612e4c848484846134fc565b50505050565b6060612e5d82611f40565b612e93576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612e9d61356f565b90506000815103612ebd5760405180602001604052806000815250612ee8565b80612ec784613601565b604051602001612ed89291906153f2565b6040516020818303038152906040525b915050919050565b6000807fee151c8401928dc223602bb187aff91b9a56c7cae5476ef1b3287b085a16c85f90508091505090565b6000803090506000813b9050600081149250505090565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16612fa6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f9d90615488565b60405180910390fd5b612fb08282613651565b612fb86136b7565b5050565b6000612fc6611f13565b60000154905060008203613006576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6130136000848385613710565b600160406001901b178202613026611f13565b60050160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550613093836130846000866000613716565b61308d8561373e565b1761374e565b61309b611f13565b600401600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461313d57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050613102565b5060008203613178576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80613181611f13565b6000018190555050506131976000848385613779565b505050565b600033905090565b60006131af8261283a565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613216576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806132228461377f565b915091506132388187613233612df0565b6137af565b6132845761324d86613248612df0565b611a31565b613283576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036132ea576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6132f78686866001613710565b801561330257600082555b61330a611f13565b60050160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550613361611f13565b60050160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055506133e2856133be888887613716565b7c02000000000000000000000000000000000000000000000000000000001761374e565b6133ea611f13565b60040160008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084160361348c576000600185019050600061343b611f13565b6004016000838152602001908152602001600020540361348a5761345d611f13565b6000015481146134895783613470611f13565b6004016000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46134f48686866001613779565b505050505050565b613507848484610e20565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461356957613532848484846137f3565b613568576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b60606069805461357e90614405565b80601f01602080910402602001604051908101604052809291908181526020018280546135aa90614405565b80156135f75780601f106135cc576101008083540402835291602001916135f7565b820191906000526020600020905b8154815290600101906020018083116135da57829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b60011561363c57600184039350600a81066030018453600a810490508061361a575b50828103602084039350808452505050919050565b613659612ef0565b60000160019054906101000a900460ff166136a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136a09061551a565b60405180910390fd5b6136b38282613943565b5050565b600060019054906101000a900460ff16613706576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136fd90615488565b60405180910390fd5b61370e6139e8565b565b50505050565b60008060e883901c905060e861372d868684613a41565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b600080600061378c611f13565b600601600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613819612df0565b8786866040518563ffffffff1660e01b815260040161383b949392919061558f565b6020604051808303816000875af192505050801561387757506040513d601f19601f8201168201806040525081019061387491906155f0565b60015b6138f0573d80600081146138a7576040519150601f19603f3d011682016040523d82523d6000602084013e6138ac565b606091505b5060008151036138e8576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b61394b612ef0565b60000160019054906101000a900460ff1661399b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139929061551a565b60405180910390fd5b816139a4611f13565b60020190816139b3919061500c565b50806139bd611f13565b60030190816139cc919061500c565b506139d5612114565b6139dd611f13565b600001819055505050565b600060019054906101000a900460ff16613a37576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a2e90615488565b60405180910390fd5b613a3f613a4a565b565b60009392505050565b600060019054906101000a900460ff16613a99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a9090615488565b60405180910390fd5b613aa9613aa461319c565b61294d565b565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613af481613abf565b8114613aff57600080fd5b50565b600081359050613b1181613aeb565b92915050565b600060208284031215613b2d57613b2c613ab5565b5b6000613b3b84828501613b02565b91505092915050565b60008115159050919050565b613b5981613b44565b82525050565b6000602082019050613b746000830184613b50565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613bb4578082015181840152602081019050613b99565b60008484015250505050565b6000601f19601f8301169050919050565b6000613bdc82613b7a565b613be68185613b85565b9350613bf6818560208601613b96565b613bff81613bc0565b840191505092915050565b60006020820190508181036000830152613c248184613bd1565b905092915050565b6000819050919050565b613c3f81613c2c565b8114613c4a57600080fd5b50565b600081359050613c5c81613c36565b92915050565b600060208284031215613c7857613c77613ab5565b5b6000613c8684828501613c4d565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613cba82613c8f565b9050919050565b613cca81613caf565b82525050565b6000602082019050613ce56000830184613cc1565b92915050565b613cf481613caf565b8114613cff57600080fd5b50565b600081359050613d1181613ceb565b92915050565b60008060408385031215613d2e57613d2d613ab5565b5b6000613d3c85828601613c4d565b9250506020613d4d85828601613d02565b9150509250929050565b613d6081613c2c565b82525050565b6000602082019050613d7b6000830184613d57565b92915050565b60008060408385031215613d9857613d97613ab5565b5b6000613da685828601613d02565b9250506020613db785828601613c4d565b9150509250929050565b613dca81613b44565b8114613dd557600080fd5b50565b600081359050613de781613dc1565b92915050565b600060208284031215613e0357613e02613ab5565b5b6000613e1184828501613dd8565b91505092915050565b600080600060608486031215613e3357613e32613ab5565b5b6000613e4186828701613d02565b9350506020613e5286828701613d02565b9250506040613e6386828701613c4d565b9150509250925092565b60008060408385031215613e8457613e83613ab5565b5b6000613e9285828601613c4d565b9250506020613ea385828601613c4d565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f840112613ed257613ed1613ead565b5b8235905067ffffffffffffffff811115613eef57613eee613eb2565b5b602083019150836001820283011115613f0b57613f0a613eb7565b5b9250929050565b60008060208385031215613f2957613f28613ab5565b5b600083013567ffffffffffffffff811115613f4757613f46613aba565b5b613f5385828601613ebc565b92509250509250929050565b600060208284031215613f7557613f74613ab5565b5b6000613f8384828501613d02565b91505092915050565b60008060408385031215613fa357613fa2613ab5565b5b6000613fb185828601613d02565b9250506020613fc285828601613dd8565b9150509250929050565b60008083601f840112613fe257613fe1613ead565b5b8235905067ffffffffffffffff811115613fff57613ffe613eb2565b5b60208301915083602082028301111561401b5761401a613eb7565b5b9250929050565b60008083601f84011261403857614037613ead565b5b8235905067ffffffffffffffff81111561405557614054613eb2565b5b60208301915083602082028301111561407157614070613eb7565b5b9250929050565b6000806000806040858703121561409257614091613ab5565b5b600085013567ffffffffffffffff8111156140b0576140af613aba565b5b6140bc87828801613fcc565b9450945050602085013567ffffffffffffffff8111156140df576140de613aba565b5b6140eb87828801614022565b925092505092959194509250565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61413682613bc0565b810181811067ffffffffffffffff82111715614155576141546140fe565b5b80604052505050565b6000614168613aab565b9050614174828261412d565b919050565b600067ffffffffffffffff821115614194576141936140fe565b5b61419d82613bc0565b9050602081019050919050565b82818337600083830152505050565b60006141cc6141c784614179565b61415e565b9050828152602081018484840111156141e8576141e76140f9565b5b6141f38482856141aa565b509392505050565b600082601f8301126142105761420f613ead565b5b81356142208482602086016141b9565b91505092915050565b6000806000806080858703121561424357614242613ab5565b5b600061425187828801613d02565b945050602061426287828801613d02565b935050604061427387828801613c4d565b925050606085013567ffffffffffffffff81111561429457614293613aba565b5b6142a0878288016141fb565b91505092959194509250565b600080604083850312156142c3576142c2613ab5565b5b60006142d185828601613d02565b92505060206142e285828601613d02565b9150509250929050565b600067ffffffffffffffff821115614307576143066140fe565b5b61431082613bc0565b9050602081019050919050565b600061433061432b846142ec565b61415e565b90508281526020810184848401111561434c5761434b6140f9565b5b6143578482856141aa565b509392505050565b600082601f83011261437457614373613ead565b5b813561438484826020860161431d565b91505092915050565b6000602082840312156143a3576143a2613ab5565b5b600082013567ffffffffffffffff8111156143c1576143c0613aba565b5b6143cd8482850161435f565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061441d57607f821691505b6020821081036144305761442f6143d6565b5b50919050565b7f6d696e74206e6f7420656e61626c656400000000000000000000000000000000600082015250565b600061446c601083613b85565b915061447782614436565b602082019050919050565b6000602082019050818103600083015261449b8161445f565b9050919050565b7f736f6c64206f7574000000000000000000000000000000000000000000000000600082015250565b60006144d8600883613b85565b91506144e3826144a2565b602082019050919050565b60006020820190508181036000830152614507816144cb565b9050919050565b7f696e73756666696369656e742076616c75650000000000000000000000000000600082015250565b6000614544601283613b85565b915061454f8261450e565b602082019050919050565b6000602082019050818103600083015261457381614537565b9050919050565b7f7265616368656420746865206d6178696d756d00000000000000000000000000600082015250565b60006145b0601383613b85565b91506145bb8261457a565b602082019050919050565b600060208201905081810360008301526145df816145a3565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061462082613c2c565b915061462b83613c2c565b9250828201905080821115614643576146426145e6565b5b92915050565b7f7472616e73666572206e6f7420656e61626c6564000000000000000000000000600082015250565b600061467f601483613b85565b915061468a82614649565b602082019050919050565b600060208201905081810360008301526146ae81614672565b9050919050565b7f43616e6e6f74206275726e207374616b656420746f6b656e0000000000000000600082015250565b60006146eb601883613b85565b91506146f6826146b5565b602082019050919050565b6000602082019050818103600083015261471a816146de565b9050919050565b7f546f6b656e202165786973740000000000000000000000000000000000000000600082015250565b6000614757600c83613b85565b915061476282614721565b602082019050919050565b600060208201905081810360008301526147868161474a565b9050919050565b600081905092915050565b50565b60006147a860008361478d565b91506147b382614798565b600082019050919050565b60006147c98261479b565b9150819050919050565b7f5472616e73616374696f6e20556e7375636365737366756c0000000000000000600082015250565b6000614809601883613b85565b9150614814826147d3565b602082019050919050565b60006020820190508181036000830152614838816147fc565b9050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026148ac7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261486f565b6148b6868361486f565b95508019841693508086168417925050509392505050565b6000819050919050565b60006148f36148ee6148e984613c2c565b6148ce565b613c2c565b9050919050565b6000819050919050565b61490d836148d8565b614921614919826148fa565b84845461487c565b825550505050565b600090565b614936614929565b614941818484614904565b505050565b5b818110156149655761495a60008261492e565b600181019050614947565b5050565b601f8211156149aa5761497b8161484a565b6149848461485f565b81016020851015614993578190505b6149a761499f8561485f565b830182614946565b50505b505050565b600082821c905092915050565b60006149cd600019846008026149af565b1980831691505092915050565b60006149e683836149bc565b9150826002028217905092915050565b614a00838361483f565b67ffffffffffffffff811115614a1957614a186140fe565b5b614a238254614405565b614a2e828285614969565b6000601f831160018114614a5d5760008415614a4b578287013590505b614a5585826149da565b865550614abd565b601f198416614a6b8661484a565b60005b82811015614a9357848901358255600182019150602085019450602081019050614a6e565b86831015614ab05784890135614aac601f8916826149bc565b8355505b6001600288020188555050505b50505050505050565b7f63616c6c6572206d757374206265206f776e6572000000000000000000000000600082015250565b6000614afc601483613b85565b9150614b0782614ac6565b602082019050919050565b60006020820190508181036000830152614b2b81614aef565b9050919050565b7f616c7265616479207374616b696e670000000000000000000000000000000000600082015250565b6000614b68600f83613b85565b9150614b7382614b32565b602082019050919050565b60006020820190508181036000830152614b9781614b5b565b9050919050565b6000608082019050614bb36000830187613d57565b614bc06020830186613cc1565b614bcd6040830185613d57565b614bda6060830184613d57565b95945050505050565b6000606082019050614bf86000830186613d57565b614c056020830185613cc1565b614c126040830184613d57565b949350505050565b7f216c656e67746800000000000000000000000000000000000000000000000000600082015250565b6000614c50600783613b85565b9150614c5b82614c1a565b602082019050919050565b60006020820190508181036000830152614c7f81614c43565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000614cc082613c2c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614cf257614cf16145e6565b5b600182019050919050565b7f43616e6e6f74207472616e73666572207374616b656420746f6b656e00000000600082015250565b6000614d33601c83613b85565b9150614d3e82614cfd565b602082019050919050565b60006020820190508181036000830152614d6281614d26565b9050919050565b7f544f4b454e204e4f542045584953540000000000000000000000000000000000600082015250565b6000614d9f600f83613b85565b9150614daa82614d69565b602082019050919050565b60006020820190508181036000830152614dce81614d92565b9050919050565b600081905092915050565b6000614deb82613b7a565b614df58185614dd5565b9350614e05818560208601613b96565b80840191505092915050565b6000614e1e600083614dd5565b9150614e2982614798565b600082019050919050565b6000614e408284614de0565b9150614e4b82614e11565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614eb2602683613b85565b9150614ebd82614e56565b604082019050919050565b60006020820190508181036000830152614ee181614ea5565b9050919050565b7f455243373231415f5f496e697469616c697a61626c653a20636f6e747261637460008201527f20697320616c726561647920696e697469616c697a6564000000000000000000602082015250565b6000614f44603783613b85565b9150614f4f82614ee8565b604082019050919050565b60006020820190508181036000830152614f7381614f37565b9050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b6000614fd6602e83613b85565b9150614fe182614f7a565b604082019050919050565b6000602082019050818103600083015261500581614fc9565b9050919050565b61501582613b7a565b67ffffffffffffffff81111561502e5761502d6140fe565b5b6150388254614405565b615043828285614969565b600060209050601f8311600181146150765760008415615064578287015190505b61506e85826149da565b8655506150d6565b601f1984166150848661484a565b60005b828110156150ac57848901518255600182019150602085019450602081019050615087565b868310156150c957848901516150c5601f8916826149bc565b8355505b6001600288020188555050505b505050505050565b6000819050919050565b600060ff82169050919050565b600061511061510b615106846150de565b6148ce565b6150e8565b9050919050565b615120816150f5565b82525050565b600060208201905061513b6000830184615117565b92915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000615177602083613b85565b915061518282615141565b602082019050919050565b600060208201905081810360008301526151a68161516a565b9050919050565b7f546f6b656e206973206c6f636b65640000000000000000000000000000000000600082015250565b60006151e3600f83613b85565b91506151ee826151ad565b602082019050919050565b60006020820190508181036000830152615212816151d6565b9050919050565b7f43616e6e6f7420757064617465206d6170000000000000000000000000000000600082015250565b600061524f601183613b85565b915061525a82615219565b602082019050919050565b6000602082019050818103600083015261527e81615242565b9050919050565b7f494420616c7265616479206c6f636b65642062792063616c6c65720000000000600082015250565b60006152bb601b83613b85565b91506152c682615285565b602082019050919050565b600060208201905081810360008301526152ea816152ae565b9050919050565b7f4944206e6f74206c6f636b65642062792063616c6c6572000000000000000000600082015250565b6000615327601783613b85565b9150615332826152f1565b602082019050919050565b600060208201905081810360008301526153568161531a565b9050919050565b600061536882613c2c565b91506000820361537b5761537a6145e6565b5b600182039050919050565b7f4944206e6f74206c6f636b656400000000000000000000000000000000000000600082015250565b60006153bc600d83613b85565b91506153c782615386565b602082019050919050565b600060208201905081810360008301526153eb816153af565b9050919050565b60006153fe8285614de0565b915061540a8284614de0565b91508190509392505050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b6000615472602b83613b85565b915061547d82615416565b604082019050919050565b600060208201905081810360008301526154a181615465565b9050919050565b7f455243373231415f5f496e697469616c697a61626c653a20636f6e747261637460008201527f206973206e6f7420696e697469616c697a696e67000000000000000000000000602082015250565b6000615504603483613b85565b915061550f826154a8565b604082019050919050565b60006020820190508181036000830152615533816154f7565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006155618261553a565b61556b8185615545565b935061557b818560208601613b96565b61558481613bc0565b840191505092915050565b60006080820190506155a46000830187613cc1565b6155b16020830186613cc1565b6155be6040830185613d57565b81810360608301526155d08184615556565b905095945050505050565b6000815190506155ea81613aeb565b92915050565b60006020828403121561560657615605613ab5565b5b6000615614848285016155db565b9150509291505056fea2646970667358221220321e763c4fd1287bd7ba5a352690e041ec27075cf13ef789803f86e9a3848bf464736f6c63430008120033
Deployed Bytecode
0x60806040526004361061025c5760003560e01c8063650b00f611610144578063ac52e644116100b6578063d5abeb011161007a578063d5abeb01146108e9578063e58306f914610914578063e985e9c51461093d578063f2fde38b1461097a578063f4a0a528146109a3578063f62d1888146109cc5761025c565b8063ac52e644146107ed578063b1a6505f14610816578063b88d4fde14610853578063c6004ed61461086f578063c87b56dd146108ac5761025c565b80638da5cb5b116101085780638da5cb5b146106f157806394d216d61461071c57806395d89b4114610745578063a0c5407814610770578063a22cb4651461079b578063a694fc3a146107c45761025c565b8063650b00f6146105f85780636817c76c1461063557806370a0823114610660578063715018a61461069d57806372abc8b7146106b45761025c565b80632cba8123116101dd578063453c2310116101a1578063453c2310146104d8578063493770cc1461050357806349a758a31461052c57806355f804b3146105695780635d3eea91146105925780636352211e146105bb5761025c565b80632cba81231461040257806335b504c51461043f5780633ccfd60b1461047c57806340a9c8df1461049357806342842e0e146104bc5761025c565b80631249c58b116102245780631249c58b1461035f57806318160ddd146103695780631f85e3ca1461039457806323b872dd146103bd5780632799cde0146103d95761025c565b806301ffc9a71461026157806306fdde031461029e578063081812fc146102c957806309308e5d14610306578063095ea7b314610343575b600080fd5b34801561026d57600080fd5b5061028860048036038101906102839190613b17565b6109f5565b6040516102959190613b5f565b60405180910390f35b3480156102aa57600080fd5b506102b3610a56565b6040516102c09190613c0a565b60405180910390f35b3480156102d557600080fd5b506102f060048036038101906102eb9190613c62565b610af1565b6040516102fd9190613cd0565b60405180910390f35b34801561031257600080fd5b5061032d60048036038101906103289190613d17565b610b79565b60405161033a9190613d66565b60405180910390f35b61035d60048036038101906103589190613d81565b610b9e565b005b610367610bae565b005b34801561037557600080fd5b5061037e610dd2565b60405161038b9190613d66565b60405180910390f35b3480156103a057600080fd5b506103bb60048036038101906103b69190613ded565b610dfb565b005b6103d760048036038101906103d29190613e1a565b610e20565b005b3480156103e557600080fd5b5061040060048036038101906103fb9190613c62565b610ed5565b005b34801561040e57600080fd5b5061042960048036038101906104249190613e6d565b610f29565b6040516104369190613cd0565b60405180910390f35b34801561044b57600080fd5b5061046660048036038101906104619190613c62565b610f6b565b6040516104739190613d66565b60405180910390f35b34801561048857600080fd5b50610491610f83565b005b34801561049f57600080fd5b506104ba60048036038101906104b59190613c62565b611048565b005b6104d660048036038101906104d19190613e1a565b61109c565b005b3480156104e457600080fd5b506104ed6110bc565b6040516104fa9190613d66565b60405180910390f35b34801561050f57600080fd5b5061052a60048036038101906105259190613ded565b6110c2565b005b34801561053857600080fd5b50610553600480360381019061054e9190613c62565b6110e7565b6040516105609190613cd0565b60405180910390f35b34801561057557600080fd5b50610590600480360381019061058b9190613f12565b61111a565b005b34801561059e57600080fd5b506105b960048036038101906105b49190613c62565b611138565b005b3480156105c757600080fd5b506105e260048036038101906105dd9190613c62565b611276565b6040516105ef9190613cd0565b60405180910390f35b34801561060457600080fd5b5061061f600480360381019061061a9190613c62565b611288565b60405161062c9190613d66565b60405180910390f35b34801561064157600080fd5b5061064a6112a0565b6040516106579190613d66565b60405180910390f35b34801561066c57600080fd5b5061068760048036038101906106829190613f5f565b6112a6565b6040516106949190613d66565b60405180910390f35b3480156106a957600080fd5b506106b2611367565b005b3480156106c057600080fd5b506106db60048036038101906106d69190613c62565b61137b565b6040516106e89190613b5f565b60405180910390f35b3480156106fd57600080fd5b5061070661139a565b6040516107139190613cd0565b60405180910390f35b34801561072857600080fd5b50610743600480360381019061073e9190613d17565b6113c4565b005b34801561075157600080fd5b5061075a61141a565b6040516107679190613c0a565b60405180910390f35b34801561077c57600080fd5b506107856114b5565b6040516107929190613c0a565b60405180910390f35b3480156107a757600080fd5b506107c260048036038101906107bd9190613f8c565b611543565b005b3480156107d057600080fd5b506107eb60048036038101906107e69190613c62565b611657565b005b3480156107f957600080fd5b50610814600480360381019061080f9190614078565b61178c565b005b34801561082257600080fd5b5061083d60048036038101906108389190613f5f565b6118a9565b60405161084a9190613b5f565b60405180910390f35b61086d60048036038101906108689190614229565b6118c9565b005b34801561087b57600080fd5b5061089660048036038101906108919190613f5f565b611980565b6040516108a39190613d66565b60405180910390f35b3480156108b857600080fd5b506108d360048036038101906108ce9190613c62565b611998565b6040516108e09190613c0a565b60405180910390f35b3480156108f557600080fd5b506108fe611a11565b60405161090b9190613d66565b60405180910390f35b34801561092057600080fd5b5061093b60048036038101906109369190613d81565b611a1b565b005b34801561094957600080fd5b50610964600480360381019061095f91906142ac565b611a31565b6040516109719190613b5f565b60405180910390f35b34801561098657600080fd5b506109a1600480360381019061099c9190613f5f565b611ace565b005b3480156109af57600080fd5b506109ca60048036038101906109c59190613c62565b611b51565b005b3480156109d857600080fd5b506109f360048036038101906109ee919061438d565b611b63565b005b600063706e848960e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a4f5750610a4e82611e81565b5b9050919050565b6060610a60611f13565b6002018054610a6e90614405565b80601f0160208091040260200160405190810160405280929190818152602001828054610a9a90614405565b8015610ae75780601f10610abc57610100808354040283529160200191610ae7565b820191906000526020600020905b815481529060010190602001808311610aca57829003601f168201915b5050505050905090565b6000610afc82611f40565b610b32576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b3a611f13565b600601600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6068602052816000526040600020602052806000526040600020600091509150505481565b610baa82826001611fb1565b5050565b606c60019054906101000a900460ff16610bfd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf490614482565b60405180910390fd5b610c05611a11565b610c0d610dd2565b10610c4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c44906144ee565b60405180910390fd5b606b54341015610c92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c899061455a565b60405180910390fd5b606a54606d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410610d15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0c906145c6565b60405180910390fd5b6001606d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610d659190614615565b92505081905550610d77336001612106565b33606e6000610d84610dd2565b815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000610ddc612114565b610de4611f13565b60010154610df0611f13565b600001540303905090565b610e0361211d565b80606c60016101000a81548160ff02191690831515021790555050565b606c60009054906101000a900460ff16610e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6690614695565b60405180910390fd5b6000606f60008381526020019081526020016000205414610ec5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ebc90614701565b60405180910390fd5b610ed083838361219b565b505050565b610ede81611f40565b610f1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f149061476d565b60405180910390fd5b610f26816121f3565b50565b60676020528160005260406000206020528060005260406000206000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606f6020528060005260406000206000915090505481565b610f8b61211d565b6000479050600033905060008173ffffffffffffffffffffffffffffffffffffffff1683604051610fbb906147be565b60006040518083038185875af1925050503d8060008114610ff8576040519150601f19603f3d011682016040523d82523d6000602084013e610ffd565b606091505b50508091505080611043576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103a9061481f565b60405180910390fd5b505050565b61105181611f40565b611090576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110879061476d565b60405180910390fd5b6110998161245f565b50565b6110b7838383604051806020016040528060008152506118c9565b505050565b606a5481565b6110ca61211d565b80606c60006101000a81548160ff02191690831515021790555050565b606e6020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61112261211d565b8181606991826111339291906149f6565b505050565b61114181611276565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146111ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a590614b12565b60405180910390fd5b6000606f60008381526020019081526020016000205414611204576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111fb90614b7e565b60405180910390fd5b6000606f60008381526020019081526020016000205490506000606f6000848152602001908152602001600020819055507fc1e00202ee2c06861d326fc6374026b751863ff64218ccbaa38c3e603a8e72c28233834260405161126a9493929190614b9e565b60405180910390a15050565b60006112818261283a565b9050919050565b60666020528060005260406000206000915090505481565b606b5481565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361130d576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff61131e611f13565b60050160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b61136f61211d565b611379600061294d565b565b6000806066600084815260200190815260200160002054149050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6113cd82611f40565b61140c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114039061476d565b60405180910390fd5b6114168282612a13565b5050565b6060611424611f13565b600301805461143290614405565b80601f016020809104026020016040519081016040528092919081815260200182805461145e90614405565b80156114ab5780601f10611480576101008083540402835291602001916114ab565b820191906000526020600020905b81548152906001019060200180831161148e57829003601f168201915b5050505050905090565b606980546114c290614405565b80601f01602080910402602001604051908101604052809291908181526020018280546114ee90614405565b801561153b5780601f106115105761010080835404028352916020019161153b565b820191906000526020600020905b81548152906001019060200180831161151e57829003601f168201915b505050505081565b8061154c611f13565b6007016000611559612df0565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611606612df0565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161164b9190613b5f565b60405180910390a35050565b61166081611276565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116c490614b12565b60405180910390fd5b6000606f60008381526020019081526020016000205414611723576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161171a90614b7e565b60405180910390fd5b42606f6000838152602001908152602001600020819055507f02567b2553aeb44e4ddd5d68462774dc3de158cb0f2c2da1740e729b22086aff8133606f60008581526020019081526020016000205460405161178193929190614be3565b60405180910390a150565b61179461211d565b8181905084849050146117dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117d390614c66565b60405180910390fd5b60005b848490508110156118a2578282828181106117fd576117fc614c86565b5b90506020020160208101906118129190613ded565b6065600087878581811061182957611828614c86565b5b905060200201602081019061183e9190613f5f565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061189a90614cb5565b9150506117df565b5050505050565b60656020528060005260406000206000915054906101000a900460ff1681565b606c60009054906101000a900460ff16611918576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161190f90614695565b60405180910390fd5b6000606f6000848152602001908152602001600020541461196e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196590614d49565b60405180910390fd5b61197a84848484612df8565b50505050565b606d6020528060005260406000206000915090505481565b60606119a382611f40565b6119e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119d990614db5565b60405180910390fd5b6119eb82612e52565b6040516020016119fb9190614e34565b6040516020818303038152906040529050919050565b6000612710905090565b611a2361211d565b611a2d8282612106565b5050565b6000611a3b611f13565b60070160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611ad661211d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611b45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3c90614ec8565b60405180910390fd5b611b4e8161294d565b50565b611b5961211d565b80606b8190555050565b611b6b612ef0565b60000160019054906101000a900460ff16611b9f57611b88612ef0565b60000160009054906101000a900460ff1615611ba8565b611ba7612f1d565b5b611be7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bde90614f5a565b60405180910390fd5b6000611bf1612ef0565b60000160019054906101000a900460ff161590508015611c54576001611c15612ef0565b60000160016101000a81548160ff0219169083151502179055506001611c39612ef0565b60000160006101000a81548160ff0219169083151502179055505b60008060019054906101000a900460ff16159050808015611c855750600160008054906101000a900460ff1660ff16105b80611cb25750611c9430612f34565b158015611cb15750600160008054906101000a900460ff1660ff16145b5b611cf1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce890614fec565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015611d2e576001600060016101000a81548160ff0219169083151502179055505b611da26040518060400160405280601e81526020017f5461746120417661746172206279204a756c69616e277320456469746f7200008152506040518060400160405280600481526020017f5441544100000000000000000000000000000000000000000000000000000000815250612f57565b8260699081611db1919061500c565b506001606c60006101000a81548160ff0219169083151502179055506000606c60016101000a81548160ff0219169083151502179055506001606a819055506000606b819055508015611e515760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986001604051611e489190615126565b60405180910390a15b508015611e7d576000611e62612ef0565b60000160016101000a81548160ff0219169083151502179055505b5050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611edc57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611f0c5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6000807f2569078dfb4b0305704d3008e7403993ae9601b85f7ae5e742de3de8f8011c4090508091505090565b600081611f4b612114565b11158015611f635750611f5c611f13565b6000015482105b8015611faa575060007c0100000000000000000000000000000000000000000000000000000000611f92611f13565b60040160008581526020019081526020016000205416145b9050919050565b6000611fbc83611276565b90508115612047578073ffffffffffffffffffffffffffffffffffffffff16611fe3612df0565b73ffffffffffffffffffffffffffffffffffffffff16146120465761200f8161200a612df0565b611a31565b612045576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b83612050611f13565b600601600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b6121108282612fbc565b5050565b60006001905090565b61212561319c565b73ffffffffffffffffffffffffffffffffffffffff1661214361139a565b73ffffffffffffffffffffffffffffffffffffffff1614612199576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121909061518d565b60405180910390fd5b565b6121a48161137b565b6121e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121da906151f9565b60405180910390fd5b6121ee8383836131a4565b505050565b606560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661227f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161227690615265565b60405180910390fd5b60006068600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414612312576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612309906152d1565b60405180910390fd5b6000600160666000848152602001908152602001600020546123349190614615565b90503360676000848152602001908152602001600020600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806068600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060666000838152602001908152602001600020600081548092919061241290614cb5565b91905055503373ffffffffffffffffffffffffffffffffffffffff16827f9ecfd70e9ff36df72989324a49559383d39f9290d700b10cf5ac10dcb68d264360405160405180910390a35050565b606560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166124eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e290615265565b60405180910390fd5b60006068600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008103612583576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161257a9061533d565b60405180910390fd5b60006066600084815260200190815260200160002054905080821461270d57600060676000858152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060676000868152602001908152602001600020600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060676000868152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826068600086815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050612772565b600060676000858152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006068600085815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506066600084815260200190815260200160002060008154809291906127ec9061535d565b91905055503373ffffffffffffffffffffffffffffffffffffffff16837f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3760405160405180910390a3505050565b600081612845612114565b1161291657612852611f13565b600401600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036129155760008103612910576128a0611f13565b6000015482106128dc576040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b6128e5611f13565b60040160008360019003935083815260200190815260200160002054905060008103612948576128dd565b612948565b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b606560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a9790615265565b60405180910390fd5b60006068600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008103612b38576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b2f906153d2565b60405180910390fd5b600060666000858152602001908152602001600020549050808214612cc257600060676000868152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060676000878152602001908152602001600020600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060676000878152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826068600087815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050612d27565b600060676000868152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006068600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550606660008581526020019081526020016000206000815480929190612da19061535d565b91905055508273ffffffffffffffffffffffffffffffffffffffff16847f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3760405160405180910390a350505050565b600033905090565b612e018261137b565b612e40576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e37906151f9565b60405180910390fd5b612e4c848484846134fc565b50505050565b6060612e5d82611f40565b612e93576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612e9d61356f565b90506000815103612ebd5760405180602001604052806000815250612ee8565b80612ec784613601565b604051602001612ed89291906153f2565b6040516020818303038152906040525b915050919050565b6000807fee151c8401928dc223602bb187aff91b9a56c7cae5476ef1b3287b085a16c85f90508091505090565b6000803090506000813b9050600081149250505090565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16612fa6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f9d90615488565b60405180910390fd5b612fb08282613651565b612fb86136b7565b5050565b6000612fc6611f13565b60000154905060008203613006576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6130136000848385613710565b600160406001901b178202613026611f13565b60050160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550613093836130846000866000613716565b61308d8561373e565b1761374e565b61309b611f13565b600401600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461313d57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050613102565b5060008203613178576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80613181611f13565b6000018190555050506131976000848385613779565b505050565b600033905090565b60006131af8261283a565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613216576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806132228461377f565b915091506132388187613233612df0565b6137af565b6132845761324d86613248612df0565b611a31565b613283576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036132ea576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6132f78686866001613710565b801561330257600082555b61330a611f13565b60050160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550613361611f13565b60050160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055506133e2856133be888887613716565b7c02000000000000000000000000000000000000000000000000000000001761374e565b6133ea611f13565b60040160008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084160361348c576000600185019050600061343b611f13565b6004016000838152602001908152602001600020540361348a5761345d611f13565b6000015481146134895783613470611f13565b6004016000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46134f48686866001613779565b505050505050565b613507848484610e20565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461356957613532848484846137f3565b613568576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b60606069805461357e90614405565b80601f01602080910402602001604051908101604052809291908181526020018280546135aa90614405565b80156135f75780601f106135cc576101008083540402835291602001916135f7565b820191906000526020600020905b8154815290600101906020018083116135da57829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b60011561363c57600184039350600a81066030018453600a810490508061361a575b50828103602084039350808452505050919050565b613659612ef0565b60000160019054906101000a900460ff166136a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136a09061551a565b60405180910390fd5b6136b38282613943565b5050565b600060019054906101000a900460ff16613706576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136fd90615488565b60405180910390fd5b61370e6139e8565b565b50505050565b60008060e883901c905060e861372d868684613a41565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b600080600061378c611f13565b600601600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613819612df0565b8786866040518563ffffffff1660e01b815260040161383b949392919061558f565b6020604051808303816000875af192505050801561387757506040513d601f19601f8201168201806040525081019061387491906155f0565b60015b6138f0573d80600081146138a7576040519150601f19603f3d011682016040523d82523d6000602084013e6138ac565b606091505b5060008151036138e8576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b61394b612ef0565b60000160019054906101000a900460ff1661399b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139929061551a565b60405180910390fd5b816139a4611f13565b60020190816139b3919061500c565b50806139bd611f13565b60030190816139cc919061500c565b506139d5612114565b6139dd611f13565b600001819055505050565b600060019054906101000a900460ff16613a37576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a2e90615488565b60405180910390fd5b613a3f613a4a565b565b60009392505050565b600060019054906101000a900460ff16613a99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a9090615488565b60405180910390fd5b613aa9613aa461319c565b61294d565b565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613af481613abf565b8114613aff57600080fd5b50565b600081359050613b1181613aeb565b92915050565b600060208284031215613b2d57613b2c613ab5565b5b6000613b3b84828501613b02565b91505092915050565b60008115159050919050565b613b5981613b44565b82525050565b6000602082019050613b746000830184613b50565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613bb4578082015181840152602081019050613b99565b60008484015250505050565b6000601f19601f8301169050919050565b6000613bdc82613b7a565b613be68185613b85565b9350613bf6818560208601613b96565b613bff81613bc0565b840191505092915050565b60006020820190508181036000830152613c248184613bd1565b905092915050565b6000819050919050565b613c3f81613c2c565b8114613c4a57600080fd5b50565b600081359050613c5c81613c36565b92915050565b600060208284031215613c7857613c77613ab5565b5b6000613c8684828501613c4d565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613cba82613c8f565b9050919050565b613cca81613caf565b82525050565b6000602082019050613ce56000830184613cc1565b92915050565b613cf481613caf565b8114613cff57600080fd5b50565b600081359050613d1181613ceb565b92915050565b60008060408385031215613d2e57613d2d613ab5565b5b6000613d3c85828601613c4d565b9250506020613d4d85828601613d02565b9150509250929050565b613d6081613c2c565b82525050565b6000602082019050613d7b6000830184613d57565b92915050565b60008060408385031215613d9857613d97613ab5565b5b6000613da685828601613d02565b9250506020613db785828601613c4d565b9150509250929050565b613dca81613b44565b8114613dd557600080fd5b50565b600081359050613de781613dc1565b92915050565b600060208284031215613e0357613e02613ab5565b5b6000613e1184828501613dd8565b91505092915050565b600080600060608486031215613e3357613e32613ab5565b5b6000613e4186828701613d02565b9350506020613e5286828701613d02565b9250506040613e6386828701613c4d565b9150509250925092565b60008060408385031215613e8457613e83613ab5565b5b6000613e9285828601613c4d565b9250506020613ea385828601613c4d565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f840112613ed257613ed1613ead565b5b8235905067ffffffffffffffff811115613eef57613eee613eb2565b5b602083019150836001820283011115613f0b57613f0a613eb7565b5b9250929050565b60008060208385031215613f2957613f28613ab5565b5b600083013567ffffffffffffffff811115613f4757613f46613aba565b5b613f5385828601613ebc565b92509250509250929050565b600060208284031215613f7557613f74613ab5565b5b6000613f8384828501613d02565b91505092915050565b60008060408385031215613fa357613fa2613ab5565b5b6000613fb185828601613d02565b9250506020613fc285828601613dd8565b9150509250929050565b60008083601f840112613fe257613fe1613ead565b5b8235905067ffffffffffffffff811115613fff57613ffe613eb2565b5b60208301915083602082028301111561401b5761401a613eb7565b5b9250929050565b60008083601f84011261403857614037613ead565b5b8235905067ffffffffffffffff81111561405557614054613eb2565b5b60208301915083602082028301111561407157614070613eb7565b5b9250929050565b6000806000806040858703121561409257614091613ab5565b5b600085013567ffffffffffffffff8111156140b0576140af613aba565b5b6140bc87828801613fcc565b9450945050602085013567ffffffffffffffff8111156140df576140de613aba565b5b6140eb87828801614022565b925092505092959194509250565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61413682613bc0565b810181811067ffffffffffffffff82111715614155576141546140fe565b5b80604052505050565b6000614168613aab565b9050614174828261412d565b919050565b600067ffffffffffffffff821115614194576141936140fe565b5b61419d82613bc0565b9050602081019050919050565b82818337600083830152505050565b60006141cc6141c784614179565b61415e565b9050828152602081018484840111156141e8576141e76140f9565b5b6141f38482856141aa565b509392505050565b600082601f8301126142105761420f613ead565b5b81356142208482602086016141b9565b91505092915050565b6000806000806080858703121561424357614242613ab5565b5b600061425187828801613d02565b945050602061426287828801613d02565b935050604061427387828801613c4d565b925050606085013567ffffffffffffffff81111561429457614293613aba565b5b6142a0878288016141fb565b91505092959194509250565b600080604083850312156142c3576142c2613ab5565b5b60006142d185828601613d02565b92505060206142e285828601613d02565b9150509250929050565b600067ffffffffffffffff821115614307576143066140fe565b5b61431082613bc0565b9050602081019050919050565b600061433061432b846142ec565b61415e565b90508281526020810184848401111561434c5761434b6140f9565b5b6143578482856141aa565b509392505050565b600082601f83011261437457614373613ead565b5b813561438484826020860161431d565b91505092915050565b6000602082840312156143a3576143a2613ab5565b5b600082013567ffffffffffffffff8111156143c1576143c0613aba565b5b6143cd8482850161435f565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061441d57607f821691505b6020821081036144305761442f6143d6565b5b50919050565b7f6d696e74206e6f7420656e61626c656400000000000000000000000000000000600082015250565b600061446c601083613b85565b915061447782614436565b602082019050919050565b6000602082019050818103600083015261449b8161445f565b9050919050565b7f736f6c64206f7574000000000000000000000000000000000000000000000000600082015250565b60006144d8600883613b85565b91506144e3826144a2565b602082019050919050565b60006020820190508181036000830152614507816144cb565b9050919050565b7f696e73756666696369656e742076616c75650000000000000000000000000000600082015250565b6000614544601283613b85565b915061454f8261450e565b602082019050919050565b6000602082019050818103600083015261457381614537565b9050919050565b7f7265616368656420746865206d6178696d756d00000000000000000000000000600082015250565b60006145b0601383613b85565b91506145bb8261457a565b602082019050919050565b600060208201905081810360008301526145df816145a3565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061462082613c2c565b915061462b83613c2c565b9250828201905080821115614643576146426145e6565b5b92915050565b7f7472616e73666572206e6f7420656e61626c6564000000000000000000000000600082015250565b600061467f601483613b85565b915061468a82614649565b602082019050919050565b600060208201905081810360008301526146ae81614672565b9050919050565b7f43616e6e6f74206275726e207374616b656420746f6b656e0000000000000000600082015250565b60006146eb601883613b85565b91506146f6826146b5565b602082019050919050565b6000602082019050818103600083015261471a816146de565b9050919050565b7f546f6b656e202165786973740000000000000000000000000000000000000000600082015250565b6000614757600c83613b85565b915061476282614721565b602082019050919050565b600060208201905081810360008301526147868161474a565b9050919050565b600081905092915050565b50565b60006147a860008361478d565b91506147b382614798565b600082019050919050565b60006147c98261479b565b9150819050919050565b7f5472616e73616374696f6e20556e7375636365737366756c0000000000000000600082015250565b6000614809601883613b85565b9150614814826147d3565b602082019050919050565b60006020820190508181036000830152614838816147fc565b9050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026148ac7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261486f565b6148b6868361486f565b95508019841693508086168417925050509392505050565b6000819050919050565b60006148f36148ee6148e984613c2c565b6148ce565b613c2c565b9050919050565b6000819050919050565b61490d836148d8565b614921614919826148fa565b84845461487c565b825550505050565b600090565b614936614929565b614941818484614904565b505050565b5b818110156149655761495a60008261492e565b600181019050614947565b5050565b601f8211156149aa5761497b8161484a565b6149848461485f565b81016020851015614993578190505b6149a761499f8561485f565b830182614946565b50505b505050565b600082821c905092915050565b60006149cd600019846008026149af565b1980831691505092915050565b60006149e683836149bc565b9150826002028217905092915050565b614a00838361483f565b67ffffffffffffffff811115614a1957614a186140fe565b5b614a238254614405565b614a2e828285614969565b6000601f831160018114614a5d5760008415614a4b578287013590505b614a5585826149da565b865550614abd565b601f198416614a6b8661484a565b60005b82811015614a9357848901358255600182019150602085019450602081019050614a6e565b86831015614ab05784890135614aac601f8916826149bc565b8355505b6001600288020188555050505b50505050505050565b7f63616c6c6572206d757374206265206f776e6572000000000000000000000000600082015250565b6000614afc601483613b85565b9150614b0782614ac6565b602082019050919050565b60006020820190508181036000830152614b2b81614aef565b9050919050565b7f616c7265616479207374616b696e670000000000000000000000000000000000600082015250565b6000614b68600f83613b85565b9150614b7382614b32565b602082019050919050565b60006020820190508181036000830152614b9781614b5b565b9050919050565b6000608082019050614bb36000830187613d57565b614bc06020830186613cc1565b614bcd6040830185613d57565b614bda6060830184613d57565b95945050505050565b6000606082019050614bf86000830186613d57565b614c056020830185613cc1565b614c126040830184613d57565b949350505050565b7f216c656e67746800000000000000000000000000000000000000000000000000600082015250565b6000614c50600783613b85565b9150614c5b82614c1a565b602082019050919050565b60006020820190508181036000830152614c7f81614c43565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000614cc082613c2c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614cf257614cf16145e6565b5b600182019050919050565b7f43616e6e6f74207472616e73666572207374616b656420746f6b656e00000000600082015250565b6000614d33601c83613b85565b9150614d3e82614cfd565b602082019050919050565b60006020820190508181036000830152614d6281614d26565b9050919050565b7f544f4b454e204e4f542045584953540000000000000000000000000000000000600082015250565b6000614d9f600f83613b85565b9150614daa82614d69565b602082019050919050565b60006020820190508181036000830152614dce81614d92565b9050919050565b600081905092915050565b6000614deb82613b7a565b614df58185614dd5565b9350614e05818560208601613b96565b80840191505092915050565b6000614e1e600083614dd5565b9150614e2982614798565b600082019050919050565b6000614e408284614de0565b9150614e4b82614e11565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614eb2602683613b85565b9150614ebd82614e56565b604082019050919050565b60006020820190508181036000830152614ee181614ea5565b9050919050565b7f455243373231415f5f496e697469616c697a61626c653a20636f6e747261637460008201527f20697320616c726561647920696e697469616c697a6564000000000000000000602082015250565b6000614f44603783613b85565b9150614f4f82614ee8565b604082019050919050565b60006020820190508181036000830152614f7381614f37565b9050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b6000614fd6602e83613b85565b9150614fe182614f7a565b604082019050919050565b6000602082019050818103600083015261500581614fc9565b9050919050565b61501582613b7a565b67ffffffffffffffff81111561502e5761502d6140fe565b5b6150388254614405565b615043828285614969565b600060209050601f8311600181146150765760008415615064578287015190505b61506e85826149da565b8655506150d6565b601f1984166150848661484a565b60005b828110156150ac57848901518255600182019150602085019450602081019050615087565b868310156150c957848901516150c5601f8916826149bc565b8355505b6001600288020188555050505b505050505050565b6000819050919050565b600060ff82169050919050565b600061511061510b615106846150de565b6148ce565b6150e8565b9050919050565b615120816150f5565b82525050565b600060208201905061513b6000830184615117565b92915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000615177602083613b85565b915061518282615141565b602082019050919050565b600060208201905081810360008301526151a68161516a565b9050919050565b7f546f6b656e206973206c6f636b65640000000000000000000000000000000000600082015250565b60006151e3600f83613b85565b91506151ee826151ad565b602082019050919050565b60006020820190508181036000830152615212816151d6565b9050919050565b7f43616e6e6f7420757064617465206d6170000000000000000000000000000000600082015250565b600061524f601183613b85565b915061525a82615219565b602082019050919050565b6000602082019050818103600083015261527e81615242565b9050919050565b7f494420616c7265616479206c6f636b65642062792063616c6c65720000000000600082015250565b60006152bb601b83613b85565b91506152c682615285565b602082019050919050565b600060208201905081810360008301526152ea816152ae565b9050919050565b7f4944206e6f74206c6f636b65642062792063616c6c6572000000000000000000600082015250565b6000615327601783613b85565b9150615332826152f1565b602082019050919050565b600060208201905081810360008301526153568161531a565b9050919050565b600061536882613c2c565b91506000820361537b5761537a6145e6565b5b600182039050919050565b7f4944206e6f74206c6f636b656400000000000000000000000000000000000000600082015250565b60006153bc600d83613b85565b91506153c782615386565b602082019050919050565b600060208201905081810360008301526153eb816153af565b9050919050565b60006153fe8285614de0565b915061540a8284614de0565b91508190509392505050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b6000615472602b83613b85565b915061547d82615416565b604082019050919050565b600060208201905081810360008301526154a181615465565b9050919050565b7f455243373231415f5f496e697469616c697a61626c653a20636f6e747261637460008201527f206973206e6f7420696e697469616c697a696e67000000000000000000000000602082015250565b6000615504603483613b85565b915061550f826154a8565b604082019050919050565b60006020820190508181036000830152615533816154f7565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006155618261553a565b61556b8185615545565b935061557b818560208601613b96565b61558481613bc0565b840191505092915050565b60006080820190506155a46000830187613cc1565b6155b16020830186613cc1565b6155be6040830185613d57565b81810360608301526155d08184615556565b905095945050505050565b6000815190506155ea81613aeb565b92915050565b60006020828403121561560657615605613ab5565b5b6000615614848285016155db565b9150509291505056fea2646970667358221220321e763c4fd1287bd7ba5a352690e041ec27075cf13ef789803f86e9a3848bf464736f6c63430008120033
Deployed Bytecode Sourcemap
141316:4556:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89619:292;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51949:124;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59154:292;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;23911:94;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58830:165;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;142397:412;;;:::i;:::-;;47152:422;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;143844:103;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;144801:363;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;90549:134;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;23833:71;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;141602:53;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;145591:278;;;;;;;;;;;;;:::i;:::-;;90691:138;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;66537:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;141382:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;143955:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;141549:46;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;143553:108;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;144413:380;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53487:202;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;23773:53;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;141416:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48483:333;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22403:103;;;;;;;;;;;;;:::i;:::-;;24353:114;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21762:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90837:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;52149:128;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;141352:23;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59786:314;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;144082:323;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;24475;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;23709:57;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;145172:411;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;141499:43;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;143298:247;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;142932:82;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;142270:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60257:238;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22661;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;143742:94;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;141924:338;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;89619:292;89770:4;89362:10;89828:21;;89812:37;;;:12;:37;;;;:91;;;;89866:37;89890:12;89866:23;:37::i;:::-;89812:91;89792:111;;89619:292;;;:::o;51949:124::-;52003:13;52036:23;:21;:23::i;:::-;:29;;52029:36;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51949:124;:::o;59154:292::-;59275:7;59305:16;59313:7;59305;:16::i;:::-;59300:64;;59330:34;;;;;;;;;;;;;;59300:64;59384:23;:21;:23::i;:::-;:39;;:48;59424:7;59384:48;;;;;;;;;;;:54;;;;;;;;;;;;59377:61;;59154:292;;;:::o;23911:94::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;58830:165::-;58960:27;58969:2;58973:7;58982:4;58960:8;:27::i;:::-;58830:165;;:::o;142397:412::-;142447:10;;;;;;;;;;;142439:39;;;;;;;;;;;;:::i;:::-;;;;;;;;;142513:11;:9;:11::i;:::-;142497:13;:11;:13::i;:::-;:27;142489:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;142569:9;;142556;:22;;142548:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;142643:12;;142620:8;:20;142629:10;142620:20;;;;;;;;;;;;;;;;:35;142612:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;142716:1;142692:8;:20;142701:10;142692:20;;;;;;;;;;;;;;;;:25;;;;;;;:::i;:::-;;;;;;;;142728:23;142737:10;142749:1;142728:8;:23::i;:::-;142791:10;142762:11;:26;142774:13;:11;:13::i;:::-;142762:26;;;;;;;;;;;;:39;;;;;;;;;;;;;;;;;;142397:412::o;47152:422::-;47213:7;47540:15;:13;:15::i;:::-;47484:23;:21;:23::i;:::-;:36;;;47427:23;:21;:23::i;:::-;:37;;;:93;:128;47403:152;;47152:422;:::o;143844:103::-;21648:13;:11;:13::i;:::-;143928:11:::1;143915:10;;:24;;;;;;;;;;;;;;;;;;143844:103:::0;:::o;144801:363::-;144952:14;;;;;;;;;;;144944:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;145055:1;145024:18;:27;145043:7;145024:27;;;;;;;;;;;;:32;145002:106;;;;;;;;;;;;:::i;:::-;;;;;;;;;145119:37;145138:4;145144:2;145148:7;145119:18;:37::i;:::-;144801:363;;;:::o;90549:134::-;90623:12;90631:3;90623:7;:12::i;:::-;90615:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;90663:12;90671:3;90663:7;:12::i;:::-;90549:134;:::o;23833:71::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;141602:53::-;;;;;;;;;;;;;;;;;:::o;145591:278::-;21648:13;:11;:13::i;:::-;145639:18:::1;145660:21;145639:42;;145694:9;145714:10;145694:31;;145738:12;145777:1;:6;;145791:10;145777:29;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;145763:43;;;;;145825:7;145817:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;145628:241;;;145591:278::o:0;90691:138::-;90767:12;90775:3;90767:7;:12::i;:::-;90759:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;90807:14;90817:3;90807:9;:14::i;:::-;90691:138;:::o;66537:193::-;66683:39;66700:4;66706:2;66710:7;66683:39;;;;;;;;;;;;:16;:39::i;:::-;66537:193;;;:::o;141382:27::-;;;;:::o;143955:119::-;21648:13;:11;:13::i;:::-;144051:15:::1;144034:14;;:32;;;;;;;;;;;;;;;;;;143955:119:::0;:::o;141549:46::-;;;;;;;;;;;;;;;;;;;;;;:::o;143553:108::-;21648:13;:11;:13::i;:::-;143643:10:::1;;143631:9;:22;;;;;;;:::i;:::-;;143553:108:::0;;:::o;144413:380::-;144489:16;144497:7;144489;:16::i;:::-;144475:30;;:10;:30;;;144467:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;144580:1;144549:18;:27;144568:7;144549:27;;;;;;;;;;;;:32;144541:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;144614:22;144639:18;:27;144658:7;144639:27;;;;;;;;;;;;144614:52;;144707:1;144677:18;:27;144696:7;144677:27;;;;;;;;;;;:31;;;;144724:61;144732:7;144741:10;144753:14;144769:15;144724:61;;;;;;;;;:::i;:::-;;;;;;;;144456:337;144413:380;:::o;53487:202::-;53604:7;53652:27;53671:7;53652:18;:27::i;:::-;53629:52;;53487:202;;;:::o;23773:53::-;;;;;;;;;;;;;;;;;:::o;141416:24::-;;;;:::o;48483:333::-;48600:7;48646:1;48629:19;;:5;:19;;;48625:60;;48657:28;;;;;;;;;;;;;;48625:60;43532:13;48716:23;:21;:23::i;:::-;:42;;:49;48759:5;48716:49;;;;;;;;;;;;;;;;:92;48696:112;;48483:333;;;:::o;22403:103::-;21648:13;:11;:13::i;:::-;22468:30:::1;22495:1;22468:18;:30::i;:::-;22403:103::o:0;24353:114::-;24416:4;24458:1;24440:9;:14;24450:3;24440:14;;;;;;;;;;;;:19;24433:26;;24353:114;;;:::o;21762:87::-;21808:7;21835:6;;;;;;;;;;;21828:13;;21762:87;:::o;90837:164::-;90930:12;90938:3;90930:7;:12::i;:::-;90922:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;90970:23;90978:3;90983:9;90970:7;:23::i;:::-;90837:164;;:::o;52149:128::-;52205:13;52238:23;:21;:23::i;:::-;:31;;52231:38;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52149:128;:::o;141352:23::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;59786:314::-;60013:8;59913:23;:21;:23::i;:::-;:42;;:63;59956:19;:17;:19::i;:::-;59913:63;;;;;;;;;;;;;;;:97;59991:8;59913:97;;;;;;;;;;;;;;;;:108;;;;;;;;;;;;;;;;;;60073:8;60037:55;;60052:19;:17;:19::i;:::-;60037:55;;;60083:8;60037:55;;;;;;:::i;:::-;;;;;;;;59786:314;;:::o;144082:323::-;144156:16;144164:7;144156;:16::i;:::-;144142:30;;:10;:30;;;144134:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;144247:1;144216:18;:27;144235:7;144216:27;;;;;;;;;;;;:32;144208:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;144311:15;144281:18;:27;144300:7;144281:27;;;;;;;;;;;:45;;;;144342:55;144348:7;144357:10;144369:18;:27;144388:7;144369:27;;;;;;;;;;;;144342:55;;;;;;;;:::i;:::-;;;;;;;;144082:323;:::o;24475:::-;21648:13;:11;:13::i;:::-;24648:7:::1;;:14;;24627:10;;:17;;:35;24619:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;24690:9;24685:105;24709:10;;:17;;24705:1;:21;24685:105;;;24780:7;;24788:1;24780:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;24746:16;:31;24763:10;;24774:1;24763:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;24746:31;;;;;;;;;;;;;;;;:44;;;;;;;;;;;;;;;;;;24728:3;;;;;:::i;:::-;;;;24685:105;;;;24475:323:::0;;;;:::o;23709:57::-;;;;;;;;;;;;;;;;;;;;;;:::o;145172:411::-;145356:14;;;;;;;;;;;145348:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;145459:1;145428:18;:27;145447:7;145428:27;;;;;;;;;;;;:32;145406:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;145527:48;145550:4;145556:2;145560:7;145569:5;145527:22;:48::i;:::-;145172:411;;;;:::o;141499:43::-;;;;;;;;;;;;;;;;;:::o;143298:247::-;143400:13;143439:17;143447:8;143439:7;:17::i;:::-;143431:45;;;;;;;;;;;;:::i;:::-;;;;;;;;;143508:24;143523:8;143508:14;:24::i;:::-;143494:43;;;;;;;;:::i;:::-;;;;;;;;;;;;;143487:50;;143298:247;;;:::o;142932:82::-;142974:7;143001:5;142994:12;;142932:82;:::o;142270:119::-;21648:13;:11;:13::i;:::-;142353:28:::1;142362:8;142372;142353;:28::i;:::-;142270:119:::0;;:::o;60257:238::-;60399:4;60428:23;:21;:23::i;:::-;:42;;:49;60471:5;60428:49;;;;;;;;;;;;;;;:59;60478:8;60428:59;;;;;;;;;;;;;;;;;;;;;;;;;60421:66;;60257:238;;;;:::o;22661:::-;21648:13;:11;:13::i;:::-;22784:1:::1;22764:22;;:8;:22;;::::0;22742:110:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;22863:28;22882:8;22863:18;:28::i;:::-;22661:238:::0;:::o;143742:94::-;21648:13;:11;:13::i;:::-;143822:6:::1;143810:9;:18;;;;143742:94:::0;:::o;141924:338::-;29098:38;:36;:38::i;:::-;:52;;;;;;;;;;;;:160;;29207:38;:36;:38::i;:::-;:51;;;;;;;;;;;;29206:52;29098:160;;;29170:16;:14;:16::i;:::-;29098:160;29076:265;;;;;;;;;;;;:::i;:::-;;;;;;;;;29354:19;29377:52;:50;:52::i;:::-;:80;;;;;;;;;;;;29376:81;29354:103;;29472:14;29468:179;;;29558:4;29503:38;:36;:38::i;:::-;:52;;;:59;;;;;;;;;;;;;;;;;;29631:4;29577:38;:36;:38::i;:::-;:51;;;:58;;;;;;;;;;;;;;;;;;29468:179;15398:19:::1;15421:13:::0;::::1;;;;;;;;;;15420:14;15398:36;;15468:14;:34;;;;;15501:1;15486:12;::::0;::::1;;;;;;;;:16;;;15468:34;15467:146;;;;15526:44;15564:4;15526:29;:44::i;:::-;15525:45;:87;;;;;15611:1;15595:12;::::0;::::1;;;;;;;;:17;;;15525:87;15467:146;15445:242;;;;;;;;;;;;:::i;:::-;;;;;;;;;15713:1;15698:12;::::0;:16:::1;;;;;;;;;;;;;;;;;;15729:14;15725:67;;;15776:4;15760:13;;:20;;;;;;;;;;;;;;;;;;15725:67;142051:56:::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;::::0;:14:::2;:56::i;:::-;142132:10;142120:9;:22;;;;;;:::i;:::-;;142170:4;142153:14;;:21;;;;;;;;;;;;;;;;;;142198:5;142185:10;;:18;;;;;;;;;;;;;;;;;;142229:1;142214:12;:16;;;;142253:1;142241:9;:13;;;;15818:14:::1;15814:102;;;15865:5;15849:13:::0;::::1;:21;;;;;;;;;;;;;;;;;;15890:14;15902:1;15890:14;;;;;;:::i;:::-;;;;;;;;15814:102;15387:536;29677:14:::0;29673:107;;;29763:5;29708:38;:36;:38::i;:::-;:52;;;:60;;;;;;;;;;;;;;;;;;29673:107;28791:996;141924:338;:::o;50997:689::-;51127:4;51471:10;51456:25;;:11;:25;;;;:102;;;;51548:10;51533:25;;:11;:25;;;;51456:102;:179;;;;51625:10;51610:25;;:11;:25;;;;51456:179;51436:199;;50997:689;;;:::o;32749:164::-;32790:16;32819:12;32694:46;32819:27;;32891:4;32881:14;;32866:40;32749:164;:::o;60753:360::-;60818:4;60874:7;60855:15;:13;:15::i;:::-;:26;;:90;;;;;60908:23;:21;:23::i;:::-;:37;;;60898:7;:47;60855:90;:231;;;;;61085:1;44308:8;60983:23;:21;:23::i;:::-;:41;;:50;61025:7;60983:50;;;;;;;;;;;;:85;:103;60855:231;60835:251;;60753:360;;;:::o;79288:516::-;79417:13;79433:16;79441:7;79433;:16::i;:::-;79417:32;;79466:13;79462:219;;;79521:5;79498:28;;:19;:17;:19::i;:::-;:28;;;79494:187;;79550:44;79567:5;79574:19;:17;:19::i;:::-;79550:16;:44::i;:::-;79545:136;;79626:35;;;;;;;;;;;;;;79545:136;79494:187;79462:219;79750:2;79693:23;:21;:23::i;:::-;:39;;:48;79733:7;79693:48;;;;;;;;;;;:54;;;:59;;;;;;;;;;;;;;;;;;79788:7;79784:2;79768:28;;79777:5;79768:28;;;;;;;;;;;;79406:398;79288:516;;;:::o;142817:107::-;142891:25;142897:8;142907;142891:5;:25::i;:::-;142817:107;;:::o;143071:101::-;143136:7;143163:1;143156:8;;143071:101;:::o;21927:132::-;22002:12;:10;:12::i;:::-;21991:23;;:7;:5;:7::i;:::-;:23;;;21983:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;21927:132::o;89919:285::-;90092:20;90103:8;90092:10;:20::i;:::-;90084:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;90143:53;90175:5;90182:3;90187:8;90143:31;:53::i;:::-;89919:285;;;:::o;24806:447::-;24864:16;:28;24881:10;24864:28;;;;;;;;;;;;;;;;;;;;;;;;;24856:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;24980:1;24947:12;:17;24960:3;24947:17;;;;;;;;;;;:29;24965:10;24947:29;;;;;;;;;;;;;;;;:34;24925:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;25049:13;25082:1;25065:9;:14;25075:3;25065:14;;;;;;;;;;;;:18;;;;:::i;:::-;25049:34;;25116:10;25094:7;:12;25102:3;25094:12;;;;;;;;;;;:19;25107:5;25094:19;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;25169:5;25137:12;:17;25150:3;25137:17;;;;;;;;;;;:29;25155:10;25137:29;;;;;;;;;;;;;;;:37;;;;25185:9;:14;25195:3;25185:14;;;;;;;;;;;;:16;;;;;;;;;:::i;:::-;;;;;;25234:10;25217:28;;25229:3;25217:28;;;;;;;;;;24845:408;24806:447;:::o;25261:675::-;25321:16;:28;25338:10;25321:28;;;;;;;;;;;;;;;;;;;;;;;;;25313:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;25382:13;25398:12;:17;25411:3;25398:17;;;;;;;;;;;:29;25416:10;25398:29;;;;;;;;;;;;;;;;25382:45;;25455:1;25446:5;:10;25438:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;25497:12;25512:9;:14;25522:3;25512:14;;;;;;;;;;;;25497:29;;25550:4;25541:5;:13;25537:274;;25571:20;25594:7;:12;25602:3;25594:12;;;;;;;;;;;:18;25607:4;25594:18;;;;;;;;;;;;;;;;;;;;;25571:41;;25649:12;25627:7;:12;25635:3;25627:12;;;;;;;;;;;:19;25640:5;25627:19;;;;;;;;;;;;:34;;;;;;;;;;;;;;;;;;25705:1;25676:7;:12;25684:3;25676:12;;;;;;;;;;;:18;25689:4;25676:18;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;25756:5;25722:12;:17;25735:3;25722:17;;;;;;;;;;;:31;25740:12;25722:31;;;;;;;;;;;;;;;:39;;;;25556:217;25537:274;;;25809:1;25779:7;:12;25787:3;25779:12;;;;;;;;;;;:19;25792:5;25779:19;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;25537:274;25854:1;25822:12;:17;25835:3;25822:17;;;;;;;;;;;:29;25840:10;25822:29;;;;;;;;;;;;;;;:33;;;;25866:9;:14;25876:3;25866:14;;;;;;;;;;;;:16;;;;;;;;;:::i;:::-;;;;;;25917:10;25898:30;;25912:3;25898:30;;;;;;;;;;25302:634;;25261:675;:::o;54923:1905::-;55017:14;55072:7;55053:15;:13;:15::i;:::-;:26;55049:1723;;55105:23;:21;:23::i;:::-;:41;;:50;55147:7;55105:50;;;;;;;;;;;;55096:59;;55233:1;44308:8;55205:6;:24;:29;55201:1560;;55354:1;55344:6;:11;55340:1118;;55395:23;:21;:23::i;:::-;:37;;;55384:7;:48;55380:117;;55466:31;;;;;;;;;;;;;;55380:117;56094:345;56180:23;:21;:23::i;:::-;:41;;:116;56256:9;;;;;;;56180:116;;;;;;;;;;;;56171:125;;56364:1;56354:6;:11;56402:13;56350:25;56094:345;;55340:1118;56732:13;;55201:1560;55049:1723;56789:31;;;;;;;;;;;;;;54923:1905;;;;:::o;23059:191::-;23133:16;23152:6;;;;;;;;;;;23133:25;;23178:8;23169:6;;:17;;;;;;;;;;;;;;;;;;23233:8;23202:40;;23223:8;23202:40;;;;;;;;;;;;23122:128;23059:191;:::o;25944:679::-;26022:16;:27;26039:9;26022:27;;;;;;;;;;;;;;;;;;;;;;;;;26021:28;26013:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;26082:13;26098:12;:17;26111:3;26098:17;;;;;;;;;;;:28;26116:9;26098:28;;;;;;;;;;;;;;;;26082:44;;26154:1;26145:5;:10;26137:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;26186:12;26201:9;:14;26211:3;26201:14;;;;;;;;;;;;26186:29;;26239:4;26230:5;:13;26226:274;;26260:20;26283:7;:12;26291:3;26283:12;;;;;;;;;;;:18;26296:4;26283:18;;;;;;;;;;;;;;;;;;;;;26260:41;;26338:12;26316:7;:12;26324:3;26316:12;;;;;;;;;;;:19;26329:5;26316:19;;;;;;;;;;;;:34;;;;;;;;;;;;;;;;;;26394:1;26365:7;:12;26373:3;26365:12;;;;;;;;;;;:18;26378:4;26365:18;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;26445:5;26411:12;:17;26424:3;26411:17;;;;;;;;;;;:31;26429:12;26411:31;;;;;;;;;;;;;;;:39;;;;26245:217;26226:274;;;26498:1;26468:7;:12;26476:3;26468:12;;;;;;;;;;;:19;26481:5;26468:19;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;26226:274;26542:1;26511:12;:17;26524:3;26511:17;;;;;;;;;;;:28;26529:9;26511:28;;;;;;;;;;;;;;;:32;;;;26554:9;:14;26564:3;26554:14;;;;;;;;;;;;:16;;;;;;;;;:::i;:::-;;;;;;26605:9;26586:29;;26600:3;26586:29;;;;;;;;;;26002:621;;25944:679;;:::o;86433:105::-;86493:7;86520:10;86513:17;;86433:105;:::o;90212:329::-;90418:20;90429:8;90418:10;:20::i;:::-;90410:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;90469:64;90505:5;90512:3;90517:8;90527:5;90469:35;:64::i;:::-;90212:329;;;;:::o;52383:415::-;52501:13;52537:16;52545:7;52537;:16::i;:::-;52532:59;;52562:29;;;;;;;;;;;;;;52532:59;52604:21;52628:10;:8;:10::i;:::-;52604:34;;52694:1;52675:7;52669:21;:26;:121;;;;;;;;;;;;;;;;;52739:7;52748:18;52758:7;52748:9;:18::i;:::-;52722:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;52669:121;52649:141;;;52383:415;;;:::o;27290:164::-;27331:16;27360:12;27223:58;27360:27;;27432:4;27422:14;;27407:40;27290:164;:::o;30295:569::-;30343:4;30714:12;30737:4;30714:28;;30753:10;30816:4;30804:17;30798:23;;30855:1;30849:2;:7;30842:14;;;;30295:569;:::o;2971:326::-;3031:4;3288:1;3266:7;:19;;;:23;3259:30;;2971:326;;;:::o;89381:230::-;17616:13;;;;;;;;;;;17608:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;89509:49:::1;89543:5;89550:7;89509:33;:49::i;:::-;89569:34;:32;:34::i;:::-;89381:230:::0;;:::o;71178:3149::-;71251:20;71274:23;:21;:23::i;:::-;:37;;;71251:60;;71338:1;71326:8;:13;71322:44;;71348:18;;;;;;;;;;;;;;71322:44;71379:61;71409:1;71413:2;71417:12;71431:8;71379:21;:61::i;:::-;71981:1;43670:2;71951:1;:26;;71950:32;71921:8;:62;71854:23;:21;:23::i;:::-;:42;;:46;71897:2;71854:46;;;;;;;;;;;;;;;;:129;;;;;;;;;;;72316:160;72353:2;72428:33;72451:1;72455:2;72459:1;72428:14;:33::i;:::-;72374:30;72395:8;72374:20;:30::i;:::-;:87;72316:18;:160::i;:::-;72226:23;:21;:23::i;:::-;:41;;:87;72286:12;72226:87;;;;;;;;;;;:250;;;;72493:16;72524:11;72553:8;72538:12;:23;72524:37;;73074:16;73070:2;73066:25;73054:37;;73446:12;73406:8;73365:1;73303:25;73244:1;73183;73156:335;73817:1;73803:12;73799:20;73757:346;73858:3;73849:7;73846:16;73757:346;;74076:7;74066:8;74063:1;74036:25;74033:1;74030;74025:59;73911:1;73902:7;73898:15;73887:26;;73757:346;;;73761:77;74148:1;74136:8;:13;74132:45;;74158:19;;;;;;;;;;;;;;74132:45;74234:3;74194:23;:21;:23::i;:::-;:37;;:43;;;;71628:2621;;74259:60;74288:1;74292:2;74296:12;74310:8;74259:20;:60::i;:::-;71240:3087;71178:3149;;:::o;19781:98::-;19834:7;19861:10;19854:17;;19781:98;:::o;63166:3275::-;63308:27;63338;63357:7;63338:18;:27::i;:::-;63308:57;;63423:4;63382:45;;63398:19;63382:45;;;63378:99;;63449:28;;;;;;;;;;;;;;63378:99;63505:27;63547:23;63584:35;63611:7;63584:26;:35::i;:::-;63490:129;;;;63733:134;63776:15;63810:4;63833:19;:17;:19::i;:::-;63733:24;:134::i;:::-;63714:287;;63897:43;63914:4;63920:19;:17;:19::i;:::-;63897:16;:43::i;:::-;63892:109;;63966:35;;;;;;;;;;;;;;63892:109;63714:287;64032:1;64018:16;;:2;:16;;;64014:52;;64043:23;;;;;;;;;;;;;;64014:52;64079:43;64101:4;64107:2;64111:7;64120:1;64079:21;:43::i;:::-;64215:15;64212:160;;;64355:1;64334:19;64327:30;64212:160;64752:23;:21;:23::i;:::-;:42;;:48;64795:4;64752:48;;;;;;;;;;;;;;;;64750:50;;;;;;;;;;;;64845:23;:21;:23::i;:::-;:42;;:46;64888:2;64845:46;;;;;;;;;;;;;;;;64843:48;;;;;;;;;;;65247:167;65284:2;65354:45;65369:4;65375:2;65379:19;65354:14;:45::i;:::-;44588:8;65305:94;65247:18;:167::i;:::-;65162:23;:21;:23::i;:::-;:41;;:82;65222:7;65162:82;;;;;;;;;;;:252;;;;65585:1;44588:8;65534:19;:47;:52;65530:795;;65607:19;65639:1;65629:7;:11;65607:33;;65842:1;65784:23;:21;:23::i;:::-;:41;;:54;65826:11;65784:54;;;;;;;;;;;;:59;65758:552;;65964:23;:21;:23::i;:::-;:37;;;65949:11;:52;65945:346;;66248:19;66135:23;:21;:23::i;:::-;:41;;:110;66207:11;66135:110;;;;;;;;;;;:132;;;;65945:346;65758:552;65588:737;65530:795;66372:7;66368:2;66353:27;;66362:4;66353:27;;;;;;;;;;;;66391:42;66412:4;66418:2;66422:7;66431:1;66391:20;:42::i;:::-;63297:3144;;;63166:3275;;;:::o;67328:407::-;67503:31;67516:4;67522:2;67526:7;67503:12;:31::i;:::-;67567:1;67549:2;:14;;;:19;67545:183;;67588:56;67619:4;67625:2;67629:7;67638:5;67588:30;:56::i;:::-;67583:145;;67672:40;;;;;;;;;;;;;;67583:145;67545:183;67328:407;;;;:::o;143180:110::-;143240:13;143273:9;143266:16;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;143180:110;:::o;86640:1786::-;86741:17;87180:4;87173;87167:11;87163:22;87272:1;87266:4;87259:15;87347:4;87344:1;87340:12;87333:19;;87429:1;87424:3;87417:14;87533:3;87772:5;87754:428;87780:1;87754:428;;;87820:1;87815:3;87811:11;87804:18;;87991:2;87985:4;87981:13;87977:2;87973:22;87968:3;87960:36;88085:2;88079:4;88075:13;88067:21;;88152:4;87754:428;88142:25;87754:428;87758:21;88221:3;88216;88212:13;88336:4;88331:3;88327:14;88320:21;;88401:6;88396:3;88389:19;86785:1634;;;86640:1786;;;:::o;45807:183::-;30050:38;:36;:38::i;:::-;:52;;;;;;;;;;;;30028:154;;;;;;;;;;;;:::i;:::-;;;;;;;;;45942:40:::1;45967:5;45974:7;45942:24;:40::i;:::-;45807:183:::0;;:::o;24234:111::-;17616:13;;;;;;;;;;;17608:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;24302:35:::1;:33;:35::i;:::-;24234:111::o:0;68397:159::-;;;;;:::o;85742:311::-;85877:7;85897:16;44712:3;85923:19;:41;;85897:68;;44712:3;85991:31;86002:4;86008:2;86012:9;85991:10;:31::i;:::-;85983:40;;:62;;85976:69;;;85742:311;;;;;:::o;58041:356::-;58138:14;58376:1;58366:8;58363:15;58337:24;58333:46;58323:56;;58041:356;;;:::o;57408:531::-;57515:14;57688:16;57681:5;57677:28;57668:37;;57900:5;57886:11;57861:23;57857:41;57854:52;57830:5;57809:112;57799:122;;57408:531;;;;:::o;69221:158::-;;;;;:::o;61994:552::-;62096:27;62125:23;62166:53;62222:37;:35;:37::i;:::-;:67;;:76;62290:7;62222:76;;;;;;;;;;;62166:132;;62451:18;62428:41;;62508:19;62502:26;62483:45;;62413:126;61994:552;;;:::o;61222:659::-;61371:11;61536:16;61529:5;61525:28;61516:37;;61696:16;61685:9;61681:32;61668:45;;61846:15;61835:9;61832:30;61824:5;61813:9;61810:20;61807:56;61797:66;;61222:659;;;;;:::o;69819:897::-;69982:4;70052:2;70016:56;;;70091:19;:17;:19::i;:::-;70129:4;70152:7;70178:5;70016:182;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;69999:710;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70484:1;70467:6;:13;:18;70463:235;;70513:40;;;;;;;;;;;;;;70463:235;70656:6;70650:13;70641:6;70637:2;70633:15;70626:38;69999:710;70298:109;;;70271:136;;;:6;:136;;;;70247:160;;;69819:897;;;;;;:::o;45998:310::-;30050:38;:36;:38::i;:::-;:52;;;;;;;;;;;;30028:154;;;;;;;;;;;;:::i;:::-;;;;;;;;;46177:5:::1;46145:23;:21;:23::i;:::-;:29;;:37;;;;;;:::i;:::-;;46227:7;46193:23;:21;:23::i;:::-;:31;;:41;;;;;;:::i;:::-;;46285:15;:13;:15::i;:::-;46245:23;:21;:23::i;:::-;:37;;:55;;;;45998:310:::0;;:::o;21305:97::-;17616:13;;;;;;;;;;;17608:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;21368:26:::1;:24;:26::i;:::-;21305:97::o:0;85443:147::-;85580:6;85443:147;;;;;:::o;21410:113::-;17616:13;;;;;;;;;;;17608:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;21483:32:::1;21502:12;:10;:12::i;:::-;21483:18;:32::i;:::-;21410:113::o:0;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:474::-;5310:6;5318;5367:2;5355:9;5346:7;5342:23;5338:32;5335:119;;;5373:79;;:::i;:::-;5335:119;5493:1;5518:53;5563:7;5554:6;5543:9;5539:22;5518:53;:::i;:::-;5508:63;;5464:117;5620:2;5646:53;5691:7;5682:6;5671:9;5667:22;5646:53;:::i;:::-;5636:63;;5591:118;5242:474;;;;;:::o;5722:116::-;5792:21;5807:5;5792:21;:::i;:::-;5785:5;5782:32;5772:60;;5828:1;5825;5818:12;5772:60;5722:116;:::o;5844:133::-;5887:5;5925:6;5912:20;5903:29;;5941:30;5965:5;5941:30;:::i;:::-;5844:133;;;;:::o;5983:323::-;6039:6;6088:2;6076:9;6067:7;6063:23;6059:32;6056:119;;;6094:79;;:::i;:::-;6056:119;6214:1;6239:50;6281:7;6272:6;6261:9;6257:22;6239:50;:::i;:::-;6229:60;;6185:114;5983:323;;;;:::o;6312:619::-;6389:6;6397;6405;6454:2;6442:9;6433:7;6429:23;6425:32;6422:119;;;6460:79;;:::i;:::-;6422:119;6580:1;6605:53;6650:7;6641:6;6630:9;6626:22;6605:53;:::i;:::-;6595:63;;6551:117;6707:2;6733:53;6778:7;6769:6;6758:9;6754:22;6733:53;:::i;:::-;6723:63;;6678:118;6835:2;6861:53;6906:7;6897:6;6886:9;6882:22;6861:53;:::i;:::-;6851:63;;6806:118;6312:619;;;;;:::o;6937:474::-;7005:6;7013;7062:2;7050:9;7041:7;7037:23;7033:32;7030:119;;;7068:79;;:::i;:::-;7030:119;7188:1;7213:53;7258:7;7249:6;7238:9;7234:22;7213:53;:::i;:::-;7203:63;;7159:117;7315:2;7341:53;7386:7;7377:6;7366:9;7362:22;7341:53;:::i;:::-;7331:63;;7286:118;6937:474;;;;;:::o;7417:117::-;7526:1;7523;7516:12;7540:117;7649:1;7646;7639:12;7663:117;7772:1;7769;7762:12;7800:553;7858:8;7868:6;7918:3;7911:4;7903:6;7899:17;7895:27;7885:122;;7926:79;;:::i;:::-;7885:122;8039:6;8026:20;8016:30;;8069:18;8061:6;8058:30;8055:117;;;8091:79;;:::i;:::-;8055:117;8205:4;8197:6;8193:17;8181:29;;8259:3;8251:4;8243:6;8239:17;8229:8;8225:32;8222:41;8219:128;;;8266:79;;:::i;:::-;8219:128;7800:553;;;;;:::o;8359:529::-;8430:6;8438;8487:2;8475:9;8466:7;8462:23;8458:32;8455:119;;;8493:79;;:::i;:::-;8455:119;8641:1;8630:9;8626:17;8613:31;8671:18;8663:6;8660:30;8657:117;;;8693:79;;:::i;:::-;8657:117;8806:65;8863:7;8854:6;8843:9;8839:22;8806:65;:::i;:::-;8788:83;;;;8584:297;8359:529;;;;;:::o;8894:329::-;8953:6;9002:2;8990:9;8981:7;8977:23;8973:32;8970:119;;;9008:79;;:::i;:::-;8970:119;9128:1;9153:53;9198:7;9189:6;9178:9;9174:22;9153:53;:::i;:::-;9143:63;;9099:117;8894:329;;;;:::o;9229:468::-;9294:6;9302;9351:2;9339:9;9330:7;9326:23;9322:32;9319:119;;;9357:79;;:::i;:::-;9319:119;9477:1;9502:53;9547:7;9538:6;9527:9;9523:22;9502:53;:::i;:::-;9492:63;;9448:117;9604:2;9630:50;9672:7;9663:6;9652:9;9648:22;9630:50;:::i;:::-;9620:60;;9575:115;9229:468;;;;;:::o;9720:568::-;9793:8;9803:6;9853:3;9846:4;9838:6;9834:17;9830:27;9820:122;;9861:79;;:::i;:::-;9820:122;9974:6;9961:20;9951:30;;10004:18;9996:6;9993:30;9990:117;;;10026:79;;:::i;:::-;9990:117;10140:4;10132:6;10128:17;10116:29;;10194:3;10186:4;10178:6;10174:17;10164:8;10160:32;10157:41;10154:128;;;10201:79;;:::i;:::-;10154:128;9720:568;;;;;:::o;10308:565::-;10378:8;10388:6;10438:3;10431:4;10423:6;10419:17;10415:27;10405:122;;10446:79;;:::i;:::-;10405:122;10559:6;10546:20;10536:30;;10589:18;10581:6;10578:30;10575:117;;;10611:79;;:::i;:::-;10575:117;10725:4;10717:6;10713:17;10701:29;;10779:3;10771:4;10763:6;10759:17;10749:8;10745:32;10742:41;10739:128;;;10786:79;;:::i;:::-;10739:128;10308:565;;;;;:::o;10879:928::-;10998:6;11006;11014;11022;11071:2;11059:9;11050:7;11046:23;11042:32;11039:119;;;11077:79;;:::i;:::-;11039:119;11225:1;11214:9;11210:17;11197:31;11255:18;11247:6;11244:30;11241:117;;;11277:79;;:::i;:::-;11241:117;11390:80;11462:7;11453:6;11442:9;11438:22;11390:80;:::i;:::-;11372:98;;;;11168:312;11547:2;11536:9;11532:18;11519:32;11578:18;11570:6;11567:30;11564:117;;;11600:79;;:::i;:::-;11564:117;11713:77;11782:7;11773:6;11762:9;11758:22;11713:77;:::i;:::-;11695:95;;;;11490:310;10879:928;;;;;;;:::o;11813:117::-;11922:1;11919;11912:12;11936:180;11984:77;11981:1;11974:88;12081:4;12078:1;12071:15;12105:4;12102:1;12095:15;12122:281;12205:27;12227:4;12205:27;:::i;:::-;12197:6;12193:40;12335:6;12323:10;12320:22;12299:18;12287:10;12284:34;12281:62;12278:88;;;12346:18;;:::i;:::-;12278:88;12386:10;12382:2;12375:22;12165:238;12122:281;;:::o;12409:129::-;12443:6;12470:20;;:::i;:::-;12460:30;;12499:33;12527:4;12519:6;12499:33;:::i;:::-;12409:129;;;:::o;12544:307::-;12605:4;12695:18;12687:6;12684:30;12681:56;;;12717:18;;:::i;:::-;12681:56;12755:29;12777:6;12755:29;:::i;:::-;12747:37;;12839:4;12833;12829:15;12821:23;;12544:307;;;:::o;12857:146::-;12954:6;12949:3;12944;12931:30;12995:1;12986:6;12981:3;12977:16;12970:27;12857:146;;;:::o;13009:423::-;13086:5;13111:65;13127:48;13168:6;13127:48;:::i;:::-;13111:65;:::i;:::-;13102:74;;13199:6;13192:5;13185:21;13237:4;13230:5;13226:16;13275:3;13266:6;13261:3;13257:16;13254:25;13251:112;;;13282:79;;:::i;:::-;13251:112;13372:54;13419:6;13414:3;13409;13372:54;:::i;:::-;13092:340;13009:423;;;;;:::o;13451:338::-;13506:5;13555:3;13548:4;13540:6;13536:17;13532:27;13522:122;;13563:79;;:::i;:::-;13522:122;13680:6;13667:20;13705:78;13779:3;13771:6;13764:4;13756:6;13752:17;13705:78;:::i;:::-;13696:87;;13512:277;13451:338;;;;:::o;13795:943::-;13890:6;13898;13906;13914;13963:3;13951:9;13942:7;13938:23;13934:33;13931:120;;;13970:79;;:::i;:::-;13931:120;14090:1;14115:53;14160:7;14151:6;14140:9;14136:22;14115:53;:::i;:::-;14105:63;;14061:117;14217:2;14243:53;14288:7;14279:6;14268:9;14264:22;14243:53;:::i;:::-;14233:63;;14188:118;14345:2;14371:53;14416:7;14407:6;14396:9;14392:22;14371:53;:::i;:::-;14361:63;;14316:118;14501:2;14490:9;14486:18;14473:32;14532:18;14524:6;14521:30;14518:117;;;14554:79;;:::i;:::-;14518:117;14659:62;14713:7;14704:6;14693:9;14689:22;14659:62;:::i;:::-;14649:72;;14444:287;13795:943;;;;;;;:::o;14744:474::-;14812:6;14820;14869:2;14857:9;14848:7;14844:23;14840:32;14837:119;;;14875:79;;:::i;:::-;14837:119;14995:1;15020:53;15065:7;15056:6;15045:9;15041:22;15020:53;:::i;:::-;15010:63;;14966:117;15122:2;15148:53;15193:7;15184:6;15173:9;15169:22;15148:53;:::i;:::-;15138:63;;15093:118;14744:474;;;;;:::o;15224:308::-;15286:4;15376:18;15368:6;15365:30;15362:56;;;15398:18;;:::i;:::-;15362:56;15436:29;15458:6;15436:29;:::i;:::-;15428:37;;15520:4;15514;15510:15;15502:23;;15224:308;;;:::o;15538:425::-;15616:5;15641:66;15657:49;15699:6;15657:49;:::i;:::-;15641:66;:::i;:::-;15632:75;;15730:6;15723:5;15716:21;15768:4;15761:5;15757:16;15806:3;15797:6;15792:3;15788:16;15785:25;15782:112;;;15813:79;;:::i;:::-;15782:112;15903:54;15950:6;15945:3;15940;15903:54;:::i;:::-;15622:341;15538:425;;;;;:::o;15983:340::-;16039:5;16088:3;16081:4;16073:6;16069:17;16065:27;16055:122;;16096:79;;:::i;:::-;16055:122;16213:6;16200:20;16238:79;16313:3;16305:6;16298:4;16290:6;16286:17;16238:79;:::i;:::-;16229:88;;16045:278;15983:340;;;;:::o;16329:509::-;16398:6;16447:2;16435:9;16426:7;16422:23;16418:32;16415:119;;;16453:79;;:::i;:::-;16415:119;16601:1;16590:9;16586:17;16573:31;16631:18;16623:6;16620:30;16617:117;;;16653:79;;:::i;:::-;16617:117;16758:63;16813:7;16804:6;16793:9;16789:22;16758:63;:::i;:::-;16748:73;;16544:287;16329:509;;;;:::o;16844:180::-;16892:77;16889:1;16882:88;16989:4;16986:1;16979:15;17013:4;17010:1;17003:15;17030:320;17074:6;17111:1;17105:4;17101:12;17091:22;;17158:1;17152:4;17148:12;17179:18;17169:81;;17235:4;17227:6;17223:17;17213:27;;17169:81;17297:2;17289:6;17286:14;17266:18;17263:38;17260:84;;17316:18;;:::i;:::-;17260:84;17081:269;17030:320;;;:::o;17356:166::-;17496:18;17492:1;17484:6;17480:14;17473:42;17356:166;:::o;17528:366::-;17670:3;17691:67;17755:2;17750:3;17691:67;:::i;:::-;17684:74;;17767:93;17856:3;17767:93;:::i;:::-;17885:2;17880:3;17876:12;17869:19;;17528:366;;;:::o;17900:419::-;18066:4;18104:2;18093:9;18089:18;18081:26;;18153:9;18147:4;18143:20;18139:1;18128:9;18124:17;18117:47;18181:131;18307:4;18181:131;:::i;:::-;18173:139;;17900:419;;;:::o;18325:158::-;18465:10;18461:1;18453:6;18449:14;18442:34;18325:158;:::o;18489:365::-;18631:3;18652:66;18716:1;18711:3;18652:66;:::i;:::-;18645:73;;18727:93;18816:3;18727:93;:::i;:::-;18845:2;18840:3;18836:12;18829:19;;18489:365;;;:::o;18860:419::-;19026:4;19064:2;19053:9;19049:18;19041:26;;19113:9;19107:4;19103:20;19099:1;19088:9;19084:17;19077:47;19141:131;19267:4;19141:131;:::i;:::-;19133:139;;18860:419;;;:::o;19285:168::-;19425:20;19421:1;19413:6;19409:14;19402:44;19285:168;:::o;19459:366::-;19601:3;19622:67;19686:2;19681:3;19622:67;:::i;:::-;19615:74;;19698:93;19787:3;19698:93;:::i;:::-;19816:2;19811:3;19807:12;19800:19;;19459:366;;;:::o;19831:419::-;19997:4;20035:2;20024:9;20020:18;20012:26;;20084:9;20078:4;20074:20;20070:1;20059:9;20055:17;20048:47;20112:131;20238:4;20112:131;:::i;:::-;20104:139;;19831:419;;;:::o;20256:169::-;20396:21;20392:1;20384:6;20380:14;20373:45;20256:169;:::o;20431:366::-;20573:3;20594:67;20658:2;20653:3;20594:67;:::i;:::-;20587:74;;20670:93;20759:3;20670:93;:::i;:::-;20788:2;20783:3;20779:12;20772:19;;20431:366;;;:::o;20803:419::-;20969:4;21007:2;20996:9;20992:18;20984:26;;21056:9;21050:4;21046:20;21042:1;21031:9;21027:17;21020:47;21084:131;21210:4;21084:131;:::i;:::-;21076:139;;20803:419;;;:::o;21228:180::-;21276:77;21273:1;21266:88;21373:4;21370:1;21363:15;21397:4;21394:1;21387:15;21414:191;21454:3;21473:20;21491:1;21473:20;:::i;:::-;21468:25;;21507:20;21525:1;21507:20;:::i;:::-;21502:25;;21550:1;21547;21543:9;21536:16;;21571:3;21568:1;21565:10;21562:36;;;21578:18;;:::i;:::-;21562:36;21414:191;;;;:::o;21611:170::-;21751:22;21747:1;21739:6;21735:14;21728:46;21611:170;:::o;21787:366::-;21929:3;21950:67;22014:2;22009:3;21950:67;:::i;:::-;21943:74;;22026:93;22115:3;22026:93;:::i;:::-;22144:2;22139:3;22135:12;22128:19;;21787:366;;;:::o;22159:419::-;22325:4;22363:2;22352:9;22348:18;22340:26;;22412:9;22406:4;22402:20;22398:1;22387:9;22383:17;22376:47;22440:131;22566:4;22440:131;:::i;:::-;22432:139;;22159:419;;;:::o;22584:174::-;22724:26;22720:1;22712:6;22708:14;22701:50;22584:174;:::o;22764:366::-;22906:3;22927:67;22991:2;22986:3;22927:67;:::i;:::-;22920:74;;23003:93;23092:3;23003:93;:::i;:::-;23121:2;23116:3;23112:12;23105:19;;22764:366;;;:::o;23136:419::-;23302:4;23340:2;23329:9;23325:18;23317:26;;23389:9;23383:4;23379:20;23375:1;23364:9;23360:17;23353:47;23417:131;23543:4;23417:131;:::i;:::-;23409:139;;23136:419;;;:::o;23561:162::-;23701:14;23697:1;23689:6;23685:14;23678:38;23561:162;:::o;23729:366::-;23871:3;23892:67;23956:2;23951:3;23892:67;:::i;:::-;23885:74;;23968:93;24057:3;23968:93;:::i;:::-;24086:2;24081:3;24077:12;24070:19;;23729:366;;;:::o;24101:419::-;24267:4;24305:2;24294:9;24290:18;24282:26;;24354:9;24348:4;24344:20;24340:1;24329:9;24325:17;24318:47;24382:131;24508:4;24382:131;:::i;:::-;24374:139;;24101:419;;;:::o;24526:147::-;24627:11;24664:3;24649:18;;24526:147;;;;:::o;24679:114::-;;:::o;24799:398::-;24958:3;24979:83;25060:1;25055:3;24979:83;:::i;:::-;24972:90;;25071:93;25160:3;25071:93;:::i;:::-;25189:1;25184:3;25180:11;25173:18;;24799:398;;;:::o;25203:379::-;25387:3;25409:147;25552:3;25409:147;:::i;:::-;25402:154;;25573:3;25566:10;;25203:379;;;:::o;25588:174::-;25728:26;25724:1;25716:6;25712:14;25705:50;25588:174;:::o;25768:366::-;25910:3;25931:67;25995:2;25990:3;25931:67;:::i;:::-;25924:74;;26007:93;26096:3;26007:93;:::i;:::-;26125:2;26120:3;26116:12;26109:19;;25768:366;;;:::o;26140:419::-;26306:4;26344:2;26333:9;26329:18;26321:26;;26393:9;26387:4;26383:20;26379:1;26368:9;26364:17;26357:47;26421:131;26547:4;26421:131;:::i;:::-;26413:139;;26140:419;;;:::o;26565:97::-;26624:6;26652:3;26642:13;;26565:97;;;;:::o;26668:141::-;26717:4;26740:3;26732:11;;26763:3;26760:1;26753:14;26797:4;26794:1;26784:18;26776:26;;26668:141;;;:::o;26815:93::-;26852:6;26899:2;26894;26887:5;26883:14;26879:23;26869:33;;26815:93;;;:::o;26914:107::-;26958:8;27008:5;27002:4;26998:16;26977:37;;26914:107;;;;:::o;27027:393::-;27096:6;27146:1;27134:10;27130:18;27169:97;27199:66;27188:9;27169:97;:::i;:::-;27287:39;27317:8;27306:9;27287:39;:::i;:::-;27275:51;;27359:4;27355:9;27348:5;27344:21;27335:30;;27408:4;27398:8;27394:19;27387:5;27384:30;27374:40;;27103:317;;27027:393;;;;;:::o;27426:60::-;27454:3;27475:5;27468:12;;27426:60;;;:::o;27492:142::-;27542:9;27575:53;27593:34;27602:24;27620:5;27602:24;:::i;:::-;27593:34;:::i;:::-;27575:53;:::i;:::-;27562:66;;27492:142;;;:::o;27640:75::-;27683:3;27704:5;27697:12;;27640:75;;;:::o;27721:269::-;27831:39;27862:7;27831:39;:::i;:::-;27892:91;27941:41;27965:16;27941:41;:::i;:::-;27933:6;27926:4;27920:11;27892:91;:::i;:::-;27886:4;27879:105;27797:193;27721:269;;;:::o;27996:73::-;28041:3;27996:73;:::o;28075:189::-;28152:32;;:::i;:::-;28193:65;28251:6;28243;28237:4;28193:65;:::i;:::-;28128:136;28075:189;;:::o;28270:186::-;28330:120;28347:3;28340:5;28337:14;28330:120;;;28401:39;28438:1;28431:5;28401:39;:::i;:::-;28374:1;28367:5;28363:13;28354:22;;28330:120;;;28270:186;;:::o;28462:543::-;28563:2;28558:3;28555:11;28552:446;;;28597:38;28629:5;28597:38;:::i;:::-;28681:29;28699:10;28681:29;:::i;:::-;28671:8;28667:44;28864:2;28852:10;28849:18;28846:49;;;28885:8;28870:23;;28846:49;28908:80;28964:22;28982:3;28964:22;:::i;:::-;28954:8;28950:37;28937:11;28908:80;:::i;:::-;28567:431;;28552:446;28462:543;;;:::o;29011:117::-;29065:8;29115:5;29109:4;29105:16;29084:37;;29011:117;;;;:::o;29134:169::-;29178:6;29211:51;29259:1;29255:6;29247:5;29244:1;29240:13;29211:51;:::i;:::-;29207:56;29292:4;29286;29282:15;29272:25;;29185:118;29134:169;;;;:::o;29308:295::-;29384:4;29530:29;29555:3;29549:4;29530:29;:::i;:::-;29522:37;;29592:3;29589:1;29585:11;29579:4;29576:21;29568:29;;29308:295;;;;:::o;29608:1403::-;29732:44;29772:3;29767;29732:44;:::i;:::-;29841:18;29833:6;29830:30;29827:56;;;29863:18;;:::i;:::-;29827:56;29907:38;29939:4;29933:11;29907:38;:::i;:::-;29992:67;30052:6;30044;30038:4;29992:67;:::i;:::-;30086:1;30115:2;30107:6;30104:14;30132:1;30127:632;;;;30803:1;30820:6;30817:84;;;30876:9;30871:3;30867:19;30854:33;30845:42;;30817:84;30927:67;30987:6;30980:5;30927:67;:::i;:::-;30921:4;30914:81;30776:229;30097:908;;30127:632;30179:4;30175:9;30167:6;30163:22;30213:37;30245:4;30213:37;:::i;:::-;30272:1;30286:215;30300:7;30297:1;30294:14;30286:215;;;30386:9;30381:3;30377:19;30364:33;30356:6;30349:49;30437:1;30429:6;30425:14;30415:24;;30484:2;30473:9;30469:18;30456:31;;30323:4;30320:1;30316:12;30311:17;;30286:215;;;30529:6;30520:7;30517:19;30514:186;;;30594:9;30589:3;30585:19;30572:33;30637:48;30679:4;30671:6;30667:17;30656:9;30637:48;:::i;:::-;30629:6;30622:64;30537:163;30514:186;30746:1;30742;30734:6;30730:14;30726:22;30720:4;30713:36;30134:625;;;30097:908;;29707:1304;;;29608:1403;;;:::o;31017:170::-;31157:22;31153:1;31145:6;31141:14;31134:46;31017:170;:::o;31193:366::-;31335:3;31356:67;31420:2;31415:3;31356:67;:::i;:::-;31349:74;;31432:93;31521:3;31432:93;:::i;:::-;31550:2;31545:3;31541:12;31534:19;;31193:366;;;:::o;31565:419::-;31731:4;31769:2;31758:9;31754:18;31746:26;;31818:9;31812:4;31808:20;31804:1;31793:9;31789:17;31782:47;31846:131;31972:4;31846:131;:::i;:::-;31838:139;;31565:419;;;:::o;31990:165::-;32130:17;32126:1;32118:6;32114:14;32107:41;31990:165;:::o;32161:366::-;32303:3;32324:67;32388:2;32383:3;32324:67;:::i;:::-;32317:74;;32400:93;32489:3;32400:93;:::i;:::-;32518:2;32513:3;32509:12;32502:19;;32161:366;;;:::o;32533:419::-;32699:4;32737:2;32726:9;32722:18;32714:26;;32786:9;32780:4;32776:20;32772:1;32761:9;32757:17;32750:47;32814:131;32940:4;32814:131;:::i;:::-;32806:139;;32533:419;;;:::o;32958:553::-;33135:4;33173:3;33162:9;33158:19;33150:27;;33187:71;33255:1;33244:9;33240:17;33231:6;33187:71;:::i;:::-;33268:72;33336:2;33325:9;33321:18;33312:6;33268:72;:::i;:::-;33350;33418:2;33407:9;33403:18;33394:6;33350:72;:::i;:::-;33432;33500:2;33489:9;33485:18;33476:6;33432:72;:::i;:::-;32958:553;;;;;;;:::o;33517:442::-;33666:4;33704:2;33693:9;33689:18;33681:26;;33717:71;33785:1;33774:9;33770:17;33761:6;33717:71;:::i;:::-;33798:72;33866:2;33855:9;33851:18;33842:6;33798:72;:::i;:::-;33880;33948:2;33937:9;33933:18;33924:6;33880:72;:::i;:::-;33517:442;;;;;;:::o;33965:157::-;34105:9;34101:1;34093:6;34089:14;34082:33;33965:157;:::o;34128:365::-;34270:3;34291:66;34355:1;34350:3;34291:66;:::i;:::-;34284:73;;34366:93;34455:3;34366:93;:::i;:::-;34484:2;34479:3;34475:12;34468:19;;34128:365;;;:::o;34499:419::-;34665:4;34703:2;34692:9;34688:18;34680:26;;34752:9;34746:4;34742:20;34738:1;34727:9;34723:17;34716:47;34780:131;34906:4;34780:131;:::i;:::-;34772:139;;34499:419;;;:::o;34924:180::-;34972:77;34969:1;34962:88;35069:4;35066:1;35059:15;35093:4;35090:1;35083:15;35110:233;35149:3;35172:24;35190:5;35172:24;:::i;:::-;35163:33;;35218:66;35211:5;35208:77;35205:103;;35288:18;;:::i;:::-;35205:103;35335:1;35328:5;35324:13;35317:20;;35110:233;;;:::o;35349:178::-;35489:30;35485:1;35477:6;35473:14;35466:54;35349:178;:::o;35533:366::-;35675:3;35696:67;35760:2;35755:3;35696:67;:::i;:::-;35689:74;;35772:93;35861:3;35772:93;:::i;:::-;35890:2;35885:3;35881:12;35874:19;;35533:366;;;:::o;35905:419::-;36071:4;36109:2;36098:9;36094:18;36086:26;;36158:9;36152:4;36148:20;36144:1;36133:9;36129:17;36122:47;36186:131;36312:4;36186:131;:::i;:::-;36178:139;;35905:419;;;:::o;36330:165::-;36470:17;36466:1;36458:6;36454:14;36447:41;36330:165;:::o;36501:366::-;36643:3;36664:67;36728:2;36723:3;36664:67;:::i;:::-;36657:74;;36740:93;36829:3;36740:93;:::i;:::-;36858:2;36853:3;36849:12;36842:19;;36501:366;;;:::o;36873:419::-;37039:4;37077:2;37066:9;37062:18;37054:26;;37126:9;37120:4;37116:20;37112:1;37101:9;37097:17;37090:47;37154:131;37280:4;37154:131;:::i;:::-;37146:139;;36873:419;;;:::o;37298:148::-;37400:11;37437:3;37422:18;;37298:148;;;;:::o;37452:390::-;37558:3;37586:39;37619:5;37586:39;:::i;:::-;37641:89;37723:6;37718:3;37641:89;:::i;:::-;37634:96;;37739:65;37797:6;37792:3;37785:4;37778:5;37774:16;37739:65;:::i;:::-;37829:6;37824:3;37820:16;37813:23;;37562:280;37452:390;;;;:::o;37848:400::-;38008:3;38029:84;38111:1;38106:3;38029:84;:::i;:::-;38022:91;;38122:93;38211:3;38122:93;:::i;:::-;38240:1;38235:3;38231:11;38224:18;;37848:400;;;:::o;38254:541::-;38487:3;38509:95;38600:3;38591:6;38509:95;:::i;:::-;38502:102;;38621:148;38765:3;38621:148;:::i;:::-;38614:155;;38786:3;38779:10;;38254:541;;;;:::o;38801:225::-;38941:34;38937:1;38929:6;38925:14;38918:58;39010:8;39005:2;38997:6;38993:15;38986:33;38801:225;:::o;39032:366::-;39174:3;39195:67;39259:2;39254:3;39195:67;:::i;:::-;39188:74;;39271:93;39360:3;39271:93;:::i;:::-;39389:2;39384:3;39380:12;39373:19;;39032:366;;;:::o;39404:419::-;39570:4;39608:2;39597:9;39593:18;39585:26;;39657:9;39651:4;39647:20;39643:1;39632:9;39628:17;39621:47;39685:131;39811:4;39685:131;:::i;:::-;39677:139;;39404:419;;;:::o;39829:242::-;39969:34;39965:1;39957:6;39953:14;39946:58;40038:25;40033:2;40025:6;40021:15;40014:50;39829:242;:::o;40077:366::-;40219:3;40240:67;40304:2;40299:3;40240:67;:::i;:::-;40233:74;;40316:93;40405:3;40316:93;:::i;:::-;40434:2;40429:3;40425:12;40418:19;;40077:366;;;:::o;40449:419::-;40615:4;40653:2;40642:9;40638:18;40630:26;;40702:9;40696:4;40692:20;40688:1;40677:9;40673:17;40666:47;40730:131;40856:4;40730:131;:::i;:::-;40722:139;;40449:419;;;:::o;40874:233::-;41014:34;41010:1;41002:6;40998:14;40991:58;41083:16;41078:2;41070:6;41066:15;41059:41;40874:233;:::o;41113:366::-;41255:3;41276:67;41340:2;41335:3;41276:67;:::i;:::-;41269:74;;41352:93;41441:3;41352:93;:::i;:::-;41470:2;41465:3;41461:12;41454:19;;41113:366;;;:::o;41485:419::-;41651:4;41689:2;41678:9;41674:18;41666:26;;41738:9;41732:4;41728:20;41724:1;41713:9;41709:17;41702:47;41766:131;41892:4;41766:131;:::i;:::-;41758:139;;41485:419;;;:::o;41910:1395::-;42027:37;42060:3;42027:37;:::i;:::-;42129:18;42121:6;42118:30;42115:56;;;42151:18;;:::i;:::-;42115:56;42195:38;42227:4;42221:11;42195:38;:::i;:::-;42280:67;42340:6;42332;42326:4;42280:67;:::i;:::-;42374:1;42398:4;42385:17;;42430:2;42422:6;42419:14;42447:1;42442:618;;;;43104:1;43121:6;43118:77;;;43170:9;43165:3;43161:19;43155:26;43146:35;;43118:77;43221:67;43281:6;43274:5;43221:67;:::i;:::-;43215:4;43208:81;43077:222;42412:887;;42442:618;42494:4;42490:9;42482:6;42478:22;42528:37;42560:4;42528:37;:::i;:::-;42587:1;42601:208;42615:7;42612:1;42609:14;42601:208;;;42694:9;42689:3;42685:19;42679:26;42671:6;42664:42;42745:1;42737:6;42733:14;42723:24;;42792:2;42781:9;42777:18;42764:31;;42638:4;42635:1;42631:12;42626:17;;42601:208;;;42837:6;42828:7;42825:19;42822:179;;;42895:9;42890:3;42886:19;42880:26;42938:48;42980:4;42972:6;42968:17;42957:9;42938:48;:::i;:::-;42930:6;42923:64;42845:156;42822:179;43047:1;43043;43035:6;43031:14;43027:22;43021:4;43014:36;42449:611;;;42412:887;;42002:1303;;;41910:1395;;:::o;43311:85::-;43356:7;43385:5;43374:16;;43311:85;;;:::o;43402:86::-;43437:7;43477:4;43470:5;43466:16;43455:27;;43402:86;;;:::o;43494:154::-;43550:9;43583:59;43599:42;43608:32;43634:5;43608:32;:::i;:::-;43599:42;:::i;:::-;43583:59;:::i;:::-;43570:72;;43494:154;;;:::o;43654:143::-;43747:43;43784:5;43747:43;:::i;:::-;43742:3;43735:56;43654:143;;:::o;43803:234::-;43902:4;43940:2;43929:9;43925:18;43917:26;;43953:77;44027:1;44016:9;44012:17;44003:6;43953:77;:::i;:::-;43803:234;;;;:::o;44043:182::-;44183:34;44179:1;44171:6;44167:14;44160:58;44043:182;:::o;44231:366::-;44373:3;44394:67;44458:2;44453:3;44394:67;:::i;:::-;44387:74;;44470:93;44559:3;44470:93;:::i;:::-;44588:2;44583:3;44579:12;44572:19;;44231:366;;;:::o;44603:419::-;44769:4;44807:2;44796:9;44792:18;44784:26;;44856:9;44850:4;44846:20;44842:1;44831:9;44827:17;44820:47;44884:131;45010:4;44884:131;:::i;:::-;44876:139;;44603:419;;;:::o;45028:165::-;45168:17;45164:1;45156:6;45152:14;45145:41;45028:165;:::o;45199:366::-;45341:3;45362:67;45426:2;45421:3;45362:67;:::i;:::-;45355:74;;45438:93;45527:3;45438:93;:::i;:::-;45556:2;45551:3;45547:12;45540:19;;45199:366;;;:::o;45571:419::-;45737:4;45775:2;45764:9;45760:18;45752:26;;45824:9;45818:4;45814:20;45810:1;45799:9;45795:17;45788:47;45852:131;45978:4;45852:131;:::i;:::-;45844:139;;45571:419;;;:::o;45996:167::-;46136:19;46132:1;46124:6;46120:14;46113:43;45996:167;:::o;46169:366::-;46311:3;46332:67;46396:2;46391:3;46332:67;:::i;:::-;46325:74;;46408:93;46497:3;46408:93;:::i;:::-;46526:2;46521:3;46517:12;46510:19;;46169:366;;;:::o;46541:419::-;46707:4;46745:2;46734:9;46730:18;46722:26;;46794:9;46788:4;46784:20;46780:1;46769:9;46765:17;46758:47;46822:131;46948:4;46822:131;:::i;:::-;46814:139;;46541:419;;;:::o;46966:177::-;47106:29;47102:1;47094:6;47090:14;47083:53;46966:177;:::o;47149:366::-;47291:3;47312:67;47376:2;47371:3;47312:67;:::i;:::-;47305:74;;47388:93;47477:3;47388:93;:::i;:::-;47506:2;47501:3;47497:12;47490:19;;47149:366;;;:::o;47521:419::-;47687:4;47725:2;47714:9;47710:18;47702:26;;47774:9;47768:4;47764:20;47760:1;47749:9;47745:17;47738:47;47802:131;47928:4;47802:131;:::i;:::-;47794:139;;47521:419;;;:::o;47946:173::-;48086:25;48082:1;48074:6;48070:14;48063:49;47946:173;:::o;48125:366::-;48267:3;48288:67;48352:2;48347:3;48288:67;:::i;:::-;48281:74;;48364:93;48453:3;48364:93;:::i;:::-;48482:2;48477:3;48473:12;48466:19;;48125:366;;;:::o;48497:419::-;48663:4;48701:2;48690:9;48686:18;48678:26;;48750:9;48744:4;48740:20;48736:1;48725:9;48721:17;48714:47;48778:131;48904:4;48778:131;:::i;:::-;48770:139;;48497:419;;;:::o;48922:171::-;48961:3;48984:24;49002:5;48984:24;:::i;:::-;48975:33;;49030:4;49023:5;49020:15;49017:41;;49038:18;;:::i;:::-;49017:41;49085:1;49078:5;49074:13;49067:20;;48922:171;;;:::o;49099:163::-;49239:15;49235:1;49227:6;49223:14;49216:39;49099:163;:::o;49268:366::-;49410:3;49431:67;49495:2;49490:3;49431:67;:::i;:::-;49424:74;;49507:93;49596:3;49507:93;:::i;:::-;49625:2;49620:3;49616:12;49609:19;;49268:366;;;:::o;49640:419::-;49806:4;49844:2;49833:9;49829:18;49821:26;;49893:9;49887:4;49883:20;49879:1;49868:9;49864:17;49857:47;49921:131;50047:4;49921:131;:::i;:::-;49913:139;;49640:419;;;:::o;50065:435::-;50245:3;50267:95;50358:3;50349:6;50267:95;:::i;:::-;50260:102;;50379:95;50470:3;50461:6;50379:95;:::i;:::-;50372:102;;50491:3;50484:10;;50065:435;;;;;:::o;50506:230::-;50646:34;50642:1;50634:6;50630:14;50623:58;50715:13;50710:2;50702:6;50698:15;50691:38;50506:230;:::o;50742:366::-;50884:3;50905:67;50969:2;50964:3;50905:67;:::i;:::-;50898:74;;50981:93;51070:3;50981:93;:::i;:::-;51099:2;51094:3;51090:12;51083:19;;50742:366;;;:::o;51114:419::-;51280:4;51318:2;51307:9;51303:18;51295:26;;51367:9;51361:4;51357:20;51353:1;51342:9;51338:17;51331:47;51395:131;51521:4;51395:131;:::i;:::-;51387:139;;51114:419;;;:::o;51539:239::-;51679:34;51675:1;51667:6;51663:14;51656:58;51748:22;51743:2;51735:6;51731:15;51724:47;51539:239;:::o;51784:366::-;51926:3;51947:67;52011:2;52006:3;51947:67;:::i;:::-;51940:74;;52023:93;52112:3;52023:93;:::i;:::-;52141:2;52136:3;52132:12;52125:19;;51784:366;;;:::o;52156:419::-;52322:4;52360:2;52349:9;52345:18;52337:26;;52409:9;52403:4;52399:20;52395:1;52384:9;52380:17;52373:47;52437:131;52563:4;52437:131;:::i;:::-;52429:139;;52156:419;;;:::o;52581:98::-;52632:6;52666:5;52660:12;52650:22;;52581:98;;;:::o;52685:168::-;52768:11;52802:6;52797:3;52790:19;52842:4;52837:3;52833:14;52818:29;;52685:168;;;;:::o;52859:373::-;52945:3;52973:38;53005:5;52973:38;:::i;:::-;53027:70;53090:6;53085:3;53027:70;:::i;:::-;53020:77;;53106:65;53164:6;53159:3;53152:4;53145:5;53141:16;53106:65;:::i;:::-;53196:29;53218:6;53196:29;:::i;:::-;53191:3;53187:39;53180:46;;52949:283;52859:373;;;;:::o;53238:640::-;53433:4;53471:3;53460:9;53456:19;53448:27;;53485:71;53553:1;53542:9;53538:17;53529:6;53485:71;:::i;:::-;53566:72;53634:2;53623:9;53619:18;53610:6;53566:72;:::i;:::-;53648;53716:2;53705:9;53701:18;53692:6;53648:72;:::i;:::-;53767:9;53761:4;53757:20;53752:2;53741:9;53737:18;53730:48;53795:76;53866:4;53857:6;53795:76;:::i;:::-;53787:84;;53238:640;;;;;;;:::o;53884:141::-;53940:5;53971:6;53965:13;53956:22;;53987:32;54013:5;53987:32;:::i;:::-;53884:141;;;;:::o;54031:349::-;54100:6;54149:2;54137:9;54128:7;54124:23;54120:32;54117:119;;;54155:79;;:::i;:::-;54117:119;54275:1;54300:63;54355:7;54346:6;54335:9;54331:22;54300:63;:::i;:::-;54290:73;;54246:127;54031:349;;;;:::o
Swarm Source
ipfs://321e763c4fd1287bd7ba5a352690e041ec27075cf13ef789803f86e9a3848bf4
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.