Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 17498540 | 525 days ago | IN | 0 ETH | 0.07679665 |
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-17 */ // 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 view returns(uint256) { return 30000; } // // =============== 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 transfer 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":"view","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
60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d2565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000175565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff1614620000ec5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e39190620001b5565b60405180910390a15b565b600082825260208201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b60006200015d602783620000ee565b91506200016a82620000ff565b604082019050919050565b6000602082019050818103600083015262000190816200014e565b9050919050565b600060ff82169050919050565b620001af8162000197565b82525050565b6000602082019050620001cc6000830184620001a4565b92915050565b6155e780620001e26000396000f3fe60806040526004361061025c5760003560e01c8063650b00f611610144578063ac52e644116100b6578063d5abeb011161007a578063d5abeb01146108e9578063e58306f914610914578063e985e9c51461093d578063f2fde38b1461097a578063f4a0a528146109a3578063f62d1888146109cc5761025c565b8063ac52e644146107ed578063b1a6505f14610816578063b88d4fde14610853578063c6004ed61461086f578063c87b56dd146108ac5761025c565b80638da5cb5b116101085780638da5cb5b146106f157806394d216d61461071c57806395d89b4114610745578063a0c5407814610770578063a22cb4651461079b578063a694fc3a146107c45761025c565b8063650b00f6146105f85780636817c76c1461063557806370a0823114610660578063715018a61461069d57806372abc8b7146106b45761025c565b80632cba8123116101dd578063453c2310116101a1578063453c2310146104d8578063493770cc1461050357806349a758a31461052c57806355f804b3146105695780635d3eea91146105925780636352211e146105bb5761025c565b80632cba81231461040257806335b504c51461043f5780633ccfd60b1461047c57806340a9c8df1461049357806342842e0e146104bc5761025c565b80631249c58b116102245780631249c58b1461035f57806318160ddd146103695780631f85e3ca1461039457806323b872dd146103bd5780632799cde0146103d95761025c565b806301ffc9a71461026157806306fdde031461029e578063081812fc146102c957806309308e5d14610306578063095ea7b314610343575b600080fd5b34801561026d57600080fd5b5061028860048036038101906102839190613b17565b6109f5565b6040516102959190613b5f565b60405180910390f35b3480156102aa57600080fd5b506102b3610a56565b6040516102c09190613c0a565b60405180910390f35b3480156102d557600080fd5b506102f060048036038101906102eb9190613c62565b610af1565b6040516102fd9190613cd0565b60405180910390f35b34801561031257600080fd5b5061032d60048036038101906103289190613d17565b610b79565b60405161033a9190613d66565b60405180910390f35b61035d60048036038101906103589190613d81565b610b9e565b005b610367610bae565b005b34801561037557600080fd5b5061037e610dd2565b60405161038b9190613d66565b60405180910390f35b3480156103a057600080fd5b506103bb60048036038101906103b69190613ded565b610dfb565b005b6103d760048036038101906103d29190613e1a565b610e20565b005b3480156103e557600080fd5b5061040060048036038101906103fb9190613c62565b610ed5565b005b34801561040e57600080fd5b5061042960048036038101906104249190613e6d565b610f29565b6040516104369190613cd0565b60405180910390f35b34801561044b57600080fd5b5061046660048036038101906104619190613c62565b610f6b565b6040516104739190613d66565b60405180910390f35b34801561048857600080fd5b50610491610f83565b005b34801561049f57600080fd5b506104ba60048036038101906104b59190613c62565b611048565b005b6104d660048036038101906104d19190613e1a565b61109c565b005b3480156104e457600080fd5b506104ed6110bc565b6040516104fa9190613d66565b60405180910390f35b34801561050f57600080fd5b5061052a60048036038101906105259190613ded565b6110c2565b005b34801561053857600080fd5b50610553600480360381019061054e9190613c62565b6110e7565b6040516105609190613cd0565b60405180910390f35b34801561057557600080fd5b50610590600480360381019061058b9190613f12565b61111a565b005b34801561059e57600080fd5b506105b960048036038101906105b49190613c62565b611138565b005b3480156105c757600080fd5b506105e260048036038101906105dd9190613c62565b611276565b6040516105ef9190613cd0565b60405180910390f35b34801561060457600080fd5b5061061f600480360381019061061a9190613c62565b611288565b60405161062c9190613d66565b60405180910390f35b34801561064157600080fd5b5061064a6112a0565b6040516106579190613d66565b60405180910390f35b34801561066c57600080fd5b5061068760048036038101906106829190613f5f565b6112a6565b6040516106949190613d66565b60405180910390f35b3480156106a957600080fd5b506106b2611367565b005b3480156106c057600080fd5b506106db60048036038101906106d69190613c62565b61137b565b6040516106e89190613b5f565b60405180910390f35b3480156106fd57600080fd5b5061070661139a565b6040516107139190613cd0565b60405180910390f35b34801561072857600080fd5b50610743600480360381019061073e9190613d17565b6113c4565b005b34801561075157600080fd5b5061075a61141a565b6040516107679190613c0a565b60405180910390f35b34801561077c57600080fd5b506107856114b5565b6040516107929190613c0a565b60405180910390f35b3480156107a757600080fd5b506107c260048036038101906107bd9190613f8c565b611543565b005b3480156107d057600080fd5b506107eb60048036038101906107e69190613c62565b611657565b005b3480156107f957600080fd5b50610814600480360381019061080f9190614078565b61178c565b005b34801561082257600080fd5b5061083d60048036038101906108389190613f5f565b6118a9565b60405161084a9190613b5f565b60405180910390f35b61086d60048036038101906108689190614229565b6118c9565b005b34801561087b57600080fd5b5061089660048036038101906108919190613f5f565b611980565b6040516108a39190613d66565b60405180910390f35b3480156108b857600080fd5b506108d360048036038101906108ce9190613c62565b611998565b6040516108e09190613c0a565b60405180910390f35b3480156108f557600080fd5b506108fe611a11565b60405161090b9190613d66565b60405180910390f35b34801561092057600080fd5b5061093b60048036038101906109369190613d81565b611a1b565b005b34801561094957600080fd5b50610964600480360381019061095f91906142ac565b611a31565b6040516109719190613b5f565b60405180910390f35b34801561098657600080fd5b506109a1600480360381019061099c9190613f5f565b611ace565b005b3480156109af57600080fd5b506109ca60048036038101906109c59190613c62565b611b51565b005b3480156109d857600080fd5b506109f360048036038101906109ee919061438d565b611b63565b005b600063706e848960e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a4f5750610a4e82611e81565b5b9050919050565b6060610a60611f13565b6002018054610a6e90614405565b80601f0160208091040260200160405190810160405280929190818152602001828054610a9a90614405565b8015610ae75780601f10610abc57610100808354040283529160200191610ae7565b820191906000526020600020905b815481529060010190602001808311610aca57829003601f168201915b5050505050905090565b6000610afc82611f40565b610b32576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b3a611f13565b600601600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6068602052816000526040600020602052806000526040600020600091509150505481565b610baa82826001611fb1565b5050565b606c60019054906101000a900460ff16610bfd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf490614482565b60405180910390fd5b610c05611a11565b610c0d610dd2565b10610c4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c44906144ee565b60405180910390fd5b606b54341015610c92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c899061455a565b60405180910390fd5b606a54606d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410610d15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0c906145c6565b60405180910390fd5b6001606d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610d659190614615565b92505081905550610d77336001612106565b33606e6000610d84610dd2565b815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000610ddc612114565b610de4611f13565b60010154610df0611f13565b600001540303905090565b610e0361211d565b80606c60016101000a81548160ff02191690831515021790555050565b606c60009054906101000a900460ff16610e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6690614695565b60405180910390fd5b6000606f60008381526020019081526020016000205414610ec5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ebc90614701565b60405180910390fd5b610ed083838361219b565b505050565b610ede81611f40565b610f1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f149061476d565b60405180910390fd5b610f26816121f3565b50565b60676020528160005260406000206020528060005260406000206000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606f6020528060005260406000206000915090505481565b610f8b61211d565b6000479050600033905060008173ffffffffffffffffffffffffffffffffffffffff1683604051610fbb906147be565b60006040518083038185875af1925050503d8060008114610ff8576040519150601f19603f3d011682016040523d82523d6000602084013e610ffd565b606091505b50508091505080611043576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103a9061481f565b60405180910390fd5b505050565b61105181611f40565b611090576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110879061476d565b60405180910390fd5b6110998161245f565b50565b6110b7838383604051806020016040528060008152506118c9565b505050565b606a5481565b6110ca61211d565b80606c60006101000a81548160ff02191690831515021790555050565b606e6020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61112261211d565b8181606991826111339291906149f6565b505050565b61114181611276565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146111ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a590614b12565b60405180910390fd5b6000606f60008381526020019081526020016000205414611204576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111fb90614b7e565b60405180910390fd5b6000606f60008381526020019081526020016000205490506000606f6000848152602001908152602001600020819055507fc1e00202ee2c06861d326fc6374026b751863ff64218ccbaa38c3e603a8e72c28233834260405161126a9493929190614b9e565b60405180910390a15050565b60006112818261283a565b9050919050565b60666020528060005260406000206000915090505481565b606b5481565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361130d576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff61131e611f13565b60050160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b61136f61211d565b611379600061294d565b565b6000806066600084815260200190815260200160002054149050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6113cd82611f40565b61140c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114039061476d565b60405180910390fd5b6114168282612a13565b5050565b6060611424611f13565b600301805461143290614405565b80601f016020809104026020016040519081016040528092919081815260200182805461145e90614405565b80156114ab5780601f10611480576101008083540402835291602001916114ab565b820191906000526020600020905b81548152906001019060200180831161148e57829003601f168201915b5050505050905090565b606980546114c290614405565b80601f01602080910402602001604051908101604052809291908181526020018280546114ee90614405565b801561153b5780601f106115105761010080835404028352916020019161153b565b820191906000526020600020905b81548152906001019060200180831161151e57829003601f168201915b505050505081565b8061154c611f13565b6007016000611559612df0565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611606612df0565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161164b9190613b5f565b60405180910390a35050565b61166081611276565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116c490614b12565b60405180910390fd5b6000606f60008381526020019081526020016000205414611723576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161171a90614b7e565b60405180910390fd5b42606f6000838152602001908152602001600020819055507f02567b2553aeb44e4ddd5d68462774dc3de158cb0f2c2da1740e729b22086aff8133606f60008581526020019081526020016000205460405161178193929190614be3565b60405180910390a150565b61179461211d565b8181905084849050146117dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117d390614c66565b60405180910390fd5b60005b848490508110156118a2578282828181106117fd576117fc614c86565b5b90506020020160208101906118129190613ded565b6065600087878581811061182957611828614c86565b5b905060200201602081019061183e9190613f5f565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061189a90614cb5565b9150506117df565b5050505050565b60656020528060005260406000206000915054906101000a900460ff1681565b606c60009054906101000a900460ff16611918576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161190f90614695565b60405180910390fd5b6000606f6000848152602001908152602001600020541461196e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196590614701565b60405180910390fd5b61197a84848484612df8565b50505050565b606d6020528060005260406000206000915090505481565b60606119a382611f40565b6119e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119d990614d49565b60405180910390fd5b6119eb82612e52565b6040516020016119fb9190614dc8565b6040516020818303038152906040529050919050565b6000617530905090565b611a2361211d565b611a2d8282612106565b5050565b6000611a3b611f13565b60070160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611ad661211d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611b45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3c90614e5c565b60405180910390fd5b611b4e8161294d565b50565b611b5961211d565b80606b8190555050565b611b6b612ef0565b60000160019054906101000a900460ff16611b9f57611b88612ef0565b60000160009054906101000a900460ff1615611ba8565b611ba7612f1d565b5b611be7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bde90614eee565b60405180910390fd5b6000611bf1612ef0565b60000160019054906101000a900460ff161590508015611c54576001611c15612ef0565b60000160016101000a81548160ff0219169083151502179055506001611c39612ef0565b60000160006101000a81548160ff0219169083151502179055505b60008060019054906101000a900460ff16159050808015611c855750600160008054906101000a900460ff1660ff16105b80611cb25750611c9430612f34565b158015611cb15750600160008054906101000a900460ff1660ff16145b5b611cf1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce890614f80565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015611d2e576001600060016101000a81548160ff0219169083151502179055505b611da26040518060400160405280601e81526020017f5461746120417661746172206279204a756c69616e277320456469746f7200008152506040518060400160405280600481526020017f5441544100000000000000000000000000000000000000000000000000000000815250612f57565b8260699081611db19190614fa0565b506001606c60006101000a81548160ff0219169083151502179055506000606c60016101000a81548160ff0219169083151502179055506001606a819055506000606b819055508015611e515760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986001604051611e4891906150ba565b60405180910390a15b508015611e7d576000611e62612ef0565b60000160016101000a81548160ff0219169083151502179055505b5050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611edc57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611f0c5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6000807f2569078dfb4b0305704d3008e7403993ae9601b85f7ae5e742de3de8f8011c4090508091505090565b600081611f4b612114565b11158015611f635750611f5c611f13565b6000015482105b8015611faa575060007c0100000000000000000000000000000000000000000000000000000000611f92611f13565b60040160008581526020019081526020016000205416145b9050919050565b6000611fbc83611276565b90508115612047578073ffffffffffffffffffffffffffffffffffffffff16611fe3612df0565b73ffffffffffffffffffffffffffffffffffffffff16146120465761200f8161200a612df0565b611a31565b612045576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b83612050611f13565b600601600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b6121108282612fbc565b5050565b60006001905090565b61212561319c565b73ffffffffffffffffffffffffffffffffffffffff1661214361139a565b73ffffffffffffffffffffffffffffffffffffffff1614612199576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161219090615121565b60405180910390fd5b565b6121a48161137b565b6121e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121da9061518d565b60405180910390fd5b6121ee8383836131a4565b505050565b606560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661227f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612276906151f9565b60405180910390fd5b60006068600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414612312576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161230990615265565b60405180910390fd5b6000600160666000848152602001908152602001600020546123349190614615565b90503360676000848152602001908152602001600020600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806068600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060666000838152602001908152602001600020600081548092919061241290614cb5565b91905055503373ffffffffffffffffffffffffffffffffffffffff16827f9ecfd70e9ff36df72989324a49559383d39f9290d700b10cf5ac10dcb68d264360405160405180910390a35050565b606560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166124eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e2906151f9565b60405180910390fd5b60006068600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008103612583576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161257a906152d1565b60405180910390fd5b60006066600084815260200190815260200160002054905080821461270d57600060676000858152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060676000868152602001908152602001600020600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060676000868152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826068600086815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050612772565b600060676000858152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006068600085815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506066600084815260200190815260200160002060008154809291906127ec906152f1565b91905055503373ffffffffffffffffffffffffffffffffffffffff16837f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3760405160405180910390a3505050565b600081612845612114565b1161291657612852611f13565b600401600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036129155760008103612910576128a0611f13565b6000015482106128dc576040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b6128e5611f13565b60040160008360019003935083815260200190815260200160002054905060008103612948576128dd565b612948565b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b606560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a97906151f9565b60405180910390fd5b60006068600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008103612b38576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b2f90615366565b60405180910390fd5b600060666000858152602001908152602001600020549050808214612cc257600060676000868152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060676000878152602001908152602001600020600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060676000878152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826068600087815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050612d27565b600060676000868152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006068600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550606660008581526020019081526020016000206000815480929190612da1906152f1565b91905055508273ffffffffffffffffffffffffffffffffffffffff16847f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3760405160405180910390a350505050565b600033905090565b612e018261137b565b612e40576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e379061518d565b60405180910390fd5b612e4c848484846134fc565b50505050565b6060612e5d82611f40565b612e93576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612e9d61356f565b90506000815103612ebd5760405180602001604052806000815250612ee8565b80612ec784613601565b604051602001612ed8929190615386565b6040516020818303038152906040525b915050919050565b6000807fee151c8401928dc223602bb187aff91b9a56c7cae5476ef1b3287b085a16c85f90508091505090565b6000803090506000813b9050600081149250505090565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16612fa6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f9d9061541c565b60405180910390fd5b612fb08282613651565b612fb86136b7565b5050565b6000612fc6611f13565b60000154905060008203613006576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6130136000848385613710565b600160406001901b178202613026611f13565b60050160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550613093836130846000866000613716565b61308d8561373e565b1761374e565b61309b611f13565b600401600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461313d57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050613102565b5060008203613178576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80613181611f13565b6000018190555050506131976000848385613779565b505050565b600033905090565b60006131af8261283a565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613216576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806132228461377f565b915091506132388187613233612df0565b6137af565b6132845761324d86613248612df0565b611a31565b613283576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036132ea576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6132f78686866001613710565b801561330257600082555b61330a611f13565b60050160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550613361611f13565b60050160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055506133e2856133be888887613716565b7c02000000000000000000000000000000000000000000000000000000001761374e565b6133ea611f13565b60040160008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084160361348c576000600185019050600061343b611f13565b6004016000838152602001908152602001600020540361348a5761345d611f13565b6000015481146134895783613470611f13565b6004016000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46134f48686866001613779565b505050505050565b613507848484610e20565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461356957613532848484846137f3565b613568576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b60606069805461357e90614405565b80601f01602080910402602001604051908101604052809291908181526020018280546135aa90614405565b80156135f75780601f106135cc576101008083540402835291602001916135f7565b820191906000526020600020905b8154815290600101906020018083116135da57829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b60011561363c57600184039350600a81066030018453600a810490508061361a575b50828103602084039350808452505050919050565b613659612ef0565b60000160019054906101000a900460ff166136a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136a0906154ae565b60405180910390fd5b6136b38282613943565b5050565b600060019054906101000a900460ff16613706576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136fd9061541c565b60405180910390fd5b61370e6139e8565b565b50505050565b60008060e883901c905060e861372d868684613a41565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b600080600061378c611f13565b600601600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613819612df0565b8786866040518563ffffffff1660e01b815260040161383b9493929190615523565b6020604051808303816000875af192505050801561387757506040513d601f19601f820116820180604052508101906138749190615584565b60015b6138f0573d80600081146138a7576040519150601f19603f3d011682016040523d82523d6000602084013e6138ac565b606091505b5060008151036138e8576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b61394b612ef0565b60000160019054906101000a900460ff1661399b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613992906154ae565b60405180910390fd5b816139a4611f13565b60020190816139b39190614fa0565b50806139bd611f13565b60030190816139cc9190614fa0565b506139d5612114565b6139dd611f13565b600001819055505050565b600060019054906101000a900460ff16613a37576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a2e9061541c565b60405180910390fd5b613a3f613a4a565b565b60009392505050565b600060019054906101000a900460ff16613a99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a909061541c565b60405180910390fd5b613aa9613aa461319c565b61294d565b565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613af481613abf565b8114613aff57600080fd5b50565b600081359050613b1181613aeb565b92915050565b600060208284031215613b2d57613b2c613ab5565b5b6000613b3b84828501613b02565b91505092915050565b60008115159050919050565b613b5981613b44565b82525050565b6000602082019050613b746000830184613b50565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613bb4578082015181840152602081019050613b99565b60008484015250505050565b6000601f19601f8301169050919050565b6000613bdc82613b7a565b613be68185613b85565b9350613bf6818560208601613b96565b613bff81613bc0565b840191505092915050565b60006020820190508181036000830152613c248184613bd1565b905092915050565b6000819050919050565b613c3f81613c2c565b8114613c4a57600080fd5b50565b600081359050613c5c81613c36565b92915050565b600060208284031215613c7857613c77613ab5565b5b6000613c8684828501613c4d565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613cba82613c8f565b9050919050565b613cca81613caf565b82525050565b6000602082019050613ce56000830184613cc1565b92915050565b613cf481613caf565b8114613cff57600080fd5b50565b600081359050613d1181613ceb565b92915050565b60008060408385031215613d2e57613d2d613ab5565b5b6000613d3c85828601613c4d565b9250506020613d4d85828601613d02565b9150509250929050565b613d6081613c2c565b82525050565b6000602082019050613d7b6000830184613d57565b92915050565b60008060408385031215613d9857613d97613ab5565b5b6000613da685828601613d02565b9250506020613db785828601613c4d565b9150509250929050565b613dca81613b44565b8114613dd557600080fd5b50565b600081359050613de781613dc1565b92915050565b600060208284031215613e0357613e02613ab5565b5b6000613e1184828501613dd8565b91505092915050565b600080600060608486031215613e3357613e32613ab5565b5b6000613e4186828701613d02565b9350506020613e5286828701613d02565b9250506040613e6386828701613c4d565b9150509250925092565b60008060408385031215613e8457613e83613ab5565b5b6000613e9285828601613c4d565b9250506020613ea385828601613c4d565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f840112613ed257613ed1613ead565b5b8235905067ffffffffffffffff811115613eef57613eee613eb2565b5b602083019150836001820283011115613f0b57613f0a613eb7565b5b9250929050565b60008060208385031215613f2957613f28613ab5565b5b600083013567ffffffffffffffff811115613f4757613f46613aba565b5b613f5385828601613ebc565b92509250509250929050565b600060208284031215613f7557613f74613ab5565b5b6000613f8384828501613d02565b91505092915050565b60008060408385031215613fa357613fa2613ab5565b5b6000613fb185828601613d02565b9250506020613fc285828601613dd8565b9150509250929050565b60008083601f840112613fe257613fe1613ead565b5b8235905067ffffffffffffffff811115613fff57613ffe613eb2565b5b60208301915083602082028301111561401b5761401a613eb7565b5b9250929050565b60008083601f84011261403857614037613ead565b5b8235905067ffffffffffffffff81111561405557614054613eb2565b5b60208301915083602082028301111561407157614070613eb7565b5b9250929050565b6000806000806040858703121561409257614091613ab5565b5b600085013567ffffffffffffffff8111156140b0576140af613aba565b5b6140bc87828801613fcc565b9450945050602085013567ffffffffffffffff8111156140df576140de613aba565b5b6140eb87828801614022565b925092505092959194509250565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61413682613bc0565b810181811067ffffffffffffffff82111715614155576141546140fe565b5b80604052505050565b6000614168613aab565b9050614174828261412d565b919050565b600067ffffffffffffffff821115614194576141936140fe565b5b61419d82613bc0565b9050602081019050919050565b82818337600083830152505050565b60006141cc6141c784614179565b61415e565b9050828152602081018484840111156141e8576141e76140f9565b5b6141f38482856141aa565b509392505050565b600082601f8301126142105761420f613ead565b5b81356142208482602086016141b9565b91505092915050565b6000806000806080858703121561424357614242613ab5565b5b600061425187828801613d02565b945050602061426287828801613d02565b935050604061427387828801613c4d565b925050606085013567ffffffffffffffff81111561429457614293613aba565b5b6142a0878288016141fb565b91505092959194509250565b600080604083850312156142c3576142c2613ab5565b5b60006142d185828601613d02565b92505060206142e285828601613d02565b9150509250929050565b600067ffffffffffffffff821115614307576143066140fe565b5b61431082613bc0565b9050602081019050919050565b600061433061432b846142ec565b61415e565b90508281526020810184848401111561434c5761434b6140f9565b5b6143578482856141aa565b509392505050565b600082601f83011261437457614373613ead565b5b813561438484826020860161431d565b91505092915050565b6000602082840312156143a3576143a2613ab5565b5b600082013567ffffffffffffffff8111156143c1576143c0613aba565b5b6143cd8482850161435f565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061441d57607f821691505b6020821081036144305761442f6143d6565b5b50919050565b7f6d696e74206e6f7420656e61626c656400000000000000000000000000000000600082015250565b600061446c601083613b85565b915061447782614436565b602082019050919050565b6000602082019050818103600083015261449b8161445f565b9050919050565b7f736f6c64206f7574000000000000000000000000000000000000000000000000600082015250565b60006144d8600883613b85565b91506144e3826144a2565b602082019050919050565b60006020820190508181036000830152614507816144cb565b9050919050565b7f696e73756666696369656e742076616c75650000000000000000000000000000600082015250565b6000614544601283613b85565b915061454f8261450e565b602082019050919050565b6000602082019050818103600083015261457381614537565b9050919050565b7f7265616368656420746865206d6178696d756d00000000000000000000000000600082015250565b60006145b0601383613b85565b91506145bb8261457a565b602082019050919050565b600060208201905081810360008301526145df816145a3565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061462082613c2c565b915061462b83613c2c565b9250828201905080821115614643576146426145e6565b5b92915050565b7f7472616e73666572206e6f7420656e61626c6564000000000000000000000000600082015250565b600061467f601483613b85565b915061468a82614649565b602082019050919050565b600060208201905081810360008301526146ae81614672565b9050919050565b7f43616e6e6f74207472616e73666572207374616b656420746f6b656e00000000600082015250565b60006146eb601c83613b85565b91506146f6826146b5565b602082019050919050565b6000602082019050818103600083015261471a816146de565b9050919050565b7f546f6b656e202165786973740000000000000000000000000000000000000000600082015250565b6000614757600c83613b85565b915061476282614721565b602082019050919050565b600060208201905081810360008301526147868161474a565b9050919050565b600081905092915050565b50565b60006147a860008361478d565b91506147b382614798565b600082019050919050565b60006147c98261479b565b9150819050919050565b7f5472616e73616374696f6e20556e7375636365737366756c0000000000000000600082015250565b6000614809601883613b85565b9150614814826147d3565b602082019050919050565b60006020820190508181036000830152614838816147fc565b9050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026148ac7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261486f565b6148b6868361486f565b95508019841693508086168417925050509392505050565b6000819050919050565b60006148f36148ee6148e984613c2c565b6148ce565b613c2c565b9050919050565b6000819050919050565b61490d836148d8565b614921614919826148fa565b84845461487c565b825550505050565b600090565b614936614929565b614941818484614904565b505050565b5b818110156149655761495a60008261492e565b600181019050614947565b5050565b601f8211156149aa5761497b8161484a565b6149848461485f565b81016020851015614993578190505b6149a761499f8561485f565b830182614946565b50505b505050565b600082821c905092915050565b60006149cd600019846008026149af565b1980831691505092915050565b60006149e683836149bc565b9150826002028217905092915050565b614a00838361483f565b67ffffffffffffffff811115614a1957614a186140fe565b5b614a238254614405565b614a2e828285614969565b6000601f831160018114614a5d5760008415614a4b578287013590505b614a5585826149da565b865550614abd565b601f198416614a6b8661484a565b60005b82811015614a9357848901358255600182019150602085019450602081019050614a6e565b86831015614ab05784890135614aac601f8916826149bc565b8355505b6001600288020188555050505b50505050505050565b7f63616c6c6572206d757374206265206f776e6572000000000000000000000000600082015250565b6000614afc601483613b85565b9150614b0782614ac6565b602082019050919050565b60006020820190508181036000830152614b2b81614aef565b9050919050565b7f616c7265616479207374616b696e670000000000000000000000000000000000600082015250565b6000614b68600f83613b85565b9150614b7382614b32565b602082019050919050565b60006020820190508181036000830152614b9781614b5b565b9050919050565b6000608082019050614bb36000830187613d57565b614bc06020830186613cc1565b614bcd6040830185613d57565b614bda6060830184613d57565b95945050505050565b6000606082019050614bf86000830186613d57565b614c056020830185613cc1565b614c126040830184613d57565b949350505050565b7f216c656e67746800000000000000000000000000000000000000000000000000600082015250565b6000614c50600783613b85565b9150614c5b82614c1a565b602082019050919050565b60006020820190508181036000830152614c7f81614c43565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000614cc082613c2c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614cf257614cf16145e6565b5b600182019050919050565b7f544f4b454e204e4f542045584953540000000000000000000000000000000000600082015250565b6000614d33600f83613b85565b9150614d3e82614cfd565b602082019050919050565b60006020820190508181036000830152614d6281614d26565b9050919050565b600081905092915050565b6000614d7f82613b7a565b614d898185614d69565b9350614d99818560208601613b96565b80840191505092915050565b6000614db2600083614d69565b9150614dbd82614798565b600082019050919050565b6000614dd48284614d74565b9150614ddf82614da5565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614e46602683613b85565b9150614e5182614dea565b604082019050919050565b60006020820190508181036000830152614e7581614e39565b9050919050565b7f455243373231415f5f496e697469616c697a61626c653a20636f6e747261637460008201527f20697320616c726561647920696e697469616c697a6564000000000000000000602082015250565b6000614ed8603783613b85565b9150614ee382614e7c565b604082019050919050565b60006020820190508181036000830152614f0781614ecb565b9050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b6000614f6a602e83613b85565b9150614f7582614f0e565b604082019050919050565b60006020820190508181036000830152614f9981614f5d565b9050919050565b614fa982613b7a565b67ffffffffffffffff811115614fc257614fc16140fe565b5b614fcc8254614405565b614fd7828285614969565b600060209050601f83116001811461500a5760008415614ff8578287015190505b61500285826149da565b86555061506a565b601f1984166150188661484a565b60005b828110156150405784890151825560018201915060208501945060208101905061501b565b8683101561505d5784890151615059601f8916826149bc565b8355505b6001600288020188555050505b505050505050565b6000819050919050565b600060ff82169050919050565b60006150a461509f61509a84615072565b6148ce565b61507c565b9050919050565b6150b481615089565b82525050565b60006020820190506150cf60008301846150ab565b92915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061510b602083613b85565b9150615116826150d5565b602082019050919050565b6000602082019050818103600083015261513a816150fe565b9050919050565b7f546f6b656e206973206c6f636b65640000000000000000000000000000000000600082015250565b6000615177600f83613b85565b915061518282615141565b602082019050919050565b600060208201905081810360008301526151a68161516a565b9050919050565b7f43616e6e6f7420757064617465206d6170000000000000000000000000000000600082015250565b60006151e3601183613b85565b91506151ee826151ad565b602082019050919050565b60006020820190508181036000830152615212816151d6565b9050919050565b7f494420616c7265616479206c6f636b65642062792063616c6c65720000000000600082015250565b600061524f601b83613b85565b915061525a82615219565b602082019050919050565b6000602082019050818103600083015261527e81615242565b9050919050565b7f4944206e6f74206c6f636b65642062792063616c6c6572000000000000000000600082015250565b60006152bb601783613b85565b91506152c682615285565b602082019050919050565b600060208201905081810360008301526152ea816152ae565b9050919050565b60006152fc82613c2c565b91506000820361530f5761530e6145e6565b5b600182039050919050565b7f4944206e6f74206c6f636b656400000000000000000000000000000000000000600082015250565b6000615350600d83613b85565b915061535b8261531a565b602082019050919050565b6000602082019050818103600083015261537f81615343565b9050919050565b60006153928285614d74565b915061539e8284614d74565b91508190509392505050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b6000615406602b83613b85565b9150615411826153aa565b604082019050919050565b60006020820190508181036000830152615435816153f9565b9050919050565b7f455243373231415f5f496e697469616c697a61626c653a20636f6e747261637460008201527f206973206e6f7420696e697469616c697a696e67000000000000000000000000602082015250565b6000615498603483613b85565b91506154a38261543c565b604082019050919050565b600060208201905081810360008301526154c78161548b565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006154f5826154ce565b6154ff81856154d9565b935061550f818560208601613b96565b61551881613bc0565b840191505092915050565b60006080820190506155386000830187613cc1565b6155456020830186613cc1565b6155526040830185613d57565b818103606083015261556481846154ea565b905095945050505050565b60008151905061557e81613aeb565b92915050565b60006020828403121561559a57615599613ab5565b5b60006155a88482850161556f565b9150509291505056fea26469706673582212201bd3efa406850e5fb917562dd0918358d52a9f54b85a6683aa78fd88dbe3268f64736f6c63430008120033
Deployed Bytecode
0x60806040526004361061025c5760003560e01c8063650b00f611610144578063ac52e644116100b6578063d5abeb011161007a578063d5abeb01146108e9578063e58306f914610914578063e985e9c51461093d578063f2fde38b1461097a578063f4a0a528146109a3578063f62d1888146109cc5761025c565b8063ac52e644146107ed578063b1a6505f14610816578063b88d4fde14610853578063c6004ed61461086f578063c87b56dd146108ac5761025c565b80638da5cb5b116101085780638da5cb5b146106f157806394d216d61461071c57806395d89b4114610745578063a0c5407814610770578063a22cb4651461079b578063a694fc3a146107c45761025c565b8063650b00f6146105f85780636817c76c1461063557806370a0823114610660578063715018a61461069d57806372abc8b7146106b45761025c565b80632cba8123116101dd578063453c2310116101a1578063453c2310146104d8578063493770cc1461050357806349a758a31461052c57806355f804b3146105695780635d3eea91146105925780636352211e146105bb5761025c565b80632cba81231461040257806335b504c51461043f5780633ccfd60b1461047c57806340a9c8df1461049357806342842e0e146104bc5761025c565b80631249c58b116102245780631249c58b1461035f57806318160ddd146103695780631f85e3ca1461039457806323b872dd146103bd5780632799cde0146103d95761025c565b806301ffc9a71461026157806306fdde031461029e578063081812fc146102c957806309308e5d14610306578063095ea7b314610343575b600080fd5b34801561026d57600080fd5b5061028860048036038101906102839190613b17565b6109f5565b6040516102959190613b5f565b60405180910390f35b3480156102aa57600080fd5b506102b3610a56565b6040516102c09190613c0a565b60405180910390f35b3480156102d557600080fd5b506102f060048036038101906102eb9190613c62565b610af1565b6040516102fd9190613cd0565b60405180910390f35b34801561031257600080fd5b5061032d60048036038101906103289190613d17565b610b79565b60405161033a9190613d66565b60405180910390f35b61035d60048036038101906103589190613d81565b610b9e565b005b610367610bae565b005b34801561037557600080fd5b5061037e610dd2565b60405161038b9190613d66565b60405180910390f35b3480156103a057600080fd5b506103bb60048036038101906103b69190613ded565b610dfb565b005b6103d760048036038101906103d29190613e1a565b610e20565b005b3480156103e557600080fd5b5061040060048036038101906103fb9190613c62565b610ed5565b005b34801561040e57600080fd5b5061042960048036038101906104249190613e6d565b610f29565b6040516104369190613cd0565b60405180910390f35b34801561044b57600080fd5b5061046660048036038101906104619190613c62565b610f6b565b6040516104739190613d66565b60405180910390f35b34801561048857600080fd5b50610491610f83565b005b34801561049f57600080fd5b506104ba60048036038101906104b59190613c62565b611048565b005b6104d660048036038101906104d19190613e1a565b61109c565b005b3480156104e457600080fd5b506104ed6110bc565b6040516104fa9190613d66565b60405180910390f35b34801561050f57600080fd5b5061052a60048036038101906105259190613ded565b6110c2565b005b34801561053857600080fd5b50610553600480360381019061054e9190613c62565b6110e7565b6040516105609190613cd0565b60405180910390f35b34801561057557600080fd5b50610590600480360381019061058b9190613f12565b61111a565b005b34801561059e57600080fd5b506105b960048036038101906105b49190613c62565b611138565b005b3480156105c757600080fd5b506105e260048036038101906105dd9190613c62565b611276565b6040516105ef9190613cd0565b60405180910390f35b34801561060457600080fd5b5061061f600480360381019061061a9190613c62565b611288565b60405161062c9190613d66565b60405180910390f35b34801561064157600080fd5b5061064a6112a0565b6040516106579190613d66565b60405180910390f35b34801561066c57600080fd5b5061068760048036038101906106829190613f5f565b6112a6565b6040516106949190613d66565b60405180910390f35b3480156106a957600080fd5b506106b2611367565b005b3480156106c057600080fd5b506106db60048036038101906106d69190613c62565b61137b565b6040516106e89190613b5f565b60405180910390f35b3480156106fd57600080fd5b5061070661139a565b6040516107139190613cd0565b60405180910390f35b34801561072857600080fd5b50610743600480360381019061073e9190613d17565b6113c4565b005b34801561075157600080fd5b5061075a61141a565b6040516107679190613c0a565b60405180910390f35b34801561077c57600080fd5b506107856114b5565b6040516107929190613c0a565b60405180910390f35b3480156107a757600080fd5b506107c260048036038101906107bd9190613f8c565b611543565b005b3480156107d057600080fd5b506107eb60048036038101906107e69190613c62565b611657565b005b3480156107f957600080fd5b50610814600480360381019061080f9190614078565b61178c565b005b34801561082257600080fd5b5061083d60048036038101906108389190613f5f565b6118a9565b60405161084a9190613b5f565b60405180910390f35b61086d60048036038101906108689190614229565b6118c9565b005b34801561087b57600080fd5b5061089660048036038101906108919190613f5f565b611980565b6040516108a39190613d66565b60405180910390f35b3480156108b857600080fd5b506108d360048036038101906108ce9190613c62565b611998565b6040516108e09190613c0a565b60405180910390f35b3480156108f557600080fd5b506108fe611a11565b60405161090b9190613d66565b60405180910390f35b34801561092057600080fd5b5061093b60048036038101906109369190613d81565b611a1b565b005b34801561094957600080fd5b50610964600480360381019061095f91906142ac565b611a31565b6040516109719190613b5f565b60405180910390f35b34801561098657600080fd5b506109a1600480360381019061099c9190613f5f565b611ace565b005b3480156109af57600080fd5b506109ca60048036038101906109c59190613c62565b611b51565b005b3480156109d857600080fd5b506109f360048036038101906109ee919061438d565b611b63565b005b600063706e848960e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a4f5750610a4e82611e81565b5b9050919050565b6060610a60611f13565b6002018054610a6e90614405565b80601f0160208091040260200160405190810160405280929190818152602001828054610a9a90614405565b8015610ae75780601f10610abc57610100808354040283529160200191610ae7565b820191906000526020600020905b815481529060010190602001808311610aca57829003601f168201915b5050505050905090565b6000610afc82611f40565b610b32576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b3a611f13565b600601600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6068602052816000526040600020602052806000526040600020600091509150505481565b610baa82826001611fb1565b5050565b606c60019054906101000a900460ff16610bfd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf490614482565b60405180910390fd5b610c05611a11565b610c0d610dd2565b10610c4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c44906144ee565b60405180910390fd5b606b54341015610c92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c899061455a565b60405180910390fd5b606a54606d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410610d15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0c906145c6565b60405180910390fd5b6001606d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610d659190614615565b92505081905550610d77336001612106565b33606e6000610d84610dd2565b815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000610ddc612114565b610de4611f13565b60010154610df0611f13565b600001540303905090565b610e0361211d565b80606c60016101000a81548160ff02191690831515021790555050565b606c60009054906101000a900460ff16610e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6690614695565b60405180910390fd5b6000606f60008381526020019081526020016000205414610ec5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ebc90614701565b60405180910390fd5b610ed083838361219b565b505050565b610ede81611f40565b610f1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f149061476d565b60405180910390fd5b610f26816121f3565b50565b60676020528160005260406000206020528060005260406000206000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606f6020528060005260406000206000915090505481565b610f8b61211d565b6000479050600033905060008173ffffffffffffffffffffffffffffffffffffffff1683604051610fbb906147be565b60006040518083038185875af1925050503d8060008114610ff8576040519150601f19603f3d011682016040523d82523d6000602084013e610ffd565b606091505b50508091505080611043576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103a9061481f565b60405180910390fd5b505050565b61105181611f40565b611090576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110879061476d565b60405180910390fd5b6110998161245f565b50565b6110b7838383604051806020016040528060008152506118c9565b505050565b606a5481565b6110ca61211d565b80606c60006101000a81548160ff02191690831515021790555050565b606e6020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61112261211d565b8181606991826111339291906149f6565b505050565b61114181611276565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146111ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a590614b12565b60405180910390fd5b6000606f60008381526020019081526020016000205414611204576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111fb90614b7e565b60405180910390fd5b6000606f60008381526020019081526020016000205490506000606f6000848152602001908152602001600020819055507fc1e00202ee2c06861d326fc6374026b751863ff64218ccbaa38c3e603a8e72c28233834260405161126a9493929190614b9e565b60405180910390a15050565b60006112818261283a565b9050919050565b60666020528060005260406000206000915090505481565b606b5481565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361130d576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff61131e611f13565b60050160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b61136f61211d565b611379600061294d565b565b6000806066600084815260200190815260200160002054149050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6113cd82611f40565b61140c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114039061476d565b60405180910390fd5b6114168282612a13565b5050565b6060611424611f13565b600301805461143290614405565b80601f016020809104026020016040519081016040528092919081815260200182805461145e90614405565b80156114ab5780601f10611480576101008083540402835291602001916114ab565b820191906000526020600020905b81548152906001019060200180831161148e57829003601f168201915b5050505050905090565b606980546114c290614405565b80601f01602080910402602001604051908101604052809291908181526020018280546114ee90614405565b801561153b5780601f106115105761010080835404028352916020019161153b565b820191906000526020600020905b81548152906001019060200180831161151e57829003601f168201915b505050505081565b8061154c611f13565b6007016000611559612df0565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611606612df0565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161164b9190613b5f565b60405180910390a35050565b61166081611276565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116c490614b12565b60405180910390fd5b6000606f60008381526020019081526020016000205414611723576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161171a90614b7e565b60405180910390fd5b42606f6000838152602001908152602001600020819055507f02567b2553aeb44e4ddd5d68462774dc3de158cb0f2c2da1740e729b22086aff8133606f60008581526020019081526020016000205460405161178193929190614be3565b60405180910390a150565b61179461211d565b8181905084849050146117dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117d390614c66565b60405180910390fd5b60005b848490508110156118a2578282828181106117fd576117fc614c86565b5b90506020020160208101906118129190613ded565b6065600087878581811061182957611828614c86565b5b905060200201602081019061183e9190613f5f565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061189a90614cb5565b9150506117df565b5050505050565b60656020528060005260406000206000915054906101000a900460ff1681565b606c60009054906101000a900460ff16611918576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161190f90614695565b60405180910390fd5b6000606f6000848152602001908152602001600020541461196e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196590614701565b60405180910390fd5b61197a84848484612df8565b50505050565b606d6020528060005260406000206000915090505481565b60606119a382611f40565b6119e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119d990614d49565b60405180910390fd5b6119eb82612e52565b6040516020016119fb9190614dc8565b6040516020818303038152906040529050919050565b6000617530905090565b611a2361211d565b611a2d8282612106565b5050565b6000611a3b611f13565b60070160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611ad661211d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611b45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3c90614e5c565b60405180910390fd5b611b4e8161294d565b50565b611b5961211d565b80606b8190555050565b611b6b612ef0565b60000160019054906101000a900460ff16611b9f57611b88612ef0565b60000160009054906101000a900460ff1615611ba8565b611ba7612f1d565b5b611be7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bde90614eee565b60405180910390fd5b6000611bf1612ef0565b60000160019054906101000a900460ff161590508015611c54576001611c15612ef0565b60000160016101000a81548160ff0219169083151502179055506001611c39612ef0565b60000160006101000a81548160ff0219169083151502179055505b60008060019054906101000a900460ff16159050808015611c855750600160008054906101000a900460ff1660ff16105b80611cb25750611c9430612f34565b158015611cb15750600160008054906101000a900460ff1660ff16145b5b611cf1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce890614f80565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015611d2e576001600060016101000a81548160ff0219169083151502179055505b611da26040518060400160405280601e81526020017f5461746120417661746172206279204a756c69616e277320456469746f7200008152506040518060400160405280600481526020017f5441544100000000000000000000000000000000000000000000000000000000815250612f57565b8260699081611db19190614fa0565b506001606c60006101000a81548160ff0219169083151502179055506000606c60016101000a81548160ff0219169083151502179055506001606a819055506000606b819055508015611e515760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986001604051611e4891906150ba565b60405180910390a15b508015611e7d576000611e62612ef0565b60000160016101000a81548160ff0219169083151502179055505b5050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611edc57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611f0c5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6000807f2569078dfb4b0305704d3008e7403993ae9601b85f7ae5e742de3de8f8011c4090508091505090565b600081611f4b612114565b11158015611f635750611f5c611f13565b6000015482105b8015611faa575060007c0100000000000000000000000000000000000000000000000000000000611f92611f13565b60040160008581526020019081526020016000205416145b9050919050565b6000611fbc83611276565b90508115612047578073ffffffffffffffffffffffffffffffffffffffff16611fe3612df0565b73ffffffffffffffffffffffffffffffffffffffff16146120465761200f8161200a612df0565b611a31565b612045576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b83612050611f13565b600601600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b6121108282612fbc565b5050565b60006001905090565b61212561319c565b73ffffffffffffffffffffffffffffffffffffffff1661214361139a565b73ffffffffffffffffffffffffffffffffffffffff1614612199576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161219090615121565b60405180910390fd5b565b6121a48161137b565b6121e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121da9061518d565b60405180910390fd5b6121ee8383836131a4565b505050565b606560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661227f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612276906151f9565b60405180910390fd5b60006068600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414612312576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161230990615265565b60405180910390fd5b6000600160666000848152602001908152602001600020546123349190614615565b90503360676000848152602001908152602001600020600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806068600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060666000838152602001908152602001600020600081548092919061241290614cb5565b91905055503373ffffffffffffffffffffffffffffffffffffffff16827f9ecfd70e9ff36df72989324a49559383d39f9290d700b10cf5ac10dcb68d264360405160405180910390a35050565b606560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166124eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e2906151f9565b60405180910390fd5b60006068600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008103612583576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161257a906152d1565b60405180910390fd5b60006066600084815260200190815260200160002054905080821461270d57600060676000858152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060676000868152602001908152602001600020600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060676000868152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826068600086815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050612772565b600060676000858152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006068600085815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506066600084815260200190815260200160002060008154809291906127ec906152f1565b91905055503373ffffffffffffffffffffffffffffffffffffffff16837f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3760405160405180910390a3505050565b600081612845612114565b1161291657612852611f13565b600401600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036129155760008103612910576128a0611f13565b6000015482106128dc576040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b6128e5611f13565b60040160008360019003935083815260200190815260200160002054905060008103612948576128dd565b612948565b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b606560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a97906151f9565b60405180910390fd5b60006068600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008103612b38576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b2f90615366565b60405180910390fd5b600060666000858152602001908152602001600020549050808214612cc257600060676000868152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060676000878152602001908152602001600020600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060676000878152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826068600087815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050612d27565b600060676000868152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006068600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550606660008581526020019081526020016000206000815480929190612da1906152f1565b91905055508273ffffffffffffffffffffffffffffffffffffffff16847f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3760405160405180910390a350505050565b600033905090565b612e018261137b565b612e40576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e379061518d565b60405180910390fd5b612e4c848484846134fc565b50505050565b6060612e5d82611f40565b612e93576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612e9d61356f565b90506000815103612ebd5760405180602001604052806000815250612ee8565b80612ec784613601565b604051602001612ed8929190615386565b6040516020818303038152906040525b915050919050565b6000807fee151c8401928dc223602bb187aff91b9a56c7cae5476ef1b3287b085a16c85f90508091505090565b6000803090506000813b9050600081149250505090565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16612fa6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f9d9061541c565b60405180910390fd5b612fb08282613651565b612fb86136b7565b5050565b6000612fc6611f13565b60000154905060008203613006576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6130136000848385613710565b600160406001901b178202613026611f13565b60050160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550613093836130846000866000613716565b61308d8561373e565b1761374e565b61309b611f13565b600401600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461313d57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050613102565b5060008203613178576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80613181611f13565b6000018190555050506131976000848385613779565b505050565b600033905090565b60006131af8261283a565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613216576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806132228461377f565b915091506132388187613233612df0565b6137af565b6132845761324d86613248612df0565b611a31565b613283576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036132ea576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6132f78686866001613710565b801561330257600082555b61330a611f13565b60050160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550613361611f13565b60050160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055506133e2856133be888887613716565b7c02000000000000000000000000000000000000000000000000000000001761374e565b6133ea611f13565b60040160008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084160361348c576000600185019050600061343b611f13565b6004016000838152602001908152602001600020540361348a5761345d611f13565b6000015481146134895783613470611f13565b6004016000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46134f48686866001613779565b505050505050565b613507848484610e20565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461356957613532848484846137f3565b613568576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b60606069805461357e90614405565b80601f01602080910402602001604051908101604052809291908181526020018280546135aa90614405565b80156135f75780601f106135cc576101008083540402835291602001916135f7565b820191906000526020600020905b8154815290600101906020018083116135da57829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b60011561363c57600184039350600a81066030018453600a810490508061361a575b50828103602084039350808452505050919050565b613659612ef0565b60000160019054906101000a900460ff166136a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136a0906154ae565b60405180910390fd5b6136b38282613943565b5050565b600060019054906101000a900460ff16613706576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136fd9061541c565b60405180910390fd5b61370e6139e8565b565b50505050565b60008060e883901c905060e861372d868684613a41565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b600080600061378c611f13565b600601600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613819612df0565b8786866040518563ffffffff1660e01b815260040161383b9493929190615523565b6020604051808303816000875af192505050801561387757506040513d601f19601f820116820180604052508101906138749190615584565b60015b6138f0573d80600081146138a7576040519150601f19603f3d011682016040523d82523d6000602084013e6138ac565b606091505b5060008151036138e8576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b61394b612ef0565b60000160019054906101000a900460ff1661399b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613992906154ae565b60405180910390fd5b816139a4611f13565b60020190816139b39190614fa0565b50806139bd611f13565b60030190816139cc9190614fa0565b506139d5612114565b6139dd611f13565b600001819055505050565b600060019054906101000a900460ff16613a37576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a2e9061541c565b60405180910390fd5b613a3f613a4a565b565b60009392505050565b600060019054906101000a900460ff16613a99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a909061541c565b60405180910390fd5b613aa9613aa461319c565b61294d565b565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613af481613abf565b8114613aff57600080fd5b50565b600081359050613b1181613aeb565b92915050565b600060208284031215613b2d57613b2c613ab5565b5b6000613b3b84828501613b02565b91505092915050565b60008115159050919050565b613b5981613b44565b82525050565b6000602082019050613b746000830184613b50565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613bb4578082015181840152602081019050613b99565b60008484015250505050565b6000601f19601f8301169050919050565b6000613bdc82613b7a565b613be68185613b85565b9350613bf6818560208601613b96565b613bff81613bc0565b840191505092915050565b60006020820190508181036000830152613c248184613bd1565b905092915050565b6000819050919050565b613c3f81613c2c565b8114613c4a57600080fd5b50565b600081359050613c5c81613c36565b92915050565b600060208284031215613c7857613c77613ab5565b5b6000613c8684828501613c4d565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613cba82613c8f565b9050919050565b613cca81613caf565b82525050565b6000602082019050613ce56000830184613cc1565b92915050565b613cf481613caf565b8114613cff57600080fd5b50565b600081359050613d1181613ceb565b92915050565b60008060408385031215613d2e57613d2d613ab5565b5b6000613d3c85828601613c4d565b9250506020613d4d85828601613d02565b9150509250929050565b613d6081613c2c565b82525050565b6000602082019050613d7b6000830184613d57565b92915050565b60008060408385031215613d9857613d97613ab5565b5b6000613da685828601613d02565b9250506020613db785828601613c4d565b9150509250929050565b613dca81613b44565b8114613dd557600080fd5b50565b600081359050613de781613dc1565b92915050565b600060208284031215613e0357613e02613ab5565b5b6000613e1184828501613dd8565b91505092915050565b600080600060608486031215613e3357613e32613ab5565b5b6000613e4186828701613d02565b9350506020613e5286828701613d02565b9250506040613e6386828701613c4d565b9150509250925092565b60008060408385031215613e8457613e83613ab5565b5b6000613e9285828601613c4d565b9250506020613ea385828601613c4d565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f840112613ed257613ed1613ead565b5b8235905067ffffffffffffffff811115613eef57613eee613eb2565b5b602083019150836001820283011115613f0b57613f0a613eb7565b5b9250929050565b60008060208385031215613f2957613f28613ab5565b5b600083013567ffffffffffffffff811115613f4757613f46613aba565b5b613f5385828601613ebc565b92509250509250929050565b600060208284031215613f7557613f74613ab5565b5b6000613f8384828501613d02565b91505092915050565b60008060408385031215613fa357613fa2613ab5565b5b6000613fb185828601613d02565b9250506020613fc285828601613dd8565b9150509250929050565b60008083601f840112613fe257613fe1613ead565b5b8235905067ffffffffffffffff811115613fff57613ffe613eb2565b5b60208301915083602082028301111561401b5761401a613eb7565b5b9250929050565b60008083601f84011261403857614037613ead565b5b8235905067ffffffffffffffff81111561405557614054613eb2565b5b60208301915083602082028301111561407157614070613eb7565b5b9250929050565b6000806000806040858703121561409257614091613ab5565b5b600085013567ffffffffffffffff8111156140b0576140af613aba565b5b6140bc87828801613fcc565b9450945050602085013567ffffffffffffffff8111156140df576140de613aba565b5b6140eb87828801614022565b925092505092959194509250565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61413682613bc0565b810181811067ffffffffffffffff82111715614155576141546140fe565b5b80604052505050565b6000614168613aab565b9050614174828261412d565b919050565b600067ffffffffffffffff821115614194576141936140fe565b5b61419d82613bc0565b9050602081019050919050565b82818337600083830152505050565b60006141cc6141c784614179565b61415e565b9050828152602081018484840111156141e8576141e76140f9565b5b6141f38482856141aa565b509392505050565b600082601f8301126142105761420f613ead565b5b81356142208482602086016141b9565b91505092915050565b6000806000806080858703121561424357614242613ab5565b5b600061425187828801613d02565b945050602061426287828801613d02565b935050604061427387828801613c4d565b925050606085013567ffffffffffffffff81111561429457614293613aba565b5b6142a0878288016141fb565b91505092959194509250565b600080604083850312156142c3576142c2613ab5565b5b60006142d185828601613d02565b92505060206142e285828601613d02565b9150509250929050565b600067ffffffffffffffff821115614307576143066140fe565b5b61431082613bc0565b9050602081019050919050565b600061433061432b846142ec565b61415e565b90508281526020810184848401111561434c5761434b6140f9565b5b6143578482856141aa565b509392505050565b600082601f83011261437457614373613ead565b5b813561438484826020860161431d565b91505092915050565b6000602082840312156143a3576143a2613ab5565b5b600082013567ffffffffffffffff8111156143c1576143c0613aba565b5b6143cd8482850161435f565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061441d57607f821691505b6020821081036144305761442f6143d6565b5b50919050565b7f6d696e74206e6f7420656e61626c656400000000000000000000000000000000600082015250565b600061446c601083613b85565b915061447782614436565b602082019050919050565b6000602082019050818103600083015261449b8161445f565b9050919050565b7f736f6c64206f7574000000000000000000000000000000000000000000000000600082015250565b60006144d8600883613b85565b91506144e3826144a2565b602082019050919050565b60006020820190508181036000830152614507816144cb565b9050919050565b7f696e73756666696369656e742076616c75650000000000000000000000000000600082015250565b6000614544601283613b85565b915061454f8261450e565b602082019050919050565b6000602082019050818103600083015261457381614537565b9050919050565b7f7265616368656420746865206d6178696d756d00000000000000000000000000600082015250565b60006145b0601383613b85565b91506145bb8261457a565b602082019050919050565b600060208201905081810360008301526145df816145a3565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061462082613c2c565b915061462b83613c2c565b9250828201905080821115614643576146426145e6565b5b92915050565b7f7472616e73666572206e6f7420656e61626c6564000000000000000000000000600082015250565b600061467f601483613b85565b915061468a82614649565b602082019050919050565b600060208201905081810360008301526146ae81614672565b9050919050565b7f43616e6e6f74207472616e73666572207374616b656420746f6b656e00000000600082015250565b60006146eb601c83613b85565b91506146f6826146b5565b602082019050919050565b6000602082019050818103600083015261471a816146de565b9050919050565b7f546f6b656e202165786973740000000000000000000000000000000000000000600082015250565b6000614757600c83613b85565b915061476282614721565b602082019050919050565b600060208201905081810360008301526147868161474a565b9050919050565b600081905092915050565b50565b60006147a860008361478d565b91506147b382614798565b600082019050919050565b60006147c98261479b565b9150819050919050565b7f5472616e73616374696f6e20556e7375636365737366756c0000000000000000600082015250565b6000614809601883613b85565b9150614814826147d3565b602082019050919050565b60006020820190508181036000830152614838816147fc565b9050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026148ac7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261486f565b6148b6868361486f565b95508019841693508086168417925050509392505050565b6000819050919050565b60006148f36148ee6148e984613c2c565b6148ce565b613c2c565b9050919050565b6000819050919050565b61490d836148d8565b614921614919826148fa565b84845461487c565b825550505050565b600090565b614936614929565b614941818484614904565b505050565b5b818110156149655761495a60008261492e565b600181019050614947565b5050565b601f8211156149aa5761497b8161484a565b6149848461485f565b81016020851015614993578190505b6149a761499f8561485f565b830182614946565b50505b505050565b600082821c905092915050565b60006149cd600019846008026149af565b1980831691505092915050565b60006149e683836149bc565b9150826002028217905092915050565b614a00838361483f565b67ffffffffffffffff811115614a1957614a186140fe565b5b614a238254614405565b614a2e828285614969565b6000601f831160018114614a5d5760008415614a4b578287013590505b614a5585826149da565b865550614abd565b601f198416614a6b8661484a565b60005b82811015614a9357848901358255600182019150602085019450602081019050614a6e565b86831015614ab05784890135614aac601f8916826149bc565b8355505b6001600288020188555050505b50505050505050565b7f63616c6c6572206d757374206265206f776e6572000000000000000000000000600082015250565b6000614afc601483613b85565b9150614b0782614ac6565b602082019050919050565b60006020820190508181036000830152614b2b81614aef565b9050919050565b7f616c7265616479207374616b696e670000000000000000000000000000000000600082015250565b6000614b68600f83613b85565b9150614b7382614b32565b602082019050919050565b60006020820190508181036000830152614b9781614b5b565b9050919050565b6000608082019050614bb36000830187613d57565b614bc06020830186613cc1565b614bcd6040830185613d57565b614bda6060830184613d57565b95945050505050565b6000606082019050614bf86000830186613d57565b614c056020830185613cc1565b614c126040830184613d57565b949350505050565b7f216c656e67746800000000000000000000000000000000000000000000000000600082015250565b6000614c50600783613b85565b9150614c5b82614c1a565b602082019050919050565b60006020820190508181036000830152614c7f81614c43565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000614cc082613c2c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614cf257614cf16145e6565b5b600182019050919050565b7f544f4b454e204e4f542045584953540000000000000000000000000000000000600082015250565b6000614d33600f83613b85565b9150614d3e82614cfd565b602082019050919050565b60006020820190508181036000830152614d6281614d26565b9050919050565b600081905092915050565b6000614d7f82613b7a565b614d898185614d69565b9350614d99818560208601613b96565b80840191505092915050565b6000614db2600083614d69565b9150614dbd82614798565b600082019050919050565b6000614dd48284614d74565b9150614ddf82614da5565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614e46602683613b85565b9150614e5182614dea565b604082019050919050565b60006020820190508181036000830152614e7581614e39565b9050919050565b7f455243373231415f5f496e697469616c697a61626c653a20636f6e747261637460008201527f20697320616c726561647920696e697469616c697a6564000000000000000000602082015250565b6000614ed8603783613b85565b9150614ee382614e7c565b604082019050919050565b60006020820190508181036000830152614f0781614ecb565b9050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b6000614f6a602e83613b85565b9150614f7582614f0e565b604082019050919050565b60006020820190508181036000830152614f9981614f5d565b9050919050565b614fa982613b7a565b67ffffffffffffffff811115614fc257614fc16140fe565b5b614fcc8254614405565b614fd7828285614969565b600060209050601f83116001811461500a5760008415614ff8578287015190505b61500285826149da565b86555061506a565b601f1984166150188661484a565b60005b828110156150405784890151825560018201915060208501945060208101905061501b565b8683101561505d5784890151615059601f8916826149bc565b8355505b6001600288020188555050505b505050505050565b6000819050919050565b600060ff82169050919050565b60006150a461509f61509a84615072565b6148ce565b61507c565b9050919050565b6150b481615089565b82525050565b60006020820190506150cf60008301846150ab565b92915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061510b602083613b85565b9150615116826150d5565b602082019050919050565b6000602082019050818103600083015261513a816150fe565b9050919050565b7f546f6b656e206973206c6f636b65640000000000000000000000000000000000600082015250565b6000615177600f83613b85565b915061518282615141565b602082019050919050565b600060208201905081810360008301526151a68161516a565b9050919050565b7f43616e6e6f7420757064617465206d6170000000000000000000000000000000600082015250565b60006151e3601183613b85565b91506151ee826151ad565b602082019050919050565b60006020820190508181036000830152615212816151d6565b9050919050565b7f494420616c7265616479206c6f636b65642062792063616c6c65720000000000600082015250565b600061524f601b83613b85565b915061525a82615219565b602082019050919050565b6000602082019050818103600083015261527e81615242565b9050919050565b7f4944206e6f74206c6f636b65642062792063616c6c6572000000000000000000600082015250565b60006152bb601783613b85565b91506152c682615285565b602082019050919050565b600060208201905081810360008301526152ea816152ae565b9050919050565b60006152fc82613c2c565b91506000820361530f5761530e6145e6565b5b600182039050919050565b7f4944206e6f74206c6f636b656400000000000000000000000000000000000000600082015250565b6000615350600d83613b85565b915061535b8261531a565b602082019050919050565b6000602082019050818103600083015261537f81615343565b9050919050565b60006153928285614d74565b915061539e8284614d74565b91508190509392505050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b6000615406602b83613b85565b9150615411826153aa565b604082019050919050565b60006020820190508181036000830152615435816153f9565b9050919050565b7f455243373231415f5f496e697469616c697a61626c653a20636f6e747261637460008201527f206973206e6f7420696e697469616c697a696e67000000000000000000000000602082015250565b6000615498603483613b85565b91506154a38261543c565b604082019050919050565b600060208201905081810360008301526154c78161548b565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006154f5826154ce565b6154ff81856154d9565b935061550f818560208601613b96565b61551881613bc0565b840191505092915050565b60006080820190506155386000830187613cc1565b6155456020830186613cc1565b6155526040830185613d57565b818103606083015261556481846154ea565b905095945050505050565b60008151905061557e81613aeb565b92915050565b60006020828403121561559a57615599613ab5565b5b60006155a88482850161556f565b9150509291505056fea26469706673582212201bd3efa406850e5fb917562dd0918358d52a9f54b85a6683aa78fd88dbe3268f64736f6c63430008120033
Deployed Bytecode Sourcemap
135129:4559:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85886:292;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50385:124;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56977:242;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22900:94;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56694:124;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;136198:420;;;:::i;:::-;;45870:371;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;137652:103;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;138611:367;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;86816:134;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;22822:71;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135419:53;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;139405:278;;;;;;;;;;;;;:::i;:::-;;86958:138;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;63840:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;135195:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;137763:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;135366:46;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;137361:108;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;138223:380;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51826:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22762:53;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135229:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47150:257;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21423:103;;;;;;;;;;;;;:::i;:::-;;23342:114;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;20782:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87104:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;50585:128;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135165:23;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57559:258;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;137892:323;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;23464;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;22698:57;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;138986:411;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;135316:43;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;137106:247;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;136741:81;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;136071:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57974:188;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21681:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;137550:94;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;135741:322;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;85886:292;86037:4;85629:10;86095:21;;86079:37;;;:12;:37;;;;:91;;;;86133:37;86157:12;86133:23;:37::i;:::-;86079:91;86059:111;;85886:292;;;:::o;50385:124::-;50439:13;50472:23;:21;:23::i;:::-;:29;;50465:36;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50385:124;:::o;56977:242::-;57053:7;57078:16;57086:7;57078;:16::i;:::-;57073:64;;57103:34;;;;;;;;;;;;;;57073:64;57157:23;:21;:23::i;:::-;:39;;:48;57197:7;57157:48;;;;;;;;;;;:54;;;;;;;;;;;;57150:61;;56977:242;;;:::o;22900:94::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;56694:124::-;56783:27;56792:2;56796:7;56805:4;56783:8;:27::i;:::-;56694:124;;:::o;136198:420::-;136248:10;;;;;;;;;;;136240:39;;;;;;;;;;;;:::i;:::-;;;;;;;;;136314:11;:9;:11::i;:::-;136298:13;:11;:13::i;:::-;:27;136290:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;136370:9;;136357;:22;;136349:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;136444:12;;136421:8;:20;136430:10;136421:20;;;;;;;;;;;;;;;;:35;136413:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;136525:1;136501:8;:20;136510:10;136501:20;;;;;;;;;;;;;;;;:25;;;;;;;:::i;:::-;;;;;;;;136537:23;136546:10;136558:1;136537:8;:23::i;:::-;136600:10;136571:11;:26;136583:13;:11;:13::i;:::-;136571:26;;;;;;;;;;;;:39;;;;;;;;;;;;;;;;;;136198:420::o;45870:371::-;45931:7;46207:15;:13;:15::i;:::-;46168:23;:21;:23::i;:::-;:36;;;46128:23;:21;:23::i;:::-;:37;;;:76;:94;46121:101;;45870:371;:::o;137652:103::-;20668:13;:11;:13::i;:::-;137736:11:::1;137723:10;;:24;;;;;;;;;;;;;;;;;;137652:103:::0;:::o;138611:367::-;138762:14;;;;;;;;;;;138754:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;138865:1;138834:18;:27;138853:7;138834:27;;;;;;;;;;;;:32;138812:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;138933:37;138952:4;138958:2;138962:7;138933:18;:37::i;:::-;138611:367;;;:::o;86816:134::-;86890:12;86898:3;86890:7;:12::i;:::-;86882:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;86930:12;86938:3;86930:7;:12::i;:::-;86816:134;:::o;22822:71::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;135419:53::-;;;;;;;;;;;;;;;;;:::o;139405:278::-;20668:13;:11;:13::i;:::-;139453:18:::1;139474:21;139453:42;;139508:9;139528:10;139508:31;;139552:12;139591:1;:6;;139605:10;139591:29;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;139577:43;;;;;139639:7;139631:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;139442:241;;;139405:278::o:0;86958:138::-;87034:12;87042:3;87034:7;:12::i;:::-;87026:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;87074:14;87084:3;87074:9;:14::i;:::-;86958:138;:::o;63840:193::-;63986:39;64003:4;64009:2;64013:7;63986:39;;;;;;;;;;;;:16;:39::i;:::-;63840:193;;;:::o;135195:27::-;;;;:::o;137763:119::-;20668:13;:11;:13::i;:::-;137859:15:::1;137842:14;;:32;;;;;;;;;;;;;;;;;;137763:119:::0;:::o;135366:46::-;;;;;;;;;;;;;;;;;;;;;;:::o;137361:108::-;20668:13;:11;:13::i;:::-;137451:10:::1;;137439:9;:22;;;;;;;:::i;:::-;;137361:108:::0;;:::o;138223:380::-;138299:16;138307:7;138299;:16::i;:::-;138285:30;;:10;:30;;;138277:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;138390:1;138359:18;:27;138378:7;138359:27;;;;;;;;;;;;:32;138351:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;138424:22;138449:18;:27;138468:7;138449:27;;;;;;;;;;;;138424:52;;138517:1;138487:18;:27;138506:7;138487:27;;;;;;;;;;;:31;;;;138534:61;138542:7;138551:10;138563:14;138579:15;138534:61;;;;;;;;;:::i;:::-;;;;;;;;138266:337;138223:380;:::o;51826:152::-;51898:7;51941:27;51960:7;51941:18;:27::i;:::-;51918:52;;51826:152;;;:::o;22762:53::-;;;;;;;;;;;;;;;;;:::o;135229:24::-;;;;:::o;47150:257::-;47222:7;47263:1;47246:19;;:5;:19;;;47242:60;;47274:28;;;;;;;;;;;;;;47242:60;42298:13;47320:23;:21;:23::i;:::-;:42;;:49;47363:5;47320:49;;;;;;;;;;;;;;;;:79;47313:86;;47150:257;;;:::o;21423:103::-;20668:13;:11;:13::i;:::-;21488:30:::1;21515:1;21488:18;:30::i;:::-;21423:103::o:0;23342:114::-;23405:4;23447:1;23429:9;:14;23439:3;23429:14;;;;;;;;;;;;:19;23422:26;;23342:114;;;:::o;20782:87::-;20828:7;20855:6;;;;;;;;;;;20848:13;;20782:87;:::o;87104:164::-;87197:12;87205:3;87197:7;:12::i;:::-;87189:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;87237:23;87245:3;87250:9;87237:7;:23::i;:::-;87104:164;;:::o;50585:128::-;50641:13;50674:23;:21;:23::i;:::-;:31;;50667:38;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50585:128;:::o;135165:23::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;57559:258::-;57730:8;57654:23;:21;:23::i;:::-;:42;;:63;57697:19;:17;:19::i;:::-;57654:63;;;;;;;;;;;;;;;:73;57718:8;57654:73;;;;;;;;;;;;;;;;:84;;;;;;;;;;;;;;;;;;57790:8;57754:55;;57769:19;:17;:19::i;:::-;57754:55;;;57800:8;57754:55;;;;;;:::i;:::-;;;;;;;;57559:258;;:::o;137892:323::-;137966:16;137974:7;137966;:16::i;:::-;137952:30;;:10;:30;;;137944:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;138057:1;138026:18;:27;138045:7;138026:27;;;;;;;;;;;;:32;138018:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;138121:15;138091:18;:27;138110:7;138091:27;;;;;;;;;;;:45;;;;138152:55;138158:7;138167:10;138179:18;:27;138198:7;138179:27;;;;;;;;;;;;138152:55;;;;;;;;:::i;:::-;;;;;;;;137892:323;:::o;23464:::-;20668:13;:11;:13::i;:::-;23637:7:::1;;:14;;23616:10;;:17;;:35;23608:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;23679:9;23674:105;23698:10;;:17;;23694:1;:21;23674:105;;;23769:7;;23777:1;23769:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;23735:16;:31;23752:10;;23763:1;23752:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;23735:31;;;;;;;;;;;;;;;;:44;;;;;;;;;;;;;;;;;;23717:3;;;;;:::i;:::-;;;;23674:105;;;;23464:323:::0;;;;:::o;22698:57::-;;;;;;;;;;;;;;;;;;;;;;:::o;138986:411::-;139170:14;;;;;;;;;;;139162:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;139273:1;139242:18;:27;139261:7;139242:27;;;;;;;;;;;;:32;139220:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;139341:48;139364:4;139370:2;139374:7;139383:5;139341:22;:48::i;:::-;138986:411;;;;:::o;135316:43::-;;;;;;;;;;;;;;;;;:::o;137106:247::-;137208:13;137247:17;137255:8;137247:7;:17::i;:::-;137239:45;;;;;;;;;;;;:::i;:::-;;;;;;;;;137316:24;137331:8;137316:14;:24::i;:::-;137302:43;;;;;;;;:::i;:::-;;;;;;;;;;;;;137295:50;;137106:247;;;:::o;136741:81::-;136782:7;136809:5;136802:12;;136741:81;:::o;136071:119::-;20668:13;:11;:13::i;:::-;136154:28:::1;136163:8;136173;136154;:28::i;:::-;136071:119:::0;;:::o;57974:188::-;58071:4;58095:23;:21;:23::i;:::-;:42;;:49;58138:5;58095:49;;;;;;;;;;;;;;;:59;58145:8;58095:59;;;;;;;;;;;;;;;;;;;;;;;;;58088:66;;57974:188;;;;:::o;21681:201::-;20668:13;:11;:13::i;:::-;21790:1:::1;21770:22;;:8;:22;;::::0;21762:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;21846:28;21865:8;21846:18;:28::i;:::-;21681:201:::0;:::o;137550:94::-;20668:13;:11;:13::i;:::-;137630:6:::1;137618:9;:18;;;;137550:94:::0;:::o;135741:322::-;28086:38;:36;:38::i;:::-;:52;;;;;;;;;;;;:160;;28195:38;:36;:38::i;:::-;:51;;;;;;;;;;;;28194:52;28086:160;;;28158:16;:14;:16::i;:::-;28086:160;28064:265;;;;;;;;;;;;:::i;:::-;;;;;;;;;28342:19;28365:38;:36;:38::i;:::-;:52;;;;;;;;;;;;28364:53;28342:75;;28432:14;28428:179;;;28518:4;28463:38;:36;:38::i;:::-;:52;;;:59;;;;;;;;;;;;;;;;;;28591:4;28537:38;:36;:38::i;:::-;:51;;;:58;;;;;;;;;;;;;;;;;;28428:179;14498:19:::1;14521:13:::0;::::1;;;;;;;;;;14520:14;14498:36;;14568:14;:34;;;;;14601:1;14586:12;::::0;::::1;;;;;;;;:16;;;14568:34;14567:108;;;;14609:44;14647:4;14609:29;:44::i;:::-;14608:45;:66;;;;;14673:1;14657:12;::::0;::::1;;;;;;;;:17;;;14608:66;14567:108;14545:204;;;;;;;;;;;;:::i;:::-;;;;;;;;;14775:1;14760:12;::::0;:16:::1;;;;;;;;;;;;;;;;;;14791:14;14787:67;;;14838:4;14822:13;;:20;;;;;;;;;;;;;;;;;;14787:67;135852:56:::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;::::0;:14:::2;:56::i;:::-;135933:10;135921:9;:22;;;;;;:::i;:::-;;135971:4;135954:14;;:21;;;;;;;;;;;;;;;;;;135999:5;135986:10;;:18;;;;;;;;;;;;;;;;;;136030:1;136015:12;:16;;;;136054:1;136042:9;:13;;;;14880:14:::1;14876:102;;;14927:5;14911:13:::0;::::1;:21;;;;;;;;;;;;;;;;;;14952:14;14964:1;14952:14;;;;;;:::i;:::-;;;;;;;;14876:102;14487:498;28637:14:::0;28633:107;;;28723:5;28668:38;:36;:38::i;:::-;:52;;;:60;;;;;;;;;;;;;;;;;;28633:107;27779:968;135741:322;:::o;49483:639::-;49568:4;49907:10;49892:25;;:11;:25;;;;:102;;;;49984:10;49969:25;;:11;:25;;;;49892:102;:179;;;;50061:10;50046:25;;:11;:25;;;;49892:179;49872:199;;49483:639;;;:::o;31704:164::-;31745:16;31774:12;31649:46;31774:27;;31846:4;31836:14;;31821:40;31704:164;:::o;58420:330::-;58485:4;58541:7;58522:15;:13;:15::i;:::-;:26;;:90;;;;;58575:23;:21;:23::i;:::-;:37;;;58565:7;:47;58522:90;:201;;;;;58722:1;43074:8;58650:23;:21;:23::i;:::-;:41;;:50;58692:7;58650:50;;;;;;;;;;;;:68;:73;58522:201;58502:221;;58420:330;;;:::o;75969:516::-;76098:13;76114:16;76122:7;76114;:16::i;:::-;76098:32;;76147:13;76143:219;;;76202:5;76179:28;;:19;:17;:19::i;:::-;:28;;;76175:187;;76231:44;76248:5;76255:19;:17;:19::i;:::-;76231:16;:44::i;:::-;76226:136;;76307:35;;;;;;;;;;;;;;76226:136;76175:187;76143:219;76431:2;76374:23;:21;:23::i;:::-;:39;;:48;76414:7;76374:48;;;;;;;;;;;:54;;;:59;;;;;;;;;;;;;;;;;;76469:7;76465:2;76449:28;;76458:5;76449:28;;;;;;;;;;;;76087:398;75969:516;;;:::o;136626:107::-;136700:25;136706:8;136716;136700:5;:25::i;:::-;136626:107;;:::o;136879:101::-;136944:7;136971:1;136964:8;;136879:101;:::o;20947:132::-;21022:12;:10;:12::i;:::-;21011:23;;:7;:5;:7::i;:::-;:23;;;21003:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;20947:132::o;86186:285::-;86359:20;86370:8;86359:10;:20::i;:::-;86351:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;86410:53;86442:5;86449:3;86454:8;86410:31;:53::i;:::-;86186:285;;;:::o;23795:447::-;23853:16;:28;23870:10;23853:28;;;;;;;;;;;;;;;;;;;;;;;;;23845:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;23969:1;23936:12;:17;23949:3;23936:17;;;;;;;;;;;:29;23954:10;23936:29;;;;;;;;;;;;;;;;:34;23914:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;24038:13;24071:1;24054:9;:14;24064:3;24054:14;;;;;;;;;;;;:18;;;;:::i;:::-;24038:34;;24105:10;24083:7;:12;24091:3;24083:12;;;;;;;;;;;:19;24096:5;24083:19;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;24158:5;24126:12;:17;24139:3;24126:17;;;;;;;;;;;:29;24144:10;24126:29;;;;;;;;;;;;;;;:37;;;;24174:9;:14;24184:3;24174:14;;;;;;;;;;;;:16;;;;;;;;;:::i;:::-;;;;;;24223:10;24206:28;;24218:3;24206:28;;;;;;;;;;23834:408;23795:447;:::o;24250:675::-;24310:16;:28;24327:10;24310:28;;;;;;;;;;;;;;;;;;;;;;;;;24302:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;24371:13;24387:12;:17;24400:3;24387:17;;;;;;;;;;;:29;24405:10;24387:29;;;;;;;;;;;;;;;;24371:45;;24444:1;24435:5;:10;24427:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;24486:12;24501:9;:14;24511:3;24501:14;;;;;;;;;;;;24486:29;;24539:4;24530:5;:13;24526:274;;24560:20;24583:7;:12;24591:3;24583:12;;;;;;;;;;;:18;24596:4;24583:18;;;;;;;;;;;;;;;;;;;;;24560:41;;24638:12;24616:7;:12;24624:3;24616:12;;;;;;;;;;;:19;24629:5;24616:19;;;;;;;;;;;;:34;;;;;;;;;;;;;;;;;;24694:1;24665:7;:12;24673:3;24665:12;;;;;;;;;;;:18;24678:4;24665:18;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;24745:5;24711:12;:17;24724:3;24711:17;;;;;;;;;;;:31;24729:12;24711:31;;;;;;;;;;;;;;;:39;;;;24545:217;24526:274;;;24798:1;24768:7;:12;24776:3;24768:12;;;;;;;;;;;:19;24781:5;24768:19;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;24526:274;24843:1;24811:12;:17;24824:3;24811:17;;;;;;;;;;;:29;24829:10;24811:29;;;;;;;;;;;;;;;:33;;;;24855:9;:14;24865:3;24855:14;;;;;;;;;;;;:16;;;;;;;;;:::i;:::-;;;;;;24906:10;24887:30;;24901:3;24887:30;;;;;;;;;;24291:634;;24250:675;:::o;53053:1784::-;53120:14;53170:7;53151:15;:13;:15::i;:::-;:26;53147:1634;;53203:23;:21;:23::i;:::-;:41;;:50;53245:7;53203:50;;;;;;;;;;;;53194:59;;53331:1;43074:8;53303:6;:24;:29;53299:1471;;53452:1;53442:6;:11;53438:1029;;53493:23;:21;:23::i;:::-;:37;;;53482:7;:48;53478:92;;53539:31;;;;;;;;;;;;;;53478:92;54167:281;54253:23;:21;:23::i;:::-;:41;;:52;54295:9;;;;;;;54253:52;;;;;;;;;;;;54244:61;;54373:1;54363:6;:11;54411:13;54359:25;54167:281;;53438:1029;54741:13;;53299:1471;53147:1634;54798:31;;;;;;;;;;;;;;53053:1784;;;;:::o;22042:191::-;22116:16;22135:6;;;;;;;;;;;22116:25;;22161:8;22152:6;;:17;;;;;;;;;;;;;;;;;;22216:8;22185:40;;22206:8;22185:40;;;;;;;;;;;;22105:128;22042:191;:::o;24933:679::-;25011:16;:27;25028:9;25011:27;;;;;;;;;;;;;;;;;;;;;;;;;25010:28;25002:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;25071:13;25087:12;:17;25100:3;25087:17;;;;;;;;;;;:28;25105:9;25087:28;;;;;;;;;;;;;;;;25071:44;;25143:1;25134:5;:10;25126:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;25175:12;25190:9;:14;25200:3;25190:14;;;;;;;;;;;;25175:29;;25228:4;25219:5;:13;25215:274;;25249:20;25272:7;:12;25280:3;25272:12;;;;;;;;;;;:18;25285:4;25272:18;;;;;;;;;;;;;;;;;;;;;25249:41;;25327:12;25305:7;:12;25313:3;25305:12;;;;;;;;;;;:19;25318:5;25305:19;;;;;;;;;;;;:34;;;;;;;;;;;;;;;;;;25383:1;25354:7;:12;25362:3;25354:12;;;;;;;;;;;:18;25367:4;25354:18;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;25434:5;25400:12;:17;25413:3;25400:17;;;;;;;;;;;:31;25418:12;25400:31;;;;;;;;;;;;;;;:39;;;;25234:217;25215:274;;;25487:1;25457:7;:12;25465:3;25457:12;;;;;;;;;;;:19;25470:5;25457:19;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;25215:274;25531:1;25500:12;:17;25513:3;25500:17;;;;;;;;;;;:28;25518:9;25500:28;;;;;;;;;;;;;;;:32;;;;25543:9;:14;25553:3;25543:14;;;;;;;;;;;;:16;;;;;;;;;:::i;:::-;;;;;;25594:9;25575:29;;25589:3;25575:29;;;;;;;;;;24991:621;;24933:679;;:::o;82733:105::-;82793:7;82820:10;82813:17;;82733:105;:::o;86479:329::-;86685:20;86696:8;86685:10;:20::i;:::-;86677:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;86736:64;86772:5;86779:3;86784:8;86794:5;86736:35;:64::i;:::-;86479:329;;;;:::o;50819:318::-;50892:13;50923:16;50931:7;50923;:16::i;:::-;50918:59;;50948:29;;;;;;;;;;;;;;50918:59;50990:21;51014:10;:8;:10::i;:::-;50990:34;;51067:1;51048:7;51042:21;:26;:87;;;;;;;;;;;;;;;;;51095:7;51104:18;51114:7;51104:9;:18::i;:::-;51078:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;51042:87;51035:94;;;50819:318;;;:::o;26274:164::-;26315:16;26344:12;26207:58;26344:27;;26416:4;26406:14;;26391:40;26274:164;:::o;29255:569::-;29303:4;29674:12;29697:4;29674:28;;29713:10;29776:4;29764:17;29758:23;;29815:1;29809:2;:7;29802:14;;;;29255:569;:::o;2975:326::-;3035:4;3292:1;3270:7;:19;;;:23;3263:30;;2975:326;;;:::o;85648:230::-;16641:13;;;;;;;;;;;16633:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;85776:49:::1;85810:5;85817:7;85776:33;:49::i;:::-;85836:34;:32;:34::i;:::-;85648:230:::0;;:::o;68320:3062::-;68393:20;68416:23;:21;:23::i;:::-;:37;;;68393:60;;68480:1;68468:8;:13;68464:44;;68490:18;;;;;;;;;;;;;;68464:44;68521:61;68551:1;68555:2;68559:12;68573:8;68521:21;:61::i;:::-;69089:1;42436:2;69059:1;:26;;69058:32;69046:8;:45;68996:23;:21;:23::i;:::-;:42;;:46;69039:2;68996:46;;;;;;;;;;;;;;;;:95;;;;;;;;;;;69392:139;69429:2;69483:33;69506:1;69510:2;69514:1;69483:14;:33::i;:::-;69450:30;69471:8;69450:20;:30::i;:::-;:66;69392:18;:139::i;:::-;69334:23;:21;:23::i;:::-;:41;;:55;69376:12;69334:55;;;;;;;;;;;:197;;;;69548:16;69579:11;69608:8;69593:12;:23;69579:37;;70129:16;70125:2;70121:25;70109:37;;70501:12;70461:8;70420:1;70358:25;70299:1;70238;70211:335;70872:1;70858:12;70854:20;70812:346;70913:3;70904:7;70901:16;70812:346;;71131:7;71121:8;71118:1;71091:25;71088:1;71085;71080:59;70966:1;70957:7;70953:15;70942:26;;70812:346;;;70816:77;71203:1;71191:8;:13;71187:45;;71213:19;;;;;;;;;;;;;;71187:45;71289:3;71249:23;:21;:23::i;:::-;:37;;:43;;;;68770:2534;;71314:60;71343:1;71347:2;71351:12;71365:8;71314:20;:60::i;:::-;68382:3000;68320:3062;;:::o;18820:98::-;18873:7;18900:10;18893:17;;18820:98;:::o;60775:2969::-;60917:27;60947;60966:7;60947:18;:27::i;:::-;60917:57;;61032:4;60991:45;;61007:19;60991:45;;;60987:86;;61045:28;;;;;;;;;;;;;;60987:86;61087:27;61116:23;61143:35;61170:7;61143:26;:35::i;:::-;61086:92;;;;61278:68;61303:15;61320:4;61326:19;:17;:19::i;:::-;61278:24;:68::i;:::-;61273:180;;61366:43;61383:4;61389:19;:17;:19::i;:::-;61366:16;:43::i;:::-;61361:92;;61418:35;;;;;;;;;;;;;;61361:92;61273:180;61484:1;61470:16;;:2;:16;;;61466:52;;61495:23;;;;;;;;;;;;;;61466:52;61531:43;61553:4;61559:2;61563:7;61572:1;61531:21;:43::i;:::-;61667:15;61664:160;;;61807:1;61786:19;61779:30;61664:160;62204:23;:21;:23::i;:::-;:42;;:48;62247:4;62204:48;;;;;;;;;;;;;;;;62202:50;;;;;;;;;;;;62297:23;:21;:23::i;:::-;:42;;:46;62340:2;62297:46;;;;;;;;;;;;;;;;62295:48;;;;;;;;;;;62667:146;62704:2;62753:45;62768:4;62774:2;62778:19;62753:14;:45::i;:::-;43354:8;62725:73;62667:18;:146::i;:::-;62614:23;:21;:23::i;:::-;:41;;:50;62656:7;62614:50;;;;;;;;;;;:199;;;;62984:1;43354:8;62933:19;:47;:52;62929:699;;63006:19;63038:1;63028:7;:11;63006:33;;63219:1;63161:23;:21;:23::i;:::-;:41;;:54;63203:11;63161:54;;;;;;;;;;;;:59;63157:456;;63323:23;:21;:23::i;:::-;:37;;;63308:11;:52;63304:290;;63551:19;63494:23;:21;:23::i;:::-;:41;;:54;63536:11;63494:54;;;;;;;;;;;:76;;;;63304:290;63157:456;62987:641;62929:699;63675:7;63671:2;63656:27;;63665:4;63656:27;;;;;;;;;;;;63694:42;63715:4;63721:2;63725:7;63734:1;63694:20;:42::i;:::-;60906:2838;;;60775:2969;;;:::o;64631:407::-;64806:31;64819:4;64825:2;64829:7;64806:12;:31::i;:::-;64870:1;64852:2;:14;;;:19;64848:183;;64891:56;64922:4;64928:2;64932:7;64941:5;64891:30;:56::i;:::-;64886:145;;64975:40;;;;;;;;;;;;;;64886:145;64848:183;64631:407;;;;:::o;136988:110::-;137048:13;137081:9;137074:16;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;136988:110;:::o;82940:1745::-;83005:17;83439:4;83432;83426:11;83422:22;83531:1;83525:4;83518:15;83606:4;83603:1;83599:12;83592:19;;83688:1;83683:3;83676:14;83792:3;84031:5;84013:428;84039:1;84013:428;;;84079:1;84074:3;84070:11;84063:18;;84250:2;84244:4;84240:13;84236:2;84232:22;84227:3;84219:36;84344:2;84338:4;84334:13;84326:21;;84411:4;84013:428;84401:25;84013:428;84017:21;84480:3;84475;84471:13;84595:4;84590:3;84586:14;84579:21;;84660:6;84655:3;84648:19;83044:1634;;;82940:1745;;;:::o;44573:160::-;29010:38;:36;:38::i;:::-;:52;;;;;;;;;;;;28988:154;;;;;;;;;;;;:::i;:::-;;;;;;;;;44685:40:::1;44710:5;44717:7;44685:24;:40::i;:::-;44573:160:::0;;:::o;23223:111::-;16641:13;;;;;;;;;;;16633:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;23291:35:::1;:33;:35::i;:::-;23223:111::o:0;65700:159::-;;;;;:::o;82042:311::-;82177:7;82197:16;43478:3;82223:19;:41;;82197:68;;43478:3;82291:31;82302:4;82308:2;82312:9;82291:10;:31::i;:::-;82283:40;;:62;;82276:69;;;82042:311;;;;;:::o;55937:324::-;56007:14;56240:1;56230:8;56227:15;56201:24;56197:46;56187:56;;55937:324;;;:::o;55385:450::-;55465:14;55633:16;55626:5;55622:28;55613:37;;55810:5;55796:11;55771:23;55767:41;55764:52;55757:5;55754:63;55744:73;;55385:450;;;;:::o;66524:158::-;;;;;:::o;59631:524::-;59733:27;59762:23;59803:53;59859:23;:21;:23::i;:::-;:39;;:48;59899:7;59859:48;;;;;;;;;;;59803:104;;60060:18;60037:41;;60117:19;60111:26;60092:45;;60022:126;59631:524;;;:::o;58859:659::-;59008:11;59173:16;59166:5;59162:28;59153:37;;59333:16;59322:9;59318:32;59305:45;;59483:15;59472:9;59469:30;59461:5;59450:9;59447:20;59444:56;59434:66;;58859:659;;;;;:::o;67122:736::-;67285:4;67355:2;67319:56;;;67376:19;:17;:19::i;:::-;67397:4;67403:7;67412:5;67319:99;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;67302:549;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67626:1;67609:6;:13;:18;67605:235;;67655:40;;;;;;;;;;;;;;67605:235;67798:6;67792:13;67783:6;67779:2;67775:15;67768:38;67302:549;67484:65;;;67474:75;;;:6;:75;;;;67467:82;;;67122:736;;;;;;:::o;44741:285::-;29010:38;:36;:38::i;:::-;:52;;;;;;;;;;;;28988:154;;;;;;;;;;;;:::i;:::-;;;;;;;;;44895:5:::1;44863:23;:21;:23::i;:::-;:29;;:37;;;;;;:::i;:::-;;44945:7;44911:23;:21;:23::i;:::-;:31;;:41;;;;;;:::i;:::-;;45003:15;:13;:15::i;:::-;44963:23;:21;:23::i;:::-;:37;;:55;;;;44741:285:::0;;:::o;20325:97::-;16641:13;;;;;;;;;;;16633:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;20388:26:::1;:24;:26::i;:::-;20325:97::o:0;81743:147::-;81880:6;81743:147;;;;;:::o;20430:113::-;16641:13;;;;;;;;;;;16633:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;20503:32:::1;20522:12;:10;:12::i;:::-;20503:18;:32::i;:::-;20430: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:178::-;22724:30;22720:1;22712:6;22708:14;22701:54;22584:178;:::o;22768:366::-;22910:3;22931:67;22995:2;22990:3;22931:67;:::i;:::-;22924:74;;23007:93;23096:3;23007:93;:::i;:::-;23125:2;23120:3;23116:12;23109:19;;22768:366;;;:::o;23140:419::-;23306:4;23344:2;23333:9;23329:18;23321:26;;23393:9;23387:4;23383:20;23379:1;23368:9;23364:17;23357:47;23421:131;23547:4;23421:131;:::i;:::-;23413:139;;23140:419;;;:::o;23565:162::-;23705:14;23701:1;23693:6;23689:14;23682:38;23565:162;:::o;23733:366::-;23875:3;23896:67;23960:2;23955:3;23896:67;:::i;:::-;23889:74;;23972:93;24061:3;23972:93;:::i;:::-;24090:2;24085:3;24081:12;24074:19;;23733:366;;;:::o;24105:419::-;24271:4;24309:2;24298:9;24294:18;24286:26;;24358:9;24352:4;24348:20;24344:1;24333:9;24329:17;24322:47;24386:131;24512:4;24386:131;:::i;:::-;24378:139;;24105:419;;;:::o;24530:147::-;24631:11;24668:3;24653:18;;24530:147;;;;:::o;24683:114::-;;:::o;24803:398::-;24962:3;24983:83;25064:1;25059:3;24983:83;:::i;:::-;24976:90;;25075:93;25164:3;25075:93;:::i;:::-;25193:1;25188:3;25184:11;25177:18;;24803:398;;;:::o;25207:379::-;25391:3;25413:147;25556:3;25413:147;:::i;:::-;25406:154;;25577:3;25570:10;;25207:379;;;:::o;25592:174::-;25732:26;25728:1;25720:6;25716:14;25709:50;25592:174;:::o;25772:366::-;25914:3;25935:67;25999:2;25994:3;25935:67;:::i;:::-;25928:74;;26011:93;26100:3;26011:93;:::i;:::-;26129:2;26124:3;26120:12;26113:19;;25772:366;;;:::o;26144:419::-;26310:4;26348:2;26337:9;26333:18;26325:26;;26397:9;26391:4;26387:20;26383:1;26372:9;26368:17;26361:47;26425:131;26551:4;26425:131;:::i;:::-;26417:139;;26144:419;;;:::o;26569:97::-;26628:6;26656:3;26646:13;;26569:97;;;;:::o;26672:141::-;26721:4;26744:3;26736:11;;26767:3;26764:1;26757:14;26801:4;26798:1;26788:18;26780:26;;26672:141;;;:::o;26819:93::-;26856:6;26903:2;26898;26891:5;26887:14;26883:23;26873:33;;26819:93;;;:::o;26918:107::-;26962:8;27012:5;27006:4;27002:16;26981:37;;26918:107;;;;:::o;27031:393::-;27100:6;27150:1;27138:10;27134:18;27173:97;27203:66;27192:9;27173:97;:::i;:::-;27291:39;27321:8;27310:9;27291:39;:::i;:::-;27279:51;;27363:4;27359:9;27352:5;27348:21;27339:30;;27412:4;27402:8;27398:19;27391:5;27388:30;27378:40;;27107:317;;27031:393;;;;;:::o;27430:60::-;27458:3;27479:5;27472:12;;27430:60;;;:::o;27496:142::-;27546:9;27579:53;27597:34;27606:24;27624:5;27606:24;:::i;:::-;27597:34;:::i;:::-;27579:53;:::i;:::-;27566:66;;27496:142;;;:::o;27644:75::-;27687:3;27708:5;27701:12;;27644:75;;;:::o;27725:269::-;27835:39;27866:7;27835:39;:::i;:::-;27896:91;27945:41;27969:16;27945:41;:::i;:::-;27937:6;27930:4;27924:11;27896:91;:::i;:::-;27890:4;27883:105;27801:193;27725:269;;;:::o;28000:73::-;28045:3;28000:73;:::o;28079:189::-;28156:32;;:::i;:::-;28197:65;28255:6;28247;28241:4;28197:65;:::i;:::-;28132:136;28079:189;;:::o;28274:186::-;28334:120;28351:3;28344:5;28341:14;28334:120;;;28405:39;28442:1;28435:5;28405:39;:::i;:::-;28378:1;28371:5;28367:13;28358:22;;28334:120;;;28274:186;;:::o;28466:543::-;28567:2;28562:3;28559:11;28556:446;;;28601:38;28633:5;28601:38;:::i;:::-;28685:29;28703:10;28685:29;:::i;:::-;28675:8;28671:44;28868:2;28856:10;28853:18;28850:49;;;28889:8;28874:23;;28850:49;28912:80;28968:22;28986:3;28968:22;:::i;:::-;28958:8;28954:37;28941:11;28912:80;:::i;:::-;28571:431;;28556:446;28466:543;;;:::o;29015:117::-;29069:8;29119:5;29113:4;29109:16;29088:37;;29015:117;;;;:::o;29138:169::-;29182:6;29215:51;29263:1;29259:6;29251:5;29248:1;29244:13;29215:51;:::i;:::-;29211:56;29296:4;29290;29286:15;29276:25;;29189:118;29138:169;;;;:::o;29312:295::-;29388:4;29534:29;29559:3;29553:4;29534:29;:::i;:::-;29526:37;;29596:3;29593:1;29589:11;29583:4;29580:21;29572:29;;29312:295;;;;:::o;29612:1403::-;29736:44;29776:3;29771;29736:44;:::i;:::-;29845:18;29837:6;29834:30;29831:56;;;29867:18;;:::i;:::-;29831:56;29911:38;29943:4;29937:11;29911:38;:::i;:::-;29996:67;30056:6;30048;30042:4;29996:67;:::i;:::-;30090:1;30119:2;30111:6;30108:14;30136:1;30131:632;;;;30807:1;30824:6;30821:84;;;30880:9;30875:3;30871:19;30858:33;30849:42;;30821:84;30931:67;30991:6;30984:5;30931:67;:::i;:::-;30925:4;30918:81;30780:229;30101:908;;30131:632;30183:4;30179:9;30171:6;30167:22;30217:37;30249:4;30217:37;:::i;:::-;30276:1;30290:215;30304:7;30301:1;30298:14;30290:215;;;30390:9;30385:3;30381:19;30368:33;30360:6;30353:49;30441:1;30433:6;30429:14;30419:24;;30488:2;30477:9;30473:18;30460:31;;30327:4;30324:1;30320:12;30315:17;;30290:215;;;30533:6;30524:7;30521:19;30518:186;;;30598:9;30593:3;30589:19;30576:33;30641:48;30683:4;30675:6;30671:17;30660:9;30641:48;:::i;:::-;30633:6;30626:64;30541:163;30518:186;30750:1;30746;30738:6;30734:14;30730:22;30724:4;30717:36;30138:625;;;30101:908;;29711:1304;;;29612:1403;;;:::o;31021:170::-;31161:22;31157:1;31149:6;31145:14;31138:46;31021:170;:::o;31197:366::-;31339:3;31360:67;31424:2;31419:3;31360:67;:::i;:::-;31353:74;;31436:93;31525:3;31436:93;:::i;:::-;31554:2;31549:3;31545:12;31538:19;;31197:366;;;:::o;31569:419::-;31735:4;31773:2;31762:9;31758:18;31750:26;;31822:9;31816:4;31812:20;31808:1;31797:9;31793:17;31786:47;31850:131;31976:4;31850:131;:::i;:::-;31842:139;;31569:419;;;:::o;31994:165::-;32134:17;32130:1;32122:6;32118:14;32111:41;31994:165;:::o;32165:366::-;32307:3;32328:67;32392:2;32387:3;32328:67;:::i;:::-;32321:74;;32404:93;32493:3;32404:93;:::i;:::-;32522:2;32517:3;32513:12;32506:19;;32165:366;;;:::o;32537:419::-;32703:4;32741:2;32730:9;32726:18;32718:26;;32790:9;32784:4;32780:20;32776:1;32765:9;32761:17;32754:47;32818:131;32944:4;32818:131;:::i;:::-;32810:139;;32537:419;;;:::o;32962:553::-;33139:4;33177:3;33166:9;33162:19;33154:27;;33191:71;33259:1;33248:9;33244:17;33235:6;33191:71;:::i;:::-;33272:72;33340:2;33329:9;33325:18;33316:6;33272:72;:::i;:::-;33354;33422:2;33411:9;33407:18;33398:6;33354:72;:::i;:::-;33436;33504:2;33493:9;33489:18;33480:6;33436:72;:::i;:::-;32962:553;;;;;;;:::o;33521:442::-;33670:4;33708:2;33697:9;33693:18;33685:26;;33721:71;33789:1;33778:9;33774:17;33765:6;33721:71;:::i;:::-;33802:72;33870:2;33859:9;33855:18;33846:6;33802:72;:::i;:::-;33884;33952:2;33941:9;33937:18;33928:6;33884:72;:::i;:::-;33521:442;;;;;;:::o;33969:157::-;34109:9;34105:1;34097:6;34093:14;34086:33;33969:157;:::o;34132:365::-;34274:3;34295:66;34359:1;34354:3;34295:66;:::i;:::-;34288:73;;34370:93;34459:3;34370:93;:::i;:::-;34488:2;34483:3;34479:12;34472:19;;34132:365;;;:::o;34503:419::-;34669:4;34707:2;34696:9;34692:18;34684:26;;34756:9;34750:4;34746:20;34742:1;34731:9;34727:17;34720:47;34784:131;34910:4;34784:131;:::i;:::-;34776:139;;34503:419;;;:::o;34928:180::-;34976:77;34973:1;34966:88;35073:4;35070:1;35063:15;35097:4;35094:1;35087:15;35114:233;35153:3;35176:24;35194:5;35176:24;:::i;:::-;35167:33;;35222:66;35215:5;35212:77;35209:103;;35292:18;;:::i;:::-;35209:103;35339:1;35332:5;35328:13;35321:20;;35114:233;;;:::o;35353:165::-;35493:17;35489:1;35481:6;35477:14;35470:41;35353:165;:::o;35524:366::-;35666:3;35687:67;35751:2;35746:3;35687:67;:::i;:::-;35680:74;;35763:93;35852:3;35763:93;:::i;:::-;35881:2;35876:3;35872:12;35865:19;;35524:366;;;:::o;35896:419::-;36062:4;36100:2;36089:9;36085:18;36077:26;;36149:9;36143:4;36139:20;36135:1;36124:9;36120:17;36113:47;36177:131;36303:4;36177:131;:::i;:::-;36169:139;;35896:419;;;:::o;36321:148::-;36423:11;36460:3;36445:18;;36321:148;;;;:::o;36475:390::-;36581:3;36609:39;36642:5;36609:39;:::i;:::-;36664:89;36746:6;36741:3;36664:89;:::i;:::-;36657:96;;36762:65;36820:6;36815:3;36808:4;36801:5;36797:16;36762:65;:::i;:::-;36852:6;36847:3;36843:16;36836:23;;36585:280;36475:390;;;;:::o;36871:400::-;37031:3;37052:84;37134:1;37129:3;37052:84;:::i;:::-;37045:91;;37145:93;37234:3;37145:93;:::i;:::-;37263:1;37258:3;37254:11;37247:18;;36871:400;;;:::o;37277:541::-;37510:3;37532:95;37623:3;37614:6;37532:95;:::i;:::-;37525:102;;37644:148;37788:3;37644:148;:::i;:::-;37637:155;;37809:3;37802:10;;37277:541;;;;:::o;37824:225::-;37964:34;37960:1;37952:6;37948:14;37941:58;38033:8;38028:2;38020:6;38016:15;38009:33;37824:225;:::o;38055:366::-;38197:3;38218:67;38282:2;38277:3;38218:67;:::i;:::-;38211:74;;38294:93;38383:3;38294:93;:::i;:::-;38412:2;38407:3;38403:12;38396:19;;38055:366;;;:::o;38427:419::-;38593:4;38631:2;38620:9;38616:18;38608:26;;38680:9;38674:4;38670:20;38666:1;38655:9;38651:17;38644:47;38708:131;38834:4;38708:131;:::i;:::-;38700:139;;38427:419;;;:::o;38852:242::-;38992:34;38988:1;38980:6;38976:14;38969:58;39061:25;39056:2;39048:6;39044:15;39037:50;38852:242;:::o;39100:366::-;39242:3;39263:67;39327:2;39322:3;39263:67;:::i;:::-;39256:74;;39339:93;39428:3;39339:93;:::i;:::-;39457:2;39452:3;39448:12;39441:19;;39100:366;;;:::o;39472:419::-;39638:4;39676:2;39665:9;39661:18;39653:26;;39725:9;39719:4;39715:20;39711:1;39700:9;39696:17;39689:47;39753:131;39879:4;39753:131;:::i;:::-;39745:139;;39472:419;;;:::o;39897:233::-;40037:34;40033:1;40025:6;40021:14;40014:58;40106:16;40101:2;40093:6;40089:15;40082:41;39897:233;:::o;40136:366::-;40278:3;40299:67;40363:2;40358:3;40299:67;:::i;:::-;40292:74;;40375:93;40464:3;40375:93;:::i;:::-;40493:2;40488:3;40484:12;40477:19;;40136:366;;;:::o;40508:419::-;40674:4;40712:2;40701:9;40697:18;40689:26;;40761:9;40755:4;40751:20;40747:1;40736:9;40732:17;40725:47;40789:131;40915:4;40789:131;:::i;:::-;40781:139;;40508:419;;;:::o;40933:1395::-;41050:37;41083:3;41050:37;:::i;:::-;41152:18;41144:6;41141:30;41138:56;;;41174:18;;:::i;:::-;41138:56;41218:38;41250:4;41244:11;41218:38;:::i;:::-;41303:67;41363:6;41355;41349:4;41303:67;:::i;:::-;41397:1;41421:4;41408:17;;41453:2;41445:6;41442:14;41470:1;41465:618;;;;42127:1;42144:6;42141:77;;;42193:9;42188:3;42184:19;42178:26;42169:35;;42141:77;42244:67;42304:6;42297:5;42244:67;:::i;:::-;42238:4;42231:81;42100:222;41435:887;;41465:618;41517:4;41513:9;41505:6;41501:22;41551:37;41583:4;41551:37;:::i;:::-;41610:1;41624:208;41638:7;41635:1;41632:14;41624:208;;;41717:9;41712:3;41708:19;41702:26;41694:6;41687:42;41768:1;41760:6;41756:14;41746:24;;41815:2;41804:9;41800:18;41787:31;;41661:4;41658:1;41654:12;41649:17;;41624:208;;;41860:6;41851:7;41848:19;41845:179;;;41918:9;41913:3;41909:19;41903:26;41961:48;42003:4;41995:6;41991:17;41980:9;41961:48;:::i;:::-;41953:6;41946:64;41868:156;41845:179;42070:1;42066;42058:6;42054:14;42050:22;42044:4;42037:36;41472:611;;;41435:887;;41025:1303;;;40933:1395;;:::o;42334:85::-;42379:7;42408:5;42397:16;;42334:85;;;:::o;42425:86::-;42460:7;42500:4;42493:5;42489:16;42478:27;;42425:86;;;:::o;42517:154::-;42573:9;42606:59;42622:42;42631:32;42657:5;42631:32;:::i;:::-;42622:42;:::i;:::-;42606:59;:::i;:::-;42593:72;;42517:154;;;:::o;42677:143::-;42770:43;42807:5;42770:43;:::i;:::-;42765:3;42758:56;42677:143;;:::o;42826:234::-;42925:4;42963:2;42952:9;42948:18;42940:26;;42976:77;43050:1;43039:9;43035:17;43026:6;42976:77;:::i;:::-;42826:234;;;;:::o;43066:182::-;43206:34;43202:1;43194:6;43190:14;43183:58;43066:182;:::o;43254:366::-;43396:3;43417:67;43481:2;43476:3;43417:67;:::i;:::-;43410:74;;43493:93;43582:3;43493:93;:::i;:::-;43611:2;43606:3;43602:12;43595:19;;43254:366;;;:::o;43626:419::-;43792:4;43830:2;43819:9;43815:18;43807:26;;43879:9;43873:4;43869:20;43865:1;43854:9;43850:17;43843:47;43907:131;44033:4;43907:131;:::i;:::-;43899:139;;43626:419;;;:::o;44051:165::-;44191:17;44187:1;44179:6;44175:14;44168:41;44051:165;:::o;44222:366::-;44364:3;44385:67;44449:2;44444:3;44385:67;:::i;:::-;44378:74;;44461:93;44550:3;44461:93;:::i;:::-;44579:2;44574:3;44570:12;44563:19;;44222:366;;;:::o;44594:419::-;44760:4;44798:2;44787:9;44783:18;44775:26;;44847:9;44841:4;44837:20;44833:1;44822:9;44818:17;44811:47;44875:131;45001:4;44875:131;:::i;:::-;44867:139;;44594:419;;;:::o;45019:167::-;45159:19;45155:1;45147:6;45143:14;45136:43;45019:167;:::o;45192:366::-;45334:3;45355:67;45419:2;45414:3;45355:67;:::i;:::-;45348:74;;45431:93;45520:3;45431:93;:::i;:::-;45549:2;45544:3;45540:12;45533:19;;45192:366;;;:::o;45564:419::-;45730:4;45768:2;45757:9;45753:18;45745:26;;45817:9;45811:4;45807:20;45803:1;45792:9;45788:17;45781:47;45845:131;45971:4;45845:131;:::i;:::-;45837:139;;45564:419;;;:::o;45989:177::-;46129:29;46125:1;46117:6;46113:14;46106:53;45989:177;:::o;46172:366::-;46314:3;46335:67;46399:2;46394:3;46335:67;:::i;:::-;46328:74;;46411:93;46500:3;46411:93;:::i;:::-;46529:2;46524:3;46520:12;46513:19;;46172:366;;;:::o;46544:419::-;46710:4;46748:2;46737:9;46733:18;46725:26;;46797:9;46791:4;46787:20;46783:1;46772:9;46768:17;46761:47;46825:131;46951:4;46825:131;:::i;:::-;46817:139;;46544:419;;;:::o;46969:173::-;47109:25;47105:1;47097:6;47093:14;47086:49;46969:173;:::o;47148:366::-;47290:3;47311:67;47375:2;47370:3;47311:67;:::i;:::-;47304:74;;47387:93;47476:3;47387:93;:::i;:::-;47505:2;47500:3;47496:12;47489:19;;47148:366;;;:::o;47520:419::-;47686:4;47724:2;47713:9;47709:18;47701:26;;47773:9;47767:4;47763:20;47759:1;47748:9;47744:17;47737:47;47801:131;47927:4;47801:131;:::i;:::-;47793:139;;47520:419;;;:::o;47945:171::-;47984:3;48007:24;48025:5;48007:24;:::i;:::-;47998:33;;48053:4;48046:5;48043:15;48040:41;;48061:18;;:::i;:::-;48040:41;48108:1;48101:5;48097:13;48090:20;;47945:171;;;:::o;48122:163::-;48262:15;48258:1;48250:6;48246:14;48239:39;48122:163;:::o;48291:366::-;48433:3;48454:67;48518:2;48513:3;48454:67;:::i;:::-;48447:74;;48530:93;48619:3;48530:93;:::i;:::-;48648:2;48643:3;48639:12;48632:19;;48291:366;;;:::o;48663:419::-;48829:4;48867:2;48856:9;48852:18;48844:26;;48916:9;48910:4;48906:20;48902:1;48891:9;48887:17;48880:47;48944:131;49070:4;48944:131;:::i;:::-;48936:139;;48663:419;;;:::o;49088:435::-;49268:3;49290:95;49381:3;49372:6;49290:95;:::i;:::-;49283:102;;49402:95;49493:3;49484:6;49402:95;:::i;:::-;49395:102;;49514:3;49507:10;;49088:435;;;;;:::o;49529:230::-;49669:34;49665:1;49657:6;49653:14;49646:58;49738:13;49733:2;49725:6;49721:15;49714:38;49529:230;:::o;49765:366::-;49907:3;49928:67;49992:2;49987:3;49928:67;:::i;:::-;49921:74;;50004:93;50093:3;50004:93;:::i;:::-;50122:2;50117:3;50113:12;50106:19;;49765:366;;;:::o;50137:419::-;50303:4;50341:2;50330:9;50326:18;50318:26;;50390:9;50384:4;50380:20;50376:1;50365:9;50361:17;50354:47;50418:131;50544:4;50418:131;:::i;:::-;50410:139;;50137:419;;;:::o;50562:239::-;50702:34;50698:1;50690:6;50686:14;50679:58;50771:22;50766:2;50758:6;50754:15;50747:47;50562:239;:::o;50807:366::-;50949:3;50970:67;51034:2;51029:3;50970:67;:::i;:::-;50963:74;;51046:93;51135:3;51046:93;:::i;:::-;51164:2;51159:3;51155:12;51148:19;;50807:366;;;:::o;51179:419::-;51345:4;51383:2;51372:9;51368:18;51360:26;;51432:9;51426:4;51422:20;51418:1;51407:9;51403:17;51396:47;51460:131;51586:4;51460:131;:::i;:::-;51452:139;;51179:419;;;:::o;51604:98::-;51655:6;51689:5;51683:12;51673:22;;51604:98;;;:::o;51708:168::-;51791:11;51825:6;51820:3;51813:19;51865:4;51860:3;51856:14;51841:29;;51708:168;;;;:::o;51882:373::-;51968:3;51996:38;52028:5;51996:38;:::i;:::-;52050:70;52113:6;52108:3;52050:70;:::i;:::-;52043:77;;52129:65;52187:6;52182:3;52175:4;52168:5;52164:16;52129:65;:::i;:::-;52219:29;52241:6;52219:29;:::i;:::-;52214:3;52210:39;52203:46;;51972:283;51882:373;;;;:::o;52261:640::-;52456:4;52494:3;52483:9;52479:19;52471:27;;52508:71;52576:1;52565:9;52561:17;52552:6;52508:71;:::i;:::-;52589:72;52657:2;52646:9;52642:18;52633:6;52589:72;:::i;:::-;52671;52739:2;52728:9;52724:18;52715:6;52671:72;:::i;:::-;52790:9;52784:4;52780:20;52775:2;52764:9;52760:18;52753:48;52818:76;52889:4;52880:6;52818:76;:::i;:::-;52810:84;;52261:640;;;;;;;:::o;52907:141::-;52963:5;52994:6;52988:13;52979:22;;53010:32;53036:5;53010:32;:::i;:::-;52907:141;;;;:::o;53054:349::-;53123:6;53172:2;53160:9;53151:7;53147:23;53143:32;53140:119;;;53178:79;;:::i;:::-;53140:119;53298:1;53323:63;53378:7;53369:6;53358:9;53354:22;53323:63;:::i;:::-;53313:73;;53269:127;53054:349;;;;:::o
Swarm Source
ipfs://1bd3efa406850e5fb917562dd0918358d52a9f54b85a6683aa78fd88dbe3268f
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
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.