Feature Tip: Add private address tag to any address under My Name Tag !
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 | 17492300 | 490 days ago | IN | 0 ETH | 0.07565176 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
TokenRunBattlePass
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-06-16 */ // 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/battlepass.sol // pragma solidity ^0.8.18; pragma solidity ^0.8.18; contract TokenRunBattlePass is ERC721x { string public baseURI; uint256 public maxSupply; uint256 public maxPerWallet; uint256 public mintPrice; bool public enableTransfer; bool public enableMint; mapping(address => uint256) mintAddr; mapping(uint256 => uint256) 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 _uri, uint256 _mintPrice ) public initializerERC721A initializer { __ERC721x_init("Token Run Battle Pass", "PASS"); baseURI = _uri; enableTransfer = false; enableMint = false; maxPerWallet = 1; mintPrice = _mintPrice; } function adminMint(address receiver, uint256 quantity) public onlyOwner { safeMint(receiver, quantity); } function mint() public payable { require(enableMint, "mint not enabled"); require(msg.value >= mintPrice, "insufficient value"); require(mintAddr[msg.sender] < maxPerWallet, "reached the maximum"); mintAddr[msg.sender] = 1; safeMint(msg.sender, 1); } function safeMint(address receiver, uint256 quantity) internal { _mint(receiver, quantity); } // // =============== URI =============== function _startTokenId() internal view virtual override returns (uint256) { return 1; } function _baseURI() internal view virtual override returns (string memory) { return baseURI; } function tokenURI(uint256 _tokenId) public view override returns (string memory) { require(_exists(_tokenId), "TOKEN NOT EXIST"); return baseURI; } function setBaseURI(string calldata _uri) external onlyOwner { baseURI = _uri; } // // =============== 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":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableTransfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"_uri","type":"string"},{"internalType":"uint256","name":"_mintPrice","type":"uint256"}],"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":[],"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":"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":"_uri","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":"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":[],"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
60806040523480156200001157600080fd5b50620000226200002860201b60201c565b620001d2565b600060019054906101000a900460ff16156200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000175565b60405180910390fd5b60ff801660008054906101000a900460ff1660ff1614620000ec5760ff6000806101000a81548160ff021916908360ff1602179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860ff604051620000e39190620001b5565b60405180910390a15b565b600082825260208201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960008201527f616c697a696e6700000000000000000000000000000000000000000000000000602082015250565b60006200015d602783620000ee565b91506200016a82620000ff565b604082019050919050565b6000602082019050818103600083015262000190816200014e565b9050919050565b600060ff82169050919050565b620001af8162000197565b82525050565b6000602082019050620001cc6000830184620001a4565b92915050565b61526480620001e26000396000f3fe6080604052600436106102515760003560e01c80636817c76c11610139578063a694fc3a116100b6578063d5abeb011161007a578063d5abeb011461087b578063e58306f9146108a6578063e985e9c5146108cf578063f1b50c1d1461090c578063f2fde38b14610937578063f4a0a5281461096057610251565b8063a694fc3a14610793578063ac52e644146107bc578063b1a6505f146107e5578063b88d4fde14610822578063c87b56dd1461083e57610251565b80638beaf7d7116100fd5780638beaf7d7146106c25780638da5cb5b146106eb57806394d216d61461071657806395d89b411461073f578063a22cb4651461076a57610251565b80636817c76c146105db5780636c0360eb1461060657806370a0823114610631578063715018a61461066e57806372abc8b71461068557610251565b80632cba8123116101d2578063453c231011610196578063453c2310146104bb578063493770cc146104e657806355f804b31461050f5780635d3eea91146105385780636352211e14610561578063650b00f61461059e57610251565b80632cba8123146103f75780633ccfd60b1461043457806340a9c8df1461044b57806342842e0e1461047457806344b28d591461049057610251565b80631249c58b116102195780631249c58b1461035457806318160ddd1461035e5780631f85e3ca1461038957806323b872dd146103b25780632799cde0146103ce57610251565b806301ffc9a71461025657806306fdde0314610293578063081812fc146102be57806309308e5d146102fb578063095ea7b314610338575b600080fd5b34801561026257600080fd5b5061027d60048036038101906102789190613892565b610989565b60405161028a91906138da565b60405180910390f35b34801561029f57600080fd5b506102a86109ea565b6040516102b59190613985565b60405180910390f35b3480156102ca57600080fd5b506102e560048036038101906102e091906139dd565b610a85565b6040516102f29190613a4b565b60405180910390f35b34801561030757600080fd5b50610322600480360381019061031d9190613a92565b610b0d565b60405161032f9190613ae1565b60405180910390f35b610352600480360381019061034d9190613afc565b610b32565b005b61035c610b42565b005b34801561036a57600080fd5b50610373610cab565b6040516103809190613ae1565b60405180910390f35b34801561039557600080fd5b506103b060048036038101906103ab9190613b68565b610cd4565b005b6103cc60048036038101906103c79190613b95565b610cf9565b005b3480156103da57600080fd5b506103f560048036038101906103f091906139dd565b610dae565b005b34801561040357600080fd5b5061041e60048036038101906104199190613be8565b610e02565b60405161042b9190613a4b565b60405180910390f35b34801561044057600080fd5b50610449610e44565b005b34801561045757600080fd5b50610472600480360381019061046d91906139dd565b610f09565b005b61048e60048036038101906104899190613b95565b610f5d565b005b34801561049c57600080fd5b506104a5610f7d565b6040516104b291906138da565b60405180910390f35b3480156104c757600080fd5b506104d0610f90565b6040516104dd9190613ae1565b60405180910390f35b3480156104f257600080fd5b5061050d60048036038101906105089190613b68565b610f96565b005b34801561051b57600080fd5b5061053660048036038101906105319190613c8d565b610fbb565b005b34801561054457600080fd5b5061055f600480360381019061055a91906139dd565b610fd9565b005b34801561056d57600080fd5b50610588600480360381019061058391906139dd565b611117565b6040516105959190613a4b565b60405180910390f35b3480156105aa57600080fd5b506105c560048036038101906105c091906139dd565b611129565b6040516105d29190613ae1565b60405180910390f35b3480156105e757600080fd5b506105f0611141565b6040516105fd9190613ae1565b60405180910390f35b34801561061257600080fd5b5061061b611147565b6040516106289190613985565b60405180910390f35b34801561063d57600080fd5b5061065860048036038101906106539190613cda565b6111d5565b6040516106659190613ae1565b60405180910390f35b34801561067a57600080fd5b50610683611296565b005b34801561069157600080fd5b506106ac60048036038101906106a791906139dd565b6112aa565b6040516106b991906138da565b60405180910390f35b3480156106ce57600080fd5b506106e960048036038101906106e49190613e37565b6112c9565b005b3480156106f757600080fd5b506107006115e7565b60405161070d9190613a4b565b60405180910390f35b34801561072257600080fd5b5061073d60048036038101906107389190613a92565b611611565b005b34801561074b57600080fd5b50610754611667565b6040516107619190613985565b60405180910390f35b34801561077657600080fd5b50610791600480360381019061078c9190613e93565b611702565b005b34801561079f57600080fd5b506107ba60048036038101906107b591906139dd565b611816565b005b3480156107c857600080fd5b506107e360048036038101906107de9190613f7f565b61194b565b005b3480156107f157600080fd5b5061080c60048036038101906108079190613cda565b611a68565b60405161081991906138da565b60405180910390f35b61083c600480360381019061083791906140a1565b611a88565b005b34801561084a57600080fd5b50610865600480360381019061086091906139dd565b611b3f565b6040516108729190613985565b60405180910390f35b34801561088757600080fd5b50610890611c1b565b60405161089d9190613ae1565b60405180910390f35b3480156108b257600080fd5b506108cd60048036038101906108c89190613afc565b611c21565b005b3480156108db57600080fd5b506108f660048036038101906108f19190614124565b611c37565b60405161090391906138da565b60405180910390f35b34801561091857600080fd5b50610921611cd4565b60405161092e91906138da565b60405180910390f35b34801561094357600080fd5b5061095e60048036038101906109599190613cda565b611ce7565b005b34801561096c57600080fd5b50610987600480360381019061098291906139dd565b611d6a565b005b600063706e848960e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806109e357506109e282611d7c565b5b9050919050565b60606109f4611e0e565b6002018054610a0290614193565b80601f0160208091040260200160405190810160405280929190818152602001828054610a2e90614193565b8015610a7b5780601f10610a5057610100808354040283529160200191610a7b565b820191906000526020600020905b815481529060010190602001808311610a5e57829003601f168201915b5050505050905090565b6000610a9082611e3b565b610ac6576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ace611e0e565b600601600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6068602052816000526040600020602052806000526040600020600091509150505481565b610b3e82826001611eac565b5050565b606d60019054906101000a900460ff16610b91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b8890614210565b60405180910390fd5b606c54341015610bd6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bcd9061427c565b60405180910390fd5b606b54606e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410610c59576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c50906142e8565b60405180910390fd5b6001606e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610ca9336001612001565b565b6000610cb561200f565b610cbd611e0e565b60010154610cc9611e0e565b600001540303905090565b610cdc612018565b80606d60016101000a81548160ff02191690831515021790555050565b606d60009054906101000a900460ff16610d48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3f90614354565b60405180910390fd5b6000606f60008381526020019081526020016000205414610d9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d95906143c0565b60405180910390fd5b610da9838383612096565b505050565b610db781611e3b565b610df6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ded9061442c565b60405180910390fd5b610dff816120ee565b50565b60676020528160005260406000206020528060005260406000206000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610e4c612018565b6000479050600033905060008173ffffffffffffffffffffffffffffffffffffffff1683604051610e7c9061447d565b60006040518083038185875af1925050503d8060008114610eb9576040519150601f19603f3d011682016040523d82523d6000602084013e610ebe565b606091505b50508091505080610f04576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610efb906144de565b60405180910390fd5b505050565b610f1281611e3b565b610f51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f489061442c565b60405180910390fd5b610f5a8161235a565b50565b610f7883838360405180602001604052806000815250611a88565b505050565b606d60019054906101000a900460ff1681565b606b5481565b610f9e612018565b80606d60006101000a81548160ff02191690831515021790555050565b610fc3612018565b818160699182610fd49291906146b5565b505050565b610fe281611117565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461104f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611046906147d1565b60405180910390fd5b6000606f600083815260200190815260200160002054146110a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161109c9061483d565b60405180910390fd5b6000606f60008381526020019081526020016000205490506000606f6000848152602001908152602001600020819055507fc1e00202ee2c06861d326fc6374026b751863ff64218ccbaa38c3e603a8e72c28233834260405161110b949392919061485d565b60405180910390a15050565b600061112282612735565b9050919050565b60666020528060005260406000206000915090505481565b606c5481565b6069805461115490614193565b80601f016020809104026020016040519081016040528092919081815260200182805461118090614193565b80156111cd5780601f106111a2576101008083540402835291602001916111cd565b820191906000526020600020905b8154815290600101906020018083116111b057829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361123c576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff61124d611e0e565b60050160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b61129e612018565b6112a86000612848565b565b6000806066600084815260200190815260200160002054149050919050565b6112d161290e565b60000160019054906101000a900460ff16611305576112ee61290e565b60000160009054906101000a900460ff161561130e565b61130d61293b565b5b61134d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134490614914565b60405180910390fd5b600061135761290e565b60000160019054906101000a900460ff1615905080156113ba57600161137b61290e565b60000160016101000a81548160ff021916908315150217905550600161139f61290e565b60000160006101000a81548160ff0219169083151502179055505b60008060019054906101000a900460ff161590508080156113eb5750600160008054906101000a900460ff1660ff16105b8061141857506113fa30612952565b1580156114175750600160008054906101000a900460ff1660ff16145b5b611457576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161144e906149a6565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015611494576001600060016101000a81548160ff0219169083151502179055505b6115086040518060400160405280601581526020017f546f6b656e2052756e20426174746c65205061737300000000000000000000008152506040518060400160405280600481526020017f5041535300000000000000000000000000000000000000000000000000000000815250612975565b836069908161151791906149c6565b506000606d60006101000a81548160ff0219169083151502179055506000606d60016101000a81548160ff0219169083151502179055506001606b8190555082606c8190555080156115b65760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516115ad9190614ae0565b60405180910390a15b5080156115e25760006115c761290e565b60000160016101000a81548160ff0219169083151502179055505b505050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61161a82611e3b565b611659576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116509061442c565b60405180910390fd5b61166382826129da565b5050565b6060611671611e0e565b600301805461167f90614193565b80601f01602080910402602001604051908101604052809291908181526020018280546116ab90614193565b80156116f85780601f106116cd576101008083540402835291602001916116f8565b820191906000526020600020905b8154815290600101906020018083116116db57829003601f168201915b5050505050905090565b8061170b611e0e565b6007016000611718612db7565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166117c5612db7565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161180a91906138da565b60405180910390a35050565b61181f81611117565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461188c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611883906147d1565b60405180910390fd5b6000606f600083815260200190815260200160002054146118e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118d99061483d565b60405180910390fd5b42606f6000838152602001908152602001600020819055507f02567b2553aeb44e4ddd5d68462774dc3de158cb0f2c2da1740e729b22086aff8133606f60008581526020019081526020016000205460405161194093929190614afb565b60405180910390a150565b611953612018565b81819050848490501461199b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161199290614b7e565b60405180910390fd5b60005b84849050811015611a61578282828181106119bc576119bb614b9e565b5b90506020020160208101906119d19190613b68565b606560008787858181106119e8576119e7614b9e565b5b90506020020160208101906119fd9190613cda565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611a5990614bfc565b91505061199e565b5050505050565b60656020528060005260406000206000915054906101000a900460ff1681565b606d60009054906101000a900460ff16611ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ace90614354565b60405180910390fd5b6000606f60008481526020019081526020016000205414611b2d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b24906143c0565b60405180910390fd5b611b3984848484612dbf565b50505050565b6060611b4a82611e3b565b611b89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b8090614c90565b60405180910390fd5b60698054611b9690614193565b80601f0160208091040260200160405190810160405280929190818152602001828054611bc290614193565b8015611c0f5780601f10611be457610100808354040283529160200191611c0f565b820191906000526020600020905b815481529060010190602001808311611bf257829003601f168201915b50505050509050919050565b606a5481565b611c29612018565b611c338282612001565b5050565b6000611c41611e0e565b60070160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606d60009054906101000a900460ff1681565b611cef612018565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611d5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d5590614d22565b60405180910390fd5b611d6781612848565b50565b611d72612018565b80606c8190555050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611dd757506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611e075750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6000807f2569078dfb4b0305704d3008e7403993ae9601b85f7ae5e742de3de8f8011c4090508091505090565b600081611e4661200f565b11158015611e5e5750611e57611e0e565b6000015482105b8015611ea5575060007c0100000000000000000000000000000000000000000000000000000000611e8d611e0e565b60040160008581526020019081526020016000205416145b9050919050565b6000611eb783611117565b90508115611f42578073ffffffffffffffffffffffffffffffffffffffff16611ede612db7565b73ffffffffffffffffffffffffffffffffffffffff1614611f4157611f0a81611f05612db7565b611c37565b611f40576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b83611f4b611e0e565b600601600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b61200b8282612e19565b5050565b60006001905090565b612020612ff9565b73ffffffffffffffffffffffffffffffffffffffff1661203e6115e7565b73ffffffffffffffffffffffffffffffffffffffff1614612094576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161208b90614d8e565b60405180910390fd5b565b61209f816112aa565b6120de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120d590614dfa565b60405180910390fd5b6120e9838383613001565b505050565b606560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661217a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161217190614e66565b60405180910390fd5b60006068600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541461220d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161220490614ed2565b60405180910390fd5b60006001606660008481526020019081526020016000205461222f9190614ef2565b90503360676000848152602001908152602001600020600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806068600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060666000838152602001908152602001600020600081548092919061230d90614bfc565b91905055503373ffffffffffffffffffffffffffffffffffffffff16827f9ecfd70e9ff36df72989324a49559383d39f9290d700b10cf5ac10dcb68d264360405160405180910390a35050565b606560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166123e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123dd90614e66565b60405180910390fd5b60006068600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000810361247e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161247590614f72565b60405180910390fd5b60006066600084815260200190815260200160002054905080821461260857600060676000858152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060676000868152602001908152602001600020600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060676000868152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826068600086815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505061266d565b600060676000858152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006068600085815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506066600084815260200190815260200160002060008154809291906126e790614f92565b91905055503373ffffffffffffffffffffffffffffffffffffffff16837f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3760405160405180910390a3505050565b60008161274061200f565b116128115761274d611e0e565b600401600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603612810576000810361280b5761279b611e0e565b6000015482106127d7576040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b6127e0611e0e565b60040160008360019003935083815260200190815260200160002054905060008103612843576127d8565b612843565b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000807fee151c8401928dc223602bb187aff91b9a56c7cae5476ef1b3287b085a16c85f90508091505090565b6000803090506000813b9050600081149250505090565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff166129c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129bb9061502d565b60405180910390fd5b6129ce8282613359565b6129d66133bf565b5050565b606560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612a67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a5e90614e66565b60405180910390fd5b60006068600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008103612aff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612af690615099565b60405180910390fd5b600060666000858152602001908152602001600020549050808214612c8957600060676000868152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060676000878152602001908152602001600020600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060676000878152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826068600087815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050612cee565b600060676000868152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006068600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550606660008581526020019081526020016000206000815480929190612d6890614f92565b91905055508273ffffffffffffffffffffffffffffffffffffffff16847f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3760405160405180910390a350505050565b600033905090565b612dc8826112aa565b612e07576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dfe90614dfa565b60405180910390fd5b612e1384848484613418565b50505050565b6000612e23611e0e565b60000154905060008203612e63576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e70600084838561348b565b600160406001901b178202612e83611e0e565b60050160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612ef083612ee16000866000613491565b612eea856134b9565b176134c9565b612ef8611e0e565b600401600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114612f9a57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612f5f565b5060008203612fd5576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80612fde611e0e565b600001819055505050612ff460008483856134f4565b505050565b600033905090565b600061300c82612735565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613073576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061307f846134fa565b915091506130958187613090612db7565b61352a565b6130e1576130aa866130a5612db7565b611c37565b6130e0576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603613147576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613154868686600161348b565b801561315f57600082555b613167611e0e565b60050160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460019003919050819055506131be611e0e565b60050160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001019190508190555061323f8561321b888887613491565b7c0200000000000000000000000000000000000000000000000000000000176134c9565b613247611e0e565b60040160008681526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008416036132e95760006001850190506000613298611e0e565b600401600083815260200190815260200160002054036132e7576132ba611e0e565b6000015481146132e657836132cd611e0e565b6004016000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461335186868660016134f4565b505050505050565b61336161290e565b60000160019054906101000a900460ff166133b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133a89061512b565b60405180910390fd5b6133bb828261356e565b5050565b600060019054906101000a900460ff1661340e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134059061502d565b60405180910390fd5b613416613613565b565b613423848484610cf9565b60008373ffffffffffffffffffffffffffffffffffffffff163b146134855761344e8484848461366c565b613484576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b50505050565b60008060e883901c905060e86134a88686846137bc565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6000806000613507611e0e565b600601600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b61357661290e565b60000160019054906101000a900460ff166135c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135bd9061512b565b60405180910390fd5b816135cf611e0e565b60020190816135de91906149c6565b50806135e8611e0e565b60030190816135f791906149c6565b5061360061200f565b613608611e0e565b600001819055505050565b600060019054906101000a900460ff16613662576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136599061502d565b60405180910390fd5b61366a6137c5565b565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613692612db7565b8786866040518563ffffffff1660e01b81526004016136b494939291906151a0565b6020604051808303816000875af19250505080156136f057506040513d601f19601f820116820180604052508101906136ed9190615201565b60015b613769573d8060008114613720576040519150601f19603f3d011682016040523d82523d6000602084013e613725565b606091505b506000815103613761576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60009392505050565b600060019054906101000a900460ff16613814576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161380b9061502d565b60405180910390fd5b61382461381f612ff9565b612848565b565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61386f8161383a565b811461387a57600080fd5b50565b60008135905061388c81613866565b92915050565b6000602082840312156138a8576138a7613830565b5b60006138b68482850161387d565b91505092915050565b60008115159050919050565b6138d4816138bf565b82525050565b60006020820190506138ef60008301846138cb565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561392f578082015181840152602081019050613914565b60008484015250505050565b6000601f19601f8301169050919050565b6000613957826138f5565b6139618185613900565b9350613971818560208601613911565b61397a8161393b565b840191505092915050565b6000602082019050818103600083015261399f818461394c565b905092915050565b6000819050919050565b6139ba816139a7565b81146139c557600080fd5b50565b6000813590506139d7816139b1565b92915050565b6000602082840312156139f3576139f2613830565b5b6000613a01848285016139c8565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613a3582613a0a565b9050919050565b613a4581613a2a565b82525050565b6000602082019050613a606000830184613a3c565b92915050565b613a6f81613a2a565b8114613a7a57600080fd5b50565b600081359050613a8c81613a66565b92915050565b60008060408385031215613aa957613aa8613830565b5b6000613ab7858286016139c8565b9250506020613ac885828601613a7d565b9150509250929050565b613adb816139a7565b82525050565b6000602082019050613af66000830184613ad2565b92915050565b60008060408385031215613b1357613b12613830565b5b6000613b2185828601613a7d565b9250506020613b32858286016139c8565b9150509250929050565b613b45816138bf565b8114613b5057600080fd5b50565b600081359050613b6281613b3c565b92915050565b600060208284031215613b7e57613b7d613830565b5b6000613b8c84828501613b53565b91505092915050565b600080600060608486031215613bae57613bad613830565b5b6000613bbc86828701613a7d565b9350506020613bcd86828701613a7d565b9250506040613bde868287016139c8565b9150509250925092565b60008060408385031215613bff57613bfe613830565b5b6000613c0d858286016139c8565b9250506020613c1e858286016139c8565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f840112613c4d57613c4c613c28565b5b8235905067ffffffffffffffff811115613c6a57613c69613c2d565b5b602083019150836001820283011115613c8657613c85613c32565b5b9250929050565b60008060208385031215613ca457613ca3613830565b5b600083013567ffffffffffffffff811115613cc257613cc1613835565b5b613cce85828601613c37565b92509250509250929050565b600060208284031215613cf057613cef613830565b5b6000613cfe84828501613a7d565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613d448261393b565b810181811067ffffffffffffffff82111715613d6357613d62613d0c565b5b80604052505050565b6000613d76613826565b9050613d828282613d3b565b919050565b600067ffffffffffffffff821115613da257613da1613d0c565b5b613dab8261393b565b9050602081019050919050565b82818337600083830152505050565b6000613dda613dd584613d87565b613d6c565b905082815260208101848484011115613df657613df5613d07565b5b613e01848285613db8565b509392505050565b600082601f830112613e1e57613e1d613c28565b5b8135613e2e848260208601613dc7565b91505092915050565b60008060408385031215613e4e57613e4d613830565b5b600083013567ffffffffffffffff811115613e6c57613e6b613835565b5b613e7885828601613e09565b9250506020613e89858286016139c8565b9150509250929050565b60008060408385031215613eaa57613ea9613830565b5b6000613eb885828601613a7d565b9250506020613ec985828601613b53565b9150509250929050565b60008083601f840112613ee957613ee8613c28565b5b8235905067ffffffffffffffff811115613f0657613f05613c2d565b5b602083019150836020820283011115613f2257613f21613c32565b5b9250929050565b60008083601f840112613f3f57613f3e613c28565b5b8235905067ffffffffffffffff811115613f5c57613f5b613c2d565b5b602083019150836020820283011115613f7857613f77613c32565b5b9250929050565b60008060008060408587031215613f9957613f98613830565b5b600085013567ffffffffffffffff811115613fb757613fb6613835565b5b613fc387828801613ed3565b9450945050602085013567ffffffffffffffff811115613fe657613fe5613835565b5b613ff287828801613f29565b925092505092959194509250565b600067ffffffffffffffff82111561401b5761401a613d0c565b5b6140248261393b565b9050602081019050919050565b600061404461403f84614000565b613d6c565b9050828152602081018484840111156140605761405f613d07565b5b61406b848285613db8565b509392505050565b600082601f83011261408857614087613c28565b5b8135614098848260208601614031565b91505092915050565b600080600080608085870312156140bb576140ba613830565b5b60006140c987828801613a7d565b94505060206140da87828801613a7d565b93505060406140eb878288016139c8565b925050606085013567ffffffffffffffff81111561410c5761410b613835565b5b61411887828801614073565b91505092959194509250565b6000806040838503121561413b5761413a613830565b5b600061414985828601613a7d565b925050602061415a85828601613a7d565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806141ab57607f821691505b6020821081036141be576141bd614164565b5b50919050565b7f6d696e74206e6f7420656e61626c656400000000000000000000000000000000600082015250565b60006141fa601083613900565b9150614205826141c4565b602082019050919050565b60006020820190508181036000830152614229816141ed565b9050919050565b7f696e73756666696369656e742076616c75650000000000000000000000000000600082015250565b6000614266601283613900565b915061427182614230565b602082019050919050565b6000602082019050818103600083015261429581614259565b9050919050565b7f7265616368656420746865206d6178696d756d00000000000000000000000000600082015250565b60006142d2601383613900565b91506142dd8261429c565b602082019050919050565b60006020820190508181036000830152614301816142c5565b9050919050565b7f7472616e73666572206e6f7420656e61626c6564000000000000000000000000600082015250565b600061433e601483613900565b915061434982614308565b602082019050919050565b6000602082019050818103600083015261436d81614331565b9050919050565b7f43616e6e6f74207472616e73666572207374616b656420746f6b656e00000000600082015250565b60006143aa601c83613900565b91506143b582614374565b602082019050919050565b600060208201905081810360008301526143d98161439d565b9050919050565b7f546f6b656e202165786973740000000000000000000000000000000000000000600082015250565b6000614416600c83613900565b9150614421826143e0565b602082019050919050565b6000602082019050818103600083015261444581614409565b9050919050565b600081905092915050565b50565b600061446760008361444c565b915061447282614457565b600082019050919050565b60006144888261445a565b9150819050919050565b7f5472616e73616374696f6e20556e7375636365737366756c0000000000000000600082015250565b60006144c8601883613900565b91506144d382614492565b602082019050919050565b600060208201905081810360008301526144f7816144bb565b9050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261456b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261452e565b614575868361452e565b95508019841693508086168417925050509392505050565b6000819050919050565b60006145b26145ad6145a8846139a7565b61458d565b6139a7565b9050919050565b6000819050919050565b6145cc83614597565b6145e06145d8826145b9565b84845461453b565b825550505050565b600090565b6145f56145e8565b6146008184846145c3565b505050565b5b81811015614624576146196000826145ed565b600181019050614606565b5050565b601f8211156146695761463a81614509565b6146438461451e565b81016020851015614652578190505b61466661465e8561451e565b830182614605565b50505b505050565b600082821c905092915050565b600061468c6000198460080261466e565b1980831691505092915050565b60006146a5838361467b565b9150826002028217905092915050565b6146bf83836144fe565b67ffffffffffffffff8111156146d8576146d7613d0c565b5b6146e28254614193565b6146ed828285614628565b6000601f83116001811461471c576000841561470a578287013590505b6147148582614699565b86555061477c565b601f19841661472a86614509565b60005b828110156147525784890135825560018201915060208501945060208101905061472d565b8683101561476f578489013561476b601f89168261467b565b8355505b6001600288020188555050505b50505050505050565b7f63616c6c6572206d757374206265206f776e6572000000000000000000000000600082015250565b60006147bb601483613900565b91506147c682614785565b602082019050919050565b600060208201905081810360008301526147ea816147ae565b9050919050565b7f616c7265616479207374616b696e670000000000000000000000000000000000600082015250565b6000614827600f83613900565b9150614832826147f1565b602082019050919050565b600060208201905081810360008301526148568161481a565b9050919050565b60006080820190506148726000830187613ad2565b61487f6020830186613a3c565b61488c6040830185613ad2565b6148996060830184613ad2565b95945050505050565b7f455243373231415f5f496e697469616c697a61626c653a20636f6e747261637460008201527f20697320616c726561647920696e697469616c697a6564000000000000000000602082015250565b60006148fe603783613900565b9150614909826148a2565b604082019050919050565b6000602082019050818103600083015261492d816148f1565b9050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b6000614990602e83613900565b915061499b82614934565b604082019050919050565b600060208201905081810360008301526149bf81614983565b9050919050565b6149cf826138f5565b67ffffffffffffffff8111156149e8576149e7613d0c565b5b6149f28254614193565b6149fd828285614628565b600060209050601f831160018114614a305760008415614a1e578287015190505b614a288582614699565b865550614a90565b601f198416614a3e86614509565b60005b82811015614a6657848901518255600182019150602085019450602081019050614a41565b86831015614a835784890151614a7f601f89168261467b565b8355505b6001600288020188555050505b505050505050565b6000819050919050565b600060ff82169050919050565b6000614aca614ac5614ac084614a98565b61458d565b614aa2565b9050919050565b614ada81614aaf565b82525050565b6000602082019050614af56000830184614ad1565b92915050565b6000606082019050614b106000830186613ad2565b614b1d6020830185613a3c565b614b2a6040830184613ad2565b949350505050565b7f216c656e67746800000000000000000000000000000000000000000000000000600082015250565b6000614b68600783613900565b9150614b7382614b32565b602082019050919050565b60006020820190508181036000830152614b9781614b5b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614c07826139a7565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614c3957614c38614bcd565b5b600182019050919050565b7f544f4b454e204e4f542045584953540000000000000000000000000000000000600082015250565b6000614c7a600f83613900565b9150614c8582614c44565b602082019050919050565b60006020820190508181036000830152614ca981614c6d565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614d0c602683613900565b9150614d1782614cb0565b604082019050919050565b60006020820190508181036000830152614d3b81614cff565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614d78602083613900565b9150614d8382614d42565b602082019050919050565b60006020820190508181036000830152614da781614d6b565b9050919050565b7f546f6b656e206973206c6f636b65640000000000000000000000000000000000600082015250565b6000614de4600f83613900565b9150614def82614dae565b602082019050919050565b60006020820190508181036000830152614e1381614dd7565b9050919050565b7f43616e6e6f7420757064617465206d6170000000000000000000000000000000600082015250565b6000614e50601183613900565b9150614e5b82614e1a565b602082019050919050565b60006020820190508181036000830152614e7f81614e43565b9050919050565b7f494420616c7265616479206c6f636b65642062792063616c6c65720000000000600082015250565b6000614ebc601b83613900565b9150614ec782614e86565b602082019050919050565b60006020820190508181036000830152614eeb81614eaf565b9050919050565b6000614efd826139a7565b9150614f08836139a7565b9250828201905080821115614f2057614f1f614bcd565b5b92915050565b7f4944206e6f74206c6f636b65642062792063616c6c6572000000000000000000600082015250565b6000614f5c601783613900565b9150614f6782614f26565b602082019050919050565b60006020820190508181036000830152614f8b81614f4f565b9050919050565b6000614f9d826139a7565b915060008203614fb057614faf614bcd565b5b600182039050919050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b6000615017602b83613900565b915061502282614fbb565b604082019050919050565b600060208201905081810360008301526150468161500a565b9050919050565b7f4944206e6f74206c6f636b656400000000000000000000000000000000000000600082015250565b6000615083600d83613900565b915061508e8261504d565b602082019050919050565b600060208201905081810360008301526150b281615076565b9050919050565b7f455243373231415f5f496e697469616c697a61626c653a20636f6e747261637460008201527f206973206e6f7420696e697469616c697a696e67000000000000000000000000602082015250565b6000615115603483613900565b9150615120826150b9565b604082019050919050565b6000602082019050818103600083015261514481615108565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006151728261514b565b61517c8185615156565b935061518c818560208601613911565b6151958161393b565b840191505092915050565b60006080820190506151b56000830187613a3c565b6151c26020830186613a3c565b6151cf6040830185613ad2565b81810360608301526151e18184615167565b905095945050505050565b6000815190506151fb81613866565b92915050565b60006020828403121561521757615216613830565b5b6000615225848285016151ec565b9150509291505056fea26469706673582212207aa42ed34c05c31bc63088a295d18c860b3da493e3e0cb66675971fd0a27131264736f6c63430008120033
Deployed Bytecode
0x6080604052600436106102515760003560e01c80636817c76c11610139578063a694fc3a116100b6578063d5abeb011161007a578063d5abeb011461087b578063e58306f9146108a6578063e985e9c5146108cf578063f1b50c1d1461090c578063f2fde38b14610937578063f4a0a5281461096057610251565b8063a694fc3a14610793578063ac52e644146107bc578063b1a6505f146107e5578063b88d4fde14610822578063c87b56dd1461083e57610251565b80638beaf7d7116100fd5780638beaf7d7146106c25780638da5cb5b146106eb57806394d216d61461071657806395d89b411461073f578063a22cb4651461076a57610251565b80636817c76c146105db5780636c0360eb1461060657806370a0823114610631578063715018a61461066e57806372abc8b71461068557610251565b80632cba8123116101d2578063453c231011610196578063453c2310146104bb578063493770cc146104e657806355f804b31461050f5780635d3eea91146105385780636352211e14610561578063650b00f61461059e57610251565b80632cba8123146103f75780633ccfd60b1461043457806340a9c8df1461044b57806342842e0e1461047457806344b28d591461049057610251565b80631249c58b116102195780631249c58b1461035457806318160ddd1461035e5780631f85e3ca1461038957806323b872dd146103b25780632799cde0146103ce57610251565b806301ffc9a71461025657806306fdde0314610293578063081812fc146102be57806309308e5d146102fb578063095ea7b314610338575b600080fd5b34801561026257600080fd5b5061027d60048036038101906102789190613892565b610989565b60405161028a91906138da565b60405180910390f35b34801561029f57600080fd5b506102a86109ea565b6040516102b59190613985565b60405180910390f35b3480156102ca57600080fd5b506102e560048036038101906102e091906139dd565b610a85565b6040516102f29190613a4b565b60405180910390f35b34801561030757600080fd5b50610322600480360381019061031d9190613a92565b610b0d565b60405161032f9190613ae1565b60405180910390f35b610352600480360381019061034d9190613afc565b610b32565b005b61035c610b42565b005b34801561036a57600080fd5b50610373610cab565b6040516103809190613ae1565b60405180910390f35b34801561039557600080fd5b506103b060048036038101906103ab9190613b68565b610cd4565b005b6103cc60048036038101906103c79190613b95565b610cf9565b005b3480156103da57600080fd5b506103f560048036038101906103f091906139dd565b610dae565b005b34801561040357600080fd5b5061041e60048036038101906104199190613be8565b610e02565b60405161042b9190613a4b565b60405180910390f35b34801561044057600080fd5b50610449610e44565b005b34801561045757600080fd5b50610472600480360381019061046d91906139dd565b610f09565b005b61048e60048036038101906104899190613b95565b610f5d565b005b34801561049c57600080fd5b506104a5610f7d565b6040516104b291906138da565b60405180910390f35b3480156104c757600080fd5b506104d0610f90565b6040516104dd9190613ae1565b60405180910390f35b3480156104f257600080fd5b5061050d60048036038101906105089190613b68565b610f96565b005b34801561051b57600080fd5b5061053660048036038101906105319190613c8d565b610fbb565b005b34801561054457600080fd5b5061055f600480360381019061055a91906139dd565b610fd9565b005b34801561056d57600080fd5b50610588600480360381019061058391906139dd565b611117565b6040516105959190613a4b565b60405180910390f35b3480156105aa57600080fd5b506105c560048036038101906105c091906139dd565b611129565b6040516105d29190613ae1565b60405180910390f35b3480156105e757600080fd5b506105f0611141565b6040516105fd9190613ae1565b60405180910390f35b34801561061257600080fd5b5061061b611147565b6040516106289190613985565b60405180910390f35b34801561063d57600080fd5b5061065860048036038101906106539190613cda565b6111d5565b6040516106659190613ae1565b60405180910390f35b34801561067a57600080fd5b50610683611296565b005b34801561069157600080fd5b506106ac60048036038101906106a791906139dd565b6112aa565b6040516106b991906138da565b60405180910390f35b3480156106ce57600080fd5b506106e960048036038101906106e49190613e37565b6112c9565b005b3480156106f757600080fd5b506107006115e7565b60405161070d9190613a4b565b60405180910390f35b34801561072257600080fd5b5061073d60048036038101906107389190613a92565b611611565b005b34801561074b57600080fd5b50610754611667565b6040516107619190613985565b60405180910390f35b34801561077657600080fd5b50610791600480360381019061078c9190613e93565b611702565b005b34801561079f57600080fd5b506107ba60048036038101906107b591906139dd565b611816565b005b3480156107c857600080fd5b506107e360048036038101906107de9190613f7f565b61194b565b005b3480156107f157600080fd5b5061080c60048036038101906108079190613cda565b611a68565b60405161081991906138da565b60405180910390f35b61083c600480360381019061083791906140a1565b611a88565b005b34801561084a57600080fd5b50610865600480360381019061086091906139dd565b611b3f565b6040516108729190613985565b60405180910390f35b34801561088757600080fd5b50610890611c1b565b60405161089d9190613ae1565b60405180910390f35b3480156108b257600080fd5b506108cd60048036038101906108c89190613afc565b611c21565b005b3480156108db57600080fd5b506108f660048036038101906108f19190614124565b611c37565b60405161090391906138da565b60405180910390f35b34801561091857600080fd5b50610921611cd4565b60405161092e91906138da565b60405180910390f35b34801561094357600080fd5b5061095e60048036038101906109599190613cda565b611ce7565b005b34801561096c57600080fd5b50610987600480360381019061098291906139dd565b611d6a565b005b600063706e848960e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806109e357506109e282611d7c565b5b9050919050565b60606109f4611e0e565b6002018054610a0290614193565b80601f0160208091040260200160405190810160405280929190818152602001828054610a2e90614193565b8015610a7b5780601f10610a5057610100808354040283529160200191610a7b565b820191906000526020600020905b815481529060010190602001808311610a5e57829003601f168201915b5050505050905090565b6000610a9082611e3b565b610ac6576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ace611e0e565b600601600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6068602052816000526040600020602052806000526040600020600091509150505481565b610b3e82826001611eac565b5050565b606d60019054906101000a900460ff16610b91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b8890614210565b60405180910390fd5b606c54341015610bd6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bcd9061427c565b60405180910390fd5b606b54606e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410610c59576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c50906142e8565b60405180910390fd5b6001606e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610ca9336001612001565b565b6000610cb561200f565b610cbd611e0e565b60010154610cc9611e0e565b600001540303905090565b610cdc612018565b80606d60016101000a81548160ff02191690831515021790555050565b606d60009054906101000a900460ff16610d48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3f90614354565b60405180910390fd5b6000606f60008381526020019081526020016000205414610d9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d95906143c0565b60405180910390fd5b610da9838383612096565b505050565b610db781611e3b565b610df6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ded9061442c565b60405180910390fd5b610dff816120ee565b50565b60676020528160005260406000206020528060005260406000206000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610e4c612018565b6000479050600033905060008173ffffffffffffffffffffffffffffffffffffffff1683604051610e7c9061447d565b60006040518083038185875af1925050503d8060008114610eb9576040519150601f19603f3d011682016040523d82523d6000602084013e610ebe565b606091505b50508091505080610f04576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610efb906144de565b60405180910390fd5b505050565b610f1281611e3b565b610f51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f489061442c565b60405180910390fd5b610f5a8161235a565b50565b610f7883838360405180602001604052806000815250611a88565b505050565b606d60019054906101000a900460ff1681565b606b5481565b610f9e612018565b80606d60006101000a81548160ff02191690831515021790555050565b610fc3612018565b818160699182610fd49291906146b5565b505050565b610fe281611117565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461104f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611046906147d1565b60405180910390fd5b6000606f600083815260200190815260200160002054146110a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161109c9061483d565b60405180910390fd5b6000606f60008381526020019081526020016000205490506000606f6000848152602001908152602001600020819055507fc1e00202ee2c06861d326fc6374026b751863ff64218ccbaa38c3e603a8e72c28233834260405161110b949392919061485d565b60405180910390a15050565b600061112282612735565b9050919050565b60666020528060005260406000206000915090505481565b606c5481565b6069805461115490614193565b80601f016020809104026020016040519081016040528092919081815260200182805461118090614193565b80156111cd5780601f106111a2576101008083540402835291602001916111cd565b820191906000526020600020905b8154815290600101906020018083116111b057829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361123c576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff61124d611e0e565b60050160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b61129e612018565b6112a86000612848565b565b6000806066600084815260200190815260200160002054149050919050565b6112d161290e565b60000160019054906101000a900460ff16611305576112ee61290e565b60000160009054906101000a900460ff161561130e565b61130d61293b565b5b61134d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134490614914565b60405180910390fd5b600061135761290e565b60000160019054906101000a900460ff1615905080156113ba57600161137b61290e565b60000160016101000a81548160ff021916908315150217905550600161139f61290e565b60000160006101000a81548160ff0219169083151502179055505b60008060019054906101000a900460ff161590508080156113eb5750600160008054906101000a900460ff1660ff16105b8061141857506113fa30612952565b1580156114175750600160008054906101000a900460ff1660ff16145b5b611457576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161144e906149a6565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015611494576001600060016101000a81548160ff0219169083151502179055505b6115086040518060400160405280601581526020017f546f6b656e2052756e20426174746c65205061737300000000000000000000008152506040518060400160405280600481526020017f5041535300000000000000000000000000000000000000000000000000000000815250612975565b836069908161151791906149c6565b506000606d60006101000a81548160ff0219169083151502179055506000606d60016101000a81548160ff0219169083151502179055506001606b8190555082606c8190555080156115b65760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516115ad9190614ae0565b60405180910390a15b5080156115e25760006115c761290e565b60000160016101000a81548160ff0219169083151502179055505b505050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61161a82611e3b565b611659576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116509061442c565b60405180910390fd5b61166382826129da565b5050565b6060611671611e0e565b600301805461167f90614193565b80601f01602080910402602001604051908101604052809291908181526020018280546116ab90614193565b80156116f85780601f106116cd576101008083540402835291602001916116f8565b820191906000526020600020905b8154815290600101906020018083116116db57829003601f168201915b5050505050905090565b8061170b611e0e565b6007016000611718612db7565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166117c5612db7565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161180a91906138da565b60405180910390a35050565b61181f81611117565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461188c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611883906147d1565b60405180910390fd5b6000606f600083815260200190815260200160002054146118e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118d99061483d565b60405180910390fd5b42606f6000838152602001908152602001600020819055507f02567b2553aeb44e4ddd5d68462774dc3de158cb0f2c2da1740e729b22086aff8133606f60008581526020019081526020016000205460405161194093929190614afb565b60405180910390a150565b611953612018565b81819050848490501461199b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161199290614b7e565b60405180910390fd5b60005b84849050811015611a61578282828181106119bc576119bb614b9e565b5b90506020020160208101906119d19190613b68565b606560008787858181106119e8576119e7614b9e565b5b90506020020160208101906119fd9190613cda565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508080611a5990614bfc565b91505061199e565b5050505050565b60656020528060005260406000206000915054906101000a900460ff1681565b606d60009054906101000a900460ff16611ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ace90614354565b60405180910390fd5b6000606f60008481526020019081526020016000205414611b2d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b24906143c0565b60405180910390fd5b611b3984848484612dbf565b50505050565b6060611b4a82611e3b565b611b89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b8090614c90565b60405180910390fd5b60698054611b9690614193565b80601f0160208091040260200160405190810160405280929190818152602001828054611bc290614193565b8015611c0f5780601f10611be457610100808354040283529160200191611c0f565b820191906000526020600020905b815481529060010190602001808311611bf257829003601f168201915b50505050509050919050565b606a5481565b611c29612018565b611c338282612001565b5050565b6000611c41611e0e565b60070160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606d60009054906101000a900460ff1681565b611cef612018565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611d5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d5590614d22565b60405180910390fd5b611d6781612848565b50565b611d72612018565b80606c8190555050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611dd757506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611e075750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6000807f2569078dfb4b0305704d3008e7403993ae9601b85f7ae5e742de3de8f8011c4090508091505090565b600081611e4661200f565b11158015611e5e5750611e57611e0e565b6000015482105b8015611ea5575060007c0100000000000000000000000000000000000000000000000000000000611e8d611e0e565b60040160008581526020019081526020016000205416145b9050919050565b6000611eb783611117565b90508115611f42578073ffffffffffffffffffffffffffffffffffffffff16611ede612db7565b73ffffffffffffffffffffffffffffffffffffffff1614611f4157611f0a81611f05612db7565b611c37565b611f40576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b83611f4b611e0e565b600601600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b61200b8282612e19565b5050565b60006001905090565b612020612ff9565b73ffffffffffffffffffffffffffffffffffffffff1661203e6115e7565b73ffffffffffffffffffffffffffffffffffffffff1614612094576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161208b90614d8e565b60405180910390fd5b565b61209f816112aa565b6120de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120d590614dfa565b60405180910390fd5b6120e9838383613001565b505050565b606560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661217a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161217190614e66565b60405180910390fd5b60006068600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541461220d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161220490614ed2565b60405180910390fd5b60006001606660008481526020019081526020016000205461222f9190614ef2565b90503360676000848152602001908152602001600020600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806068600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060666000838152602001908152602001600020600081548092919061230d90614bfc565b91905055503373ffffffffffffffffffffffffffffffffffffffff16827f9ecfd70e9ff36df72989324a49559383d39f9290d700b10cf5ac10dcb68d264360405160405180910390a35050565b606560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166123e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123dd90614e66565b60405180910390fd5b60006068600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000810361247e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161247590614f72565b60405180910390fd5b60006066600084815260200190815260200160002054905080821461260857600060676000858152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060676000868152602001908152602001600020600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060676000868152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826068600086815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505061266d565b600060676000858152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006068600085815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506066600084815260200190815260200160002060008154809291906126e790614f92565b91905055503373ffffffffffffffffffffffffffffffffffffffff16837f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3760405160405180910390a3505050565b60008161274061200f565b116128115761274d611e0e565b600401600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603612810576000810361280b5761279b611e0e565b6000015482106127d7576040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b6127e0611e0e565b60040160008360019003935083815260200190815260200160002054905060008103612843576127d8565b612843565b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000807fee151c8401928dc223602bb187aff91b9a56c7cae5476ef1b3287b085a16c85f90508091505090565b6000803090506000813b9050600081149250505090565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff166129c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129bb9061502d565b60405180910390fd5b6129ce8282613359565b6129d66133bf565b5050565b606560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612a67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a5e90614e66565b60405180910390fd5b60006068600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008103612aff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612af690615099565b60405180910390fd5b600060666000858152602001908152602001600020549050808214612c8957600060676000868152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508060676000878152602001908152602001600020600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060676000878152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826068600087815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050612cee565b600060676000868152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b60006068600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550606660008581526020019081526020016000206000815480929190612d6890614f92565b91905055508273ffffffffffffffffffffffffffffffffffffffff16847f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3760405160405180910390a350505050565b600033905090565b612dc8826112aa565b612e07576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dfe90614dfa565b60405180910390fd5b612e1384848484613418565b50505050565b6000612e23611e0e565b60000154905060008203612e63576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e70600084838561348b565b600160406001901b178202612e83611e0e565b60050160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612ef083612ee16000866000613491565b612eea856134b9565b176134c9565b612ef8611e0e565b600401600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114612f9a57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612f5f565b5060008203612fd5576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80612fde611e0e565b600001819055505050612ff460008483856134f4565b505050565b600033905090565b600061300c82612735565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613073576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061307f846134fa565b915091506130958187613090612db7565b61352a565b6130e1576130aa866130a5612db7565b611c37565b6130e0576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603613147576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613154868686600161348b565b801561315f57600082555b613167611e0e565b60050160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460019003919050819055506131be611e0e565b60050160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001019190508190555061323f8561321b888887613491565b7c0200000000000000000000000000000000000000000000000000000000176134c9565b613247611e0e565b60040160008681526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008416036132e95760006001850190506000613298611e0e565b600401600083815260200190815260200160002054036132e7576132ba611e0e565b6000015481146132e657836132cd611e0e565b6004016000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461335186868660016134f4565b505050505050565b61336161290e565b60000160019054906101000a900460ff166133b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133a89061512b565b60405180910390fd5b6133bb828261356e565b5050565b600060019054906101000a900460ff1661340e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134059061502d565b60405180910390fd5b613416613613565b565b613423848484610cf9565b60008373ffffffffffffffffffffffffffffffffffffffff163b146134855761344e8484848461366c565b613484576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b50505050565b60008060e883901c905060e86134a88686846137bc565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6000806000613507611e0e565b600601600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b61357661290e565b60000160019054906101000a900460ff166135c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135bd9061512b565b60405180910390fd5b816135cf611e0e565b60020190816135de91906149c6565b50806135e8611e0e565b60030190816135f791906149c6565b5061360061200f565b613608611e0e565b600001819055505050565b600060019054906101000a900460ff16613662576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136599061502d565b60405180910390fd5b61366a6137c5565b565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613692612db7565b8786866040518563ffffffff1660e01b81526004016136b494939291906151a0565b6020604051808303816000875af19250505080156136f057506040513d601f19601f820116820180604052508101906136ed9190615201565b60015b613769573d8060008114613720576040519150601f19603f3d011682016040523d82523d6000602084013e613725565b606091505b506000815103613761576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60009392505050565b600060019054906101000a900460ff16613814576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161380b9061502d565b60405180910390fd5b61382461381f612ff9565b612848565b565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61386f8161383a565b811461387a57600080fd5b50565b60008135905061388c81613866565b92915050565b6000602082840312156138a8576138a7613830565b5b60006138b68482850161387d565b91505092915050565b60008115159050919050565b6138d4816138bf565b82525050565b60006020820190506138ef60008301846138cb565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561392f578082015181840152602081019050613914565b60008484015250505050565b6000601f19601f8301169050919050565b6000613957826138f5565b6139618185613900565b9350613971818560208601613911565b61397a8161393b565b840191505092915050565b6000602082019050818103600083015261399f818461394c565b905092915050565b6000819050919050565b6139ba816139a7565b81146139c557600080fd5b50565b6000813590506139d7816139b1565b92915050565b6000602082840312156139f3576139f2613830565b5b6000613a01848285016139c8565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613a3582613a0a565b9050919050565b613a4581613a2a565b82525050565b6000602082019050613a606000830184613a3c565b92915050565b613a6f81613a2a565b8114613a7a57600080fd5b50565b600081359050613a8c81613a66565b92915050565b60008060408385031215613aa957613aa8613830565b5b6000613ab7858286016139c8565b9250506020613ac885828601613a7d565b9150509250929050565b613adb816139a7565b82525050565b6000602082019050613af66000830184613ad2565b92915050565b60008060408385031215613b1357613b12613830565b5b6000613b2185828601613a7d565b9250506020613b32858286016139c8565b9150509250929050565b613b45816138bf565b8114613b5057600080fd5b50565b600081359050613b6281613b3c565b92915050565b600060208284031215613b7e57613b7d613830565b5b6000613b8c84828501613b53565b91505092915050565b600080600060608486031215613bae57613bad613830565b5b6000613bbc86828701613a7d565b9350506020613bcd86828701613a7d565b9250506040613bde868287016139c8565b9150509250925092565b60008060408385031215613bff57613bfe613830565b5b6000613c0d858286016139c8565b9250506020613c1e858286016139c8565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f840112613c4d57613c4c613c28565b5b8235905067ffffffffffffffff811115613c6a57613c69613c2d565b5b602083019150836001820283011115613c8657613c85613c32565b5b9250929050565b60008060208385031215613ca457613ca3613830565b5b600083013567ffffffffffffffff811115613cc257613cc1613835565b5b613cce85828601613c37565b92509250509250929050565b600060208284031215613cf057613cef613830565b5b6000613cfe84828501613a7d565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613d448261393b565b810181811067ffffffffffffffff82111715613d6357613d62613d0c565b5b80604052505050565b6000613d76613826565b9050613d828282613d3b565b919050565b600067ffffffffffffffff821115613da257613da1613d0c565b5b613dab8261393b565b9050602081019050919050565b82818337600083830152505050565b6000613dda613dd584613d87565b613d6c565b905082815260208101848484011115613df657613df5613d07565b5b613e01848285613db8565b509392505050565b600082601f830112613e1e57613e1d613c28565b5b8135613e2e848260208601613dc7565b91505092915050565b60008060408385031215613e4e57613e4d613830565b5b600083013567ffffffffffffffff811115613e6c57613e6b613835565b5b613e7885828601613e09565b9250506020613e89858286016139c8565b9150509250929050565b60008060408385031215613eaa57613ea9613830565b5b6000613eb885828601613a7d565b9250506020613ec985828601613b53565b9150509250929050565b60008083601f840112613ee957613ee8613c28565b5b8235905067ffffffffffffffff811115613f0657613f05613c2d565b5b602083019150836020820283011115613f2257613f21613c32565b5b9250929050565b60008083601f840112613f3f57613f3e613c28565b5b8235905067ffffffffffffffff811115613f5c57613f5b613c2d565b5b602083019150836020820283011115613f7857613f77613c32565b5b9250929050565b60008060008060408587031215613f9957613f98613830565b5b600085013567ffffffffffffffff811115613fb757613fb6613835565b5b613fc387828801613ed3565b9450945050602085013567ffffffffffffffff811115613fe657613fe5613835565b5b613ff287828801613f29565b925092505092959194509250565b600067ffffffffffffffff82111561401b5761401a613d0c565b5b6140248261393b565b9050602081019050919050565b600061404461403f84614000565b613d6c565b9050828152602081018484840111156140605761405f613d07565b5b61406b848285613db8565b509392505050565b600082601f83011261408857614087613c28565b5b8135614098848260208601614031565b91505092915050565b600080600080608085870312156140bb576140ba613830565b5b60006140c987828801613a7d565b94505060206140da87828801613a7d565b93505060406140eb878288016139c8565b925050606085013567ffffffffffffffff81111561410c5761410b613835565b5b61411887828801614073565b91505092959194509250565b6000806040838503121561413b5761413a613830565b5b600061414985828601613a7d565b925050602061415a85828601613a7d565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806141ab57607f821691505b6020821081036141be576141bd614164565b5b50919050565b7f6d696e74206e6f7420656e61626c656400000000000000000000000000000000600082015250565b60006141fa601083613900565b9150614205826141c4565b602082019050919050565b60006020820190508181036000830152614229816141ed565b9050919050565b7f696e73756666696369656e742076616c75650000000000000000000000000000600082015250565b6000614266601283613900565b915061427182614230565b602082019050919050565b6000602082019050818103600083015261429581614259565b9050919050565b7f7265616368656420746865206d6178696d756d00000000000000000000000000600082015250565b60006142d2601383613900565b91506142dd8261429c565b602082019050919050565b60006020820190508181036000830152614301816142c5565b9050919050565b7f7472616e73666572206e6f7420656e61626c6564000000000000000000000000600082015250565b600061433e601483613900565b915061434982614308565b602082019050919050565b6000602082019050818103600083015261436d81614331565b9050919050565b7f43616e6e6f74207472616e73666572207374616b656420746f6b656e00000000600082015250565b60006143aa601c83613900565b91506143b582614374565b602082019050919050565b600060208201905081810360008301526143d98161439d565b9050919050565b7f546f6b656e202165786973740000000000000000000000000000000000000000600082015250565b6000614416600c83613900565b9150614421826143e0565b602082019050919050565b6000602082019050818103600083015261444581614409565b9050919050565b600081905092915050565b50565b600061446760008361444c565b915061447282614457565b600082019050919050565b60006144888261445a565b9150819050919050565b7f5472616e73616374696f6e20556e7375636365737366756c0000000000000000600082015250565b60006144c8601883613900565b91506144d382614492565b602082019050919050565b600060208201905081810360008301526144f7816144bb565b9050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261456b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261452e565b614575868361452e565b95508019841693508086168417925050509392505050565b6000819050919050565b60006145b26145ad6145a8846139a7565b61458d565b6139a7565b9050919050565b6000819050919050565b6145cc83614597565b6145e06145d8826145b9565b84845461453b565b825550505050565b600090565b6145f56145e8565b6146008184846145c3565b505050565b5b81811015614624576146196000826145ed565b600181019050614606565b5050565b601f8211156146695761463a81614509565b6146438461451e565b81016020851015614652578190505b61466661465e8561451e565b830182614605565b50505b505050565b600082821c905092915050565b600061468c6000198460080261466e565b1980831691505092915050565b60006146a5838361467b565b9150826002028217905092915050565b6146bf83836144fe565b67ffffffffffffffff8111156146d8576146d7613d0c565b5b6146e28254614193565b6146ed828285614628565b6000601f83116001811461471c576000841561470a578287013590505b6147148582614699565b86555061477c565b601f19841661472a86614509565b60005b828110156147525784890135825560018201915060208501945060208101905061472d565b8683101561476f578489013561476b601f89168261467b565b8355505b6001600288020188555050505b50505050505050565b7f63616c6c6572206d757374206265206f776e6572000000000000000000000000600082015250565b60006147bb601483613900565b91506147c682614785565b602082019050919050565b600060208201905081810360008301526147ea816147ae565b9050919050565b7f616c7265616479207374616b696e670000000000000000000000000000000000600082015250565b6000614827600f83613900565b9150614832826147f1565b602082019050919050565b600060208201905081810360008301526148568161481a565b9050919050565b60006080820190506148726000830187613ad2565b61487f6020830186613a3c565b61488c6040830185613ad2565b6148996060830184613ad2565b95945050505050565b7f455243373231415f5f496e697469616c697a61626c653a20636f6e747261637460008201527f20697320616c726561647920696e697469616c697a6564000000000000000000602082015250565b60006148fe603783613900565b9150614909826148a2565b604082019050919050565b6000602082019050818103600083015261492d816148f1565b9050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b6000614990602e83613900565b915061499b82614934565b604082019050919050565b600060208201905081810360008301526149bf81614983565b9050919050565b6149cf826138f5565b67ffffffffffffffff8111156149e8576149e7613d0c565b5b6149f28254614193565b6149fd828285614628565b600060209050601f831160018114614a305760008415614a1e578287015190505b614a288582614699565b865550614a90565b601f198416614a3e86614509565b60005b82811015614a6657848901518255600182019150602085019450602081019050614a41565b86831015614a835784890151614a7f601f89168261467b565b8355505b6001600288020188555050505b505050505050565b6000819050919050565b600060ff82169050919050565b6000614aca614ac5614ac084614a98565b61458d565b614aa2565b9050919050565b614ada81614aaf565b82525050565b6000602082019050614af56000830184614ad1565b92915050565b6000606082019050614b106000830186613ad2565b614b1d6020830185613a3c565b614b2a6040830184613ad2565b949350505050565b7f216c656e67746800000000000000000000000000000000000000000000000000600082015250565b6000614b68600783613900565b9150614b7382614b32565b602082019050919050565b60006020820190508181036000830152614b9781614b5b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614c07826139a7565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614c3957614c38614bcd565b5b600182019050919050565b7f544f4b454e204e4f542045584953540000000000000000000000000000000000600082015250565b6000614c7a600f83613900565b9150614c8582614c44565b602082019050919050565b60006020820190508181036000830152614ca981614c6d565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614d0c602683613900565b9150614d1782614cb0565b604082019050919050565b60006020820190508181036000830152614d3b81614cff565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614d78602083613900565b9150614d8382614d42565b602082019050919050565b60006020820190508181036000830152614da781614d6b565b9050919050565b7f546f6b656e206973206c6f636b65640000000000000000000000000000000000600082015250565b6000614de4600f83613900565b9150614def82614dae565b602082019050919050565b60006020820190508181036000830152614e1381614dd7565b9050919050565b7f43616e6e6f7420757064617465206d6170000000000000000000000000000000600082015250565b6000614e50601183613900565b9150614e5b82614e1a565b602082019050919050565b60006020820190508181036000830152614e7f81614e43565b9050919050565b7f494420616c7265616479206c6f636b65642062792063616c6c65720000000000600082015250565b6000614ebc601b83613900565b9150614ec782614e86565b602082019050919050565b60006020820190508181036000830152614eeb81614eaf565b9050919050565b6000614efd826139a7565b9150614f08836139a7565b9250828201905080821115614f2057614f1f614bcd565b5b92915050565b7f4944206e6f74206c6f636b65642062792063616c6c6572000000000000000000600082015250565b6000614f5c601783613900565b9150614f6782614f26565b602082019050919050565b60006020820190508181036000830152614f8b81614f4f565b9050919050565b6000614f9d826139a7565b915060008203614fb057614faf614bcd565b5b600182039050919050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b6000615017602b83613900565b915061502282614fbb565b604082019050919050565b600060208201905081810360008301526150468161500a565b9050919050565b7f4944206e6f74206c6f636b656400000000000000000000000000000000000000600082015250565b6000615083600d83613900565b915061508e8261504d565b602082019050919050565b600060208201905081810360008301526150b281615076565b9050919050565b7f455243373231415f5f496e697469616c697a61626c653a20636f6e747261637460008201527f206973206e6f7420696e697469616c697a696e67000000000000000000000000602082015250565b6000615115603483613900565b9150615120826150b9565b604082019050919050565b6000602082019050818103600083015261514481615108565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006151728261514b565b61517c8185615156565b935061518c818560208601613911565b6151958161393b565b840191505092915050565b60006080820190506151b56000830187613a3c565b6151c26020830186613a3c565b6151cf6040830185613ad2565b81810360608301526151e18184615167565b905095945050505050565b6000815190506151fb81613866565b92915050565b60006020828403121561521757615216613830565b5b6000615225848285016151ec565b9150509291505056fea26469706673582212207aa42ed34c05c31bc63088a295d18c860b3da493e3e0cb66675971fd0a27131264736f6c63430008120033
Deployed Bytecode Sourcemap
135092:4310:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85847:292;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50346:124;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56938:242;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22861:94;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56655:124;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;136163:310;;;:::i;:::-;;45831:371;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;137366:103;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;138325:367;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;86777:134;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;22783:71;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;139119:278;;;;;;;;;;;;;:::i;:::-;;86919:138;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;63801:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;135301:22;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135197:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;137477:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;137089:94;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;137937:380;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51787:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22723:53;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135231:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135138:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47111:257;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21384:103;;;;;;;;;;;;;:::i;:::-;;23303:114;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135690:338;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;20743:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87065:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;50546:128;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57520:258;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;137606:323;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;23425;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;22659:57;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;138700:411;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;136870:211;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135166:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;136036:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57935:188;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;135268:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21642:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;137264:94;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;85847:292;85998:4;85590:10;86056:21;;86040:37;;;:12;:37;;;;:91;;;;86094:37;86118:12;86094:23;:37::i;:::-;86040:91;86020:111;;85847:292;;;:::o;50346:124::-;50400:13;50433:23;:21;:23::i;:::-;:29;;50426:36;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50346:124;:::o;56938:242::-;57014:7;57039:16;57047:7;57039;:16::i;:::-;57034:64;;57064:34;;;;;;;;;;;;;;57034:64;57118:23;:21;:23::i;:::-;:39;;:48;57158:7;57118:48;;;;;;;;;;;:54;;;;;;;;;;;;57111:61;;56938:242;;;:::o;22861:94::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;56655:124::-;56744:27;56753:2;56757:7;56766:4;56744:8;:27::i;:::-;56655:124;;:::o;136163:310::-;136213:10;;;;;;;;;;;136205:39;;;;;;;;;;;;:::i;:::-;;;;;;;;;136276:9;;136263;:22;;136255:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;136350:12;;136327:8;:20;136336:10;136327:20;;;;;;;;;;;;;;;;:35;136319:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;136430:1;136407:8;:20;136416:10;136407:20;;;;;;;;;;;;;;;:24;;;;136442:23;136451:10;136463:1;136442:8;:23::i;:::-;136163:310::o;45831:371::-;45892:7;46168:15;:13;:15::i;:::-;46129:23;:21;:23::i;:::-;:36;;;46089:23;:21;:23::i;:::-;:37;;;:76;:94;46082:101;;45831:371;:::o;137366:103::-;20629:13;:11;:13::i;:::-;137450:11:::1;137437:10;;:24;;;;;;;;;;;;;;;;;;137366:103:::0;:::o;138325:367::-;138476:14;;;;;;;;;;;138468:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;138579:1;138548:18;:27;138567:7;138548:27;;;;;;;;;;;;:32;138526:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;138647:37;138666:4;138672:2;138676:7;138647:18;:37::i;:::-;138325:367;;;:::o;86777:134::-;86851:12;86859:3;86851:7;:12::i;:::-;86843:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;86891:12;86899:3;86891:7;:12::i;:::-;86777:134;:::o;22783:71::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;139119:278::-;20629:13;:11;:13::i;:::-;139167:18:::1;139188:21;139167:42;;139222:9;139242:10;139222:31;;139266:12;139305:1;:6;;139319:10;139305:29;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;139291:43;;;;;139353:7;139345:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;139156:241;;;139119:278::o:0;86919:138::-;86995:12;87003:3;86995:7;:12::i;:::-;86987:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;87035:14;87045:3;87035:9;:14::i;:::-;86919:138;:::o;63801:193::-;63947:39;63964:4;63970:2;63974:7;63947:39;;;;;;;;;;;;:16;:39::i;:::-;63801:193;;;:::o;135301:22::-;;;;;;;;;;;;;:::o;135197:27::-;;;;:::o;137477:119::-;20629:13;:11;:13::i;:::-;137573:15:::1;137556:14;;:32;;;;;;;;;;;;;;;;;;137477:119:::0;:::o;137089:94::-;20629:13;:11;:13::i;:::-;137171:4:::1;;137161:7;:14;;;;;;;:::i;:::-;;137089:94:::0;;:::o;137937:380::-;138013:16;138021:7;138013;:16::i;:::-;137999:30;;:10;:30;;;137991:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;138104:1;138073:18;:27;138092:7;138073:27;;;;;;;;;;;;:32;138065:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;138138:22;138163:18;:27;138182:7;138163:27;;;;;;;;;;;;138138:52;;138231:1;138201:18;:27;138220:7;138201:27;;;;;;;;;;;:31;;;;138248:61;138256:7;138265:10;138277:14;138293:15;138248:61;;;;;;;;;:::i;:::-;;;;;;;;137980:337;137937:380;:::o;51787:152::-;51859:7;51902:27;51921:7;51902:18;:27::i;:::-;51879:52;;51787:152;;;:::o;22723:53::-;;;;;;;;;;;;;;;;;:::o;135231:24::-;;;;:::o;135138:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;47111:257::-;47183:7;47224:1;47207:19;;:5;:19;;;47203:60;;47235:28;;;;;;;;;;;;;;47203:60;42259:13;47281:23;:21;:23::i;:::-;:42;;:49;47324:5;47281:49;;;;;;;;;;;;;;;;:79;47274:86;;47111:257;;;:::o;21384:103::-;20629:13;:11;:13::i;:::-;21449:30:::1;21476:1;21449:18;:30::i;:::-;21384:103::o:0;23303:114::-;23366:4;23408:1;23390:9;:14;23400:3;23390:14;;;;;;;;;;;;:19;23383:26;;23303:114;;;:::o;135690:338::-;28047:38;:36;:38::i;:::-;:52;;;;;;;;;;;;:160;;28156:38;:36;:38::i;:::-;:51;;;;;;;;;;;;28155:52;28047:160;;;28119:16;:14;:16::i;:::-;28047:160;28025:265;;;;;;;;;;;;:::i;:::-;;;;;;;;;28303:19;28326:38;:36;:38::i;:::-;:52;;;;;;;;;;;;28325:53;28303:75;;28393:14;28389:179;;;28479:4;28424:38;:36;:38::i;:::-;:52;;;:59;;;;;;;;;;;;;;;;;;28552:4;28498:38;:36;:38::i;:::-;:51;;;:58;;;;;;;;;;;;;;;;;;28389:179;14459:19:::1;14482:13:::0;::::1;;;;;;;;;;14481:14;14459:36;;14529:14;:34;;;;;14562:1;14547:12;::::0;::::1;;;;;;;;:16;;;14529:34;14528:108;;;;14570:44;14608:4;14570:29;:44::i;:::-;14569:45;:66;;;;;14634:1;14618:12;::::0;::::1;;;;;;;;:17;;;14569:66;14528:108;14506:204;;;;;;;;;;;;:::i;:::-;;;;;;;;;14736:1;14721:12;::::0;:16:::1;;;;;;;;;;;;;;;;;;14752:14;14748:67;;;14799:4;14783:13;;:20;;;;;;;;;;;;;;;;;;14748:67;135824:47:::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;::::0;:14:::2;:47::i;:::-;135894:4;135884:7;:14;;;;;;:::i;:::-;;135926:5;135909:14;;:22;;;;;;;;;;;;;;;;;;135955:5;135942:10;;:18;;;;;;;;;;;;;;;;;;135986:1;135971:12;:16;;;;136010:10;135998:9;:22;;;;14841:14:::1;14837:102;;;14888:5;14872:13:::0;::::1;:21;;;;;;;;;;;;;;;;;;14913:14;14925:1;14913:14;;;;;;:::i;:::-;;;;;;;;14837:102;14448:498;28598:14:::0;28594:107;;;28684:5;28629:38;:36;:38::i;:::-;:52;;;:60;;;;;;;;;;;;;;;;;;28594:107;27740:968;135690:338;;:::o;20743:87::-;20789:7;20816:6;;;;;;;;;;;20809:13;;20743:87;:::o;87065:164::-;87158:12;87166:3;87158:7;:12::i;:::-;87150:37;;;;;;;;;;;;:::i;:::-;;;;;;;;;87198:23;87206:3;87211:9;87198:7;:23::i;:::-;87065:164;;:::o;50546:128::-;50602:13;50635:23;:21;:23::i;:::-;:31;;50628:38;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50546:128;:::o;57520:258::-;57691:8;57615:23;:21;:23::i;:::-;:42;;:63;57658:19;:17;:19::i;:::-;57615:63;;;;;;;;;;;;;;;:73;57679:8;57615:73;;;;;;;;;;;;;;;;:84;;;;;;;;;;;;;;;;;;57751:8;57715:55;;57730:19;:17;:19::i;:::-;57715:55;;;57761:8;57715:55;;;;;;:::i;:::-;;;;;;;;57520:258;;:::o;137606:323::-;137680:16;137688:7;137680;:16::i;:::-;137666:30;;:10;:30;;;137658:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;137771:1;137740:18;:27;137759:7;137740:27;;;;;;;;;;;;:32;137732:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;137835:15;137805:18;:27;137824:7;137805:27;;;;;;;;;;;:45;;;;137866:55;137872:7;137881:10;137893:18;:27;137912:7;137893:27;;;;;;;;;;;;137866:55;;;;;;;;:::i;:::-;;;;;;;;137606:323;:::o;23425:::-;20629:13;:11;:13::i;:::-;23598:7:::1;;:14;;23577:10;;:17;;:35;23569:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;23640:9;23635:105;23659:10;;:17;;23655:1;:21;23635:105;;;23730:7;;23738:1;23730:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;23696:16;:31;23713:10;;23724:1;23713:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;23696:31;;;;;;;;;;;;;;;;:44;;;;;;;;;;;;;;;;;;23678:3;;;;;:::i;:::-;;;;23635:105;;;;23425:323:::0;;;;:::o;22659:57::-;;;;;;;;;;;;;;;;;;;;;;:::o;138700:411::-;138884:14;;;;;;;;;;;138876:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;138987:1;138956:18;:27;138975:7;138956:27;;;;;;;;;;;;:32;138934:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;139055:48;139078:4;139084:2;139088:7;139097:5;139055:22;:48::i;:::-;138700:411;;;;:::o;136870:211::-;136972:13;137011:17;137019:8;137011:7;:17::i;:::-;137003:45;;;;;;;;;;;;:::i;:::-;;;;;;;;;137066:7;137059:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;136870:211;;;:::o;135166:24::-;;;;:::o;136036:119::-;20629:13;:11;:13::i;:::-;136119:28:::1;136128:8;136138;136119;:28::i;:::-;136036:119:::0;;:::o;57935:188::-;58032:4;58056:23;:21;:23::i;:::-;:42;;:49;58099:5;58056:49;;;;;;;;;;;;;;;:59;58106:8;58056:59;;;;;;;;;;;;;;;;;;;;;;;;;58049:66;;57935:188;;;;:::o;135268:26::-;;;;;;;;;;;;;:::o;21642:201::-;20629:13;:11;:13::i;:::-;21751:1:::1;21731:22;;:8;:22;;::::0;21723:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;21807:28;21826:8;21807:18;:28::i;:::-;21642:201:::0;:::o;137264:94::-;20629:13;:11;:13::i;:::-;137344:6:::1;137332:9;:18;;;;137264:94:::0;:::o;49444:639::-;49529:4;49868:10;49853:25;;:11;:25;;;;:102;;;;49945:10;49930:25;;:11;:25;;;;49853:102;:179;;;;50022:10;50007:25;;:11;:25;;;;49853:179;49833:199;;49444:639;;;:::o;31665:164::-;31706:16;31735:12;31610:46;31735:27;;31807:4;31797:14;;31782:40;31665:164;:::o;58381:330::-;58446:4;58502:7;58483:15;:13;:15::i;:::-;:26;;:90;;;;;58536:23;:21;:23::i;:::-;:37;;;58526:7;:47;58483:90;:201;;;;;58683:1;43035:8;58611:23;:21;:23::i;:::-;:41;;:50;58653:7;58611:50;;;;;;;;;;;;:68;:73;58483:201;58463:221;;58381:330;;;:::o;75930:516::-;76059:13;76075:16;76083:7;76075;:16::i;:::-;76059:32;;76108:13;76104:219;;;76163:5;76140:28;;:19;:17;:19::i;:::-;:28;;;76136:187;;76192:44;76209:5;76216:19;:17;:19::i;:::-;76192:16;:44::i;:::-;76187:136;;76268:35;;;;;;;;;;;;;;76187:136;76136:187;76104:219;76392:2;76335:23;:21;:23::i;:::-;:39;;:48;76375:7;76335:48;;;;;;;;;;;:54;;;:59;;;;;;;;;;;;;;;;;;76430:7;76426:2;76410:28;;76419:5;76410:28;;;;;;;;;;;;76048:398;75930:516;;;:::o;136481:107::-;136555:25;136561:8;136571;136555:5;:25::i;:::-;136481:107;;:::o;136645:101::-;136710:7;136737:1;136730:8;;136645:101;:::o;20908:132::-;20983:12;:10;:12::i;:::-;20972:23;;:7;:5;:7::i;:::-;:23;;;20964:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;20908:132::o;86147:285::-;86320:20;86331:8;86320:10;:20::i;:::-;86312:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;86371:53;86403:5;86410:3;86415:8;86371:31;:53::i;:::-;86147:285;;;:::o;23756:447::-;23814:16;:28;23831:10;23814:28;;;;;;;;;;;;;;;;;;;;;;;;;23806:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;23930:1;23897:12;:17;23910:3;23897:17;;;;;;;;;;;:29;23915:10;23897:29;;;;;;;;;;;;;;;;:34;23875:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;23999:13;24032:1;24015:9;:14;24025:3;24015:14;;;;;;;;;;;;:18;;;;:::i;:::-;23999:34;;24066:10;24044:7;:12;24052:3;24044:12;;;;;;;;;;;:19;24057:5;24044:19;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;24119:5;24087:12;:17;24100:3;24087:17;;;;;;;;;;;:29;24105:10;24087:29;;;;;;;;;;;;;;;:37;;;;24135:9;:14;24145:3;24135:14;;;;;;;;;;;;:16;;;;;;;;;:::i;:::-;;;;;;24184:10;24167:28;;24179:3;24167:28;;;;;;;;;;23795:408;23756:447;:::o;24211:675::-;24271:16;:28;24288:10;24271:28;;;;;;;;;;;;;;;;;;;;;;;;;24263:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;24332:13;24348:12;:17;24361:3;24348:17;;;;;;;;;;;:29;24366:10;24348:29;;;;;;;;;;;;;;;;24332:45;;24405:1;24396:5;:10;24388:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;24447:12;24462:9;:14;24472:3;24462:14;;;;;;;;;;;;24447:29;;24500:4;24491:5;:13;24487:274;;24521:20;24544:7;:12;24552:3;24544:12;;;;;;;;;;;:18;24557:4;24544:18;;;;;;;;;;;;;;;;;;;;;24521:41;;24599:12;24577:7;:12;24585:3;24577:12;;;;;;;;;;;:19;24590:5;24577:19;;;;;;;;;;;;:34;;;;;;;;;;;;;;;;;;24655:1;24626:7;:12;24634:3;24626:12;;;;;;;;;;;:18;24639:4;24626:18;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;24706:5;24672:12;:17;24685:3;24672:17;;;;;;;;;;;:31;24690:12;24672:31;;;;;;;;;;;;;;;:39;;;;24506:217;24487:274;;;24759:1;24729:7;:12;24737:3;24729:12;;;;;;;;;;;:19;24742:5;24729:19;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;24487:274;24804:1;24772:12;:17;24785:3;24772:17;;;;;;;;;;;:29;24790:10;24772:29;;;;;;;;;;;;;;;:33;;;;24816:9;:14;24826:3;24816:14;;;;;;;;;;;;:16;;;;;;;;;:::i;:::-;;;;;;24867:10;24848:30;;24862:3;24848:30;;;;;;;;;;24252:634;;24211:675;:::o;53014:1784::-;53081:14;53131:7;53112:15;:13;:15::i;:::-;:26;53108:1634;;53164:23;:21;:23::i;:::-;:41;;:50;53206:7;53164:50;;;;;;;;;;;;53155:59;;53292:1;43035:8;53264:6;:24;:29;53260:1471;;53413:1;53403:6;:11;53399:1029;;53454:23;:21;:23::i;:::-;:37;;;53443:7;:48;53439:92;;53500:31;;;;;;;;;;;;;;53439:92;54128:281;54214:23;:21;:23::i;:::-;:41;;:52;54256:9;;;;;;;54214:52;;;;;;;;;;;;54205:61;;54334:1;54324:6;:11;54372:13;54320:25;54128:281;;53399:1029;54702:13;;53260:1471;53108:1634;54759:31;;;;;;;;;;;;;;53014:1784;;;;:::o;22003:191::-;22077:16;22096:6;;;;;;;;;;;22077:25;;22122:8;22113:6;;:17;;;;;;;;;;;;;;;;;;22177:8;22146:40;;22167:8;22146:40;;;;;;;;;;;;22066:128;22003:191;:::o;26235:164::-;26276:16;26305:12;26168:58;26305:27;;26377:4;26367:14;;26352:40;26235:164;:::o;29216:569::-;29264:4;29635:12;29658:4;29635:28;;29674:10;29737:4;29725:17;29719:23;;29776:1;29770:2;:7;29763:14;;;;29216:569;:::o;2936:326::-;2996:4;3253:1;3231:7;:19;;;:23;3224:30;;2936:326;;;:::o;85609:230::-;16602:13;;;;;;;;;;;16594:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;85737:49:::1;85771:5;85778:7;85737:33;:49::i;:::-;85797:34;:32;:34::i;:::-;85609:230:::0;;:::o;24894:679::-;24972:16;:27;24989:9;24972:27;;;;;;;;;;;;;;;;;;;;;;;;;24971:28;24963:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;25032:13;25048:12;:17;25061:3;25048:17;;;;;;;;;;;:28;25066:9;25048:28;;;;;;;;;;;;;;;;25032:44;;25104:1;25095:5;:10;25087:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;25136:12;25151:9;:14;25161:3;25151:14;;;;;;;;;;;;25136:29;;25189:4;25180:5;:13;25176:274;;25210:20;25233:7;:12;25241:3;25233:12;;;;;;;;;;;:18;25246:4;25233:18;;;;;;;;;;;;;;;;;;;;;25210:41;;25288:12;25266:7;:12;25274:3;25266:12;;;;;;;;;;;:19;25279:5;25266:19;;;;;;;;;;;;:34;;;;;;;;;;;;;;;;;;25344:1;25315:7;:12;25323:3;25315:12;;;;;;;;;;;:18;25328:4;25315:18;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;25395:5;25361:12;:17;25374:3;25361:17;;;;;;;;;;;:31;25379:12;25361:31;;;;;;;;;;;;;;;:39;;;;25195:217;25176:274;;;25448:1;25418:7;:12;25426:3;25418:12;;;;;;;;;;;:19;25431:5;25418:19;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;25176:274;25492:1;25461:12;:17;25474:3;25461:17;;;;;;;;;;;:28;25479:9;25461:28;;;;;;;;;;;;;;;:32;;;;25504:9;:14;25514:3;25504:14;;;;;;;;;;;;:16;;;;;;;;;:::i;:::-;;;;;;25555:9;25536:29;;25550:3;25536:29;;;;;;;;;;24952:621;;24894:679;;:::o;82694:105::-;82754:7;82781:10;82774:17;;82694:105;:::o;86440:329::-;86646:20;86657:8;86646:10;:20::i;:::-;86638:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;86697:64;86733:5;86740:3;86745:8;86755:5;86697:35;:64::i;:::-;86440:329;;;;:::o;68281:3062::-;68354:20;68377:23;:21;:23::i;:::-;:37;;;68354:60;;68441:1;68429:8;:13;68425:44;;68451:18;;;;;;;;;;;;;;68425:44;68482:61;68512:1;68516:2;68520:12;68534:8;68482:21;:61::i;:::-;69050:1;42397:2;69020:1;:26;;69019:32;69007:8;:45;68957:23;:21;:23::i;:::-;:42;;:46;69000:2;68957:46;;;;;;;;;;;;;;;;:95;;;;;;;;;;;69353:139;69390:2;69444:33;69467:1;69471:2;69475:1;69444:14;:33::i;:::-;69411:30;69432:8;69411:20;:30::i;:::-;:66;69353:18;:139::i;:::-;69295:23;:21;:23::i;:::-;:41;;:55;69337:12;69295:55;;;;;;;;;;;:197;;;;69509:16;69540:11;69569:8;69554:12;:23;69540:37;;70090:16;70086:2;70082:25;70070:37;;70462:12;70422:8;70381:1;70319:25;70260:1;70199;70172:335;70833:1;70819:12;70815:20;70773:346;70874:3;70865:7;70862:16;70773:346;;71092:7;71082:8;71079:1;71052:25;71049:1;71046;71041:59;70927:1;70918:7;70914:15;70903:26;;70773:346;;;70777:77;71164:1;71152:8;:13;71148:45;;71174:19;;;;;;;;;;;;;;71148:45;71250:3;71210:23;:21;:23::i;:::-;:37;;:43;;;;68731:2534;;71275:60;71304:1;71308:2;71312:12;71326:8;71275:20;:60::i;:::-;68343:3000;68281:3062;;:::o;18781:98::-;18834:7;18861:10;18854:17;;18781:98;:::o;60736:2969::-;60878:27;60908;60927:7;60908:18;:27::i;:::-;60878:57;;60993:4;60952:45;;60968:19;60952:45;;;60948:86;;61006:28;;;;;;;;;;;;;;60948:86;61048:27;61077:23;61104:35;61131:7;61104:26;:35::i;:::-;61047:92;;;;61239:68;61264:15;61281:4;61287:19;:17;:19::i;:::-;61239:24;:68::i;:::-;61234:180;;61327:43;61344:4;61350:19;:17;:19::i;:::-;61327:16;:43::i;:::-;61322:92;;61379:35;;;;;;;;;;;;;;61322:92;61234:180;61445:1;61431:16;;:2;:16;;;61427:52;;61456:23;;;;;;;;;;;;;;61427:52;61492:43;61514:4;61520:2;61524:7;61533:1;61492:21;:43::i;:::-;61628:15;61625:160;;;61768:1;61747:19;61740:30;61625:160;62165:23;:21;:23::i;:::-;:42;;:48;62208:4;62165:48;;;;;;;;;;;;;;;;62163:50;;;;;;;;;;;;62258:23;:21;:23::i;:::-;:42;;:46;62301:2;62258:46;;;;;;;;;;;;;;;;62256:48;;;;;;;;;;;62628:146;62665:2;62714:45;62729:4;62735:2;62739:19;62714:14;:45::i;:::-;43315:8;62686:73;62628:18;:146::i;:::-;62575:23;:21;:23::i;:::-;:41;;:50;62617:7;62575:50;;;;;;;;;;;:199;;;;62945:1;43315:8;62894:19;:47;:52;62890:699;;62967:19;62999:1;62989:7;:11;62967:33;;63180:1;63122:23;:21;:23::i;:::-;:41;;:54;63164:11;63122:54;;;;;;;;;;;;:59;63118:456;;63284:23;:21;:23::i;:::-;:37;;;63269:11;:52;63265:290;;63512:19;63455:23;:21;:23::i;:::-;:41;;:54;63497:11;63455:54;;;;;;;;;;;:76;;;;63265:290;63118:456;62948:641;62890:699;63636:7;63632:2;63617:27;;63626:4;63617:27;;;;;;;;;;;;63655:42;63676:4;63682:2;63686:7;63695:1;63655:20;:42::i;:::-;60867:2838;;;60736:2969;;;:::o;44534:160::-;28971:38;:36;:38::i;:::-;:52;;;;;;;;;;;;28949:154;;;;;;;;;;;;:::i;:::-;;;;;;;;;44646:40:::1;44671:5;44678:7;44646:24;:40::i;:::-;44534:160:::0;;:::o;23184:111::-;16602:13;;;;;;;;;;;16594:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;23252:35:::1;:33;:35::i;:::-;23184:111::o:0;64592:407::-;64767:31;64780:4;64786:2;64790:7;64767:12;:31::i;:::-;64831:1;64813:2;:14;;;:19;64809:183;;64852:56;64883:4;64889:2;64893:7;64902:5;64852:30;:56::i;:::-;64847:145;;64936:40;;;;;;;;;;;;;;64847:145;64809:183;64592:407;;;;:::o;65661:159::-;;;;;:::o;82003:311::-;82138:7;82158:16;43439:3;82184:19;:41;;82158:68;;43439:3;82252:31;82263:4;82269:2;82273:9;82252:10;:31::i;:::-;82244:40;;:62;;82237:69;;;82003:311;;;;;:::o;55898:324::-;55968:14;56201:1;56191:8;56188:15;56162:24;56158:46;56148:56;;55898:324;;;:::o;55346:450::-;55426:14;55594:16;55587:5;55583:28;55574:37;;55771:5;55757:11;55732:23;55728:41;55725:52;55718:5;55715:63;55705:73;;55346:450;;;;:::o;66485:158::-;;;;;:::o;59592:524::-;59694:27;59723:23;59764:53;59820:23;:21;:23::i;:::-;:39;;:48;59860:7;59820:48;;;;;;;;;;;59764:104;;60021:18;59998:41;;60078:19;60072:26;60053:45;;59983:126;59592:524;;;:::o;58820:659::-;58969:11;59134:16;59127:5;59123:28;59114:37;;59294:16;59283:9;59279:32;59266:45;;59444:15;59433:9;59430:30;59422:5;59411:9;59408:20;59405:56;59395:66;;58820:659;;;;;:::o;44702:285::-;28971:38;:36;:38::i;:::-;:52;;;;;;;;;;;;28949:154;;;;;;;;;;;;:::i;:::-;;;;;;;;;44856:5:::1;44824:23;:21;:23::i;:::-;:29;;:37;;;;;;:::i;:::-;;44906:7;44872:23;:21;:23::i;:::-;:31;;:41;;;;;;:::i;:::-;;44964:15;:13;:15::i;:::-;44924:23;:21;:23::i;:::-;:37;;:55;;;;44702:285:::0;;:::o;20286:97::-;16602:13;;;;;;;;;;;16594:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;20349:26:::1;:24;:26::i;:::-;20286:97::o:0;67083:736::-;67246:4;67316:2;67280:56;;;67337:19;:17;:19::i;:::-;67358:4;67364:7;67373:5;67280:99;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;67263:549;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67587:1;67570:6;:13;:18;67566:235;;67616:40;;;;;;;;;;;;;;67566:235;67759:6;67753:13;67744:6;67740:2;67736:15;67729:38;67263:549;67445:65;;;67435:75;;;:6;:75;;;;67428:82;;;67083:736;;;;;;:::o;81704:147::-;81841:6;81704:147;;;;;:::o;20391:113::-;16602:13;;;;;;;;;;;16594:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;20464:32:::1;20483:12;:10;:12::i;:::-;20464:18;:32::i;:::-;20391: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:117::-;9338:1;9335;9328:12;9352:180;9400:77;9397:1;9390:88;9497:4;9494:1;9487:15;9521:4;9518:1;9511:15;9538:281;9621:27;9643:4;9621:27;:::i;:::-;9613:6;9609:40;9751:6;9739:10;9736:22;9715:18;9703:10;9700:34;9697:62;9694:88;;;9762:18;;:::i;:::-;9694:88;9802:10;9798:2;9791:22;9581:238;9538:281;;:::o;9825:129::-;9859:6;9886:20;;:::i;:::-;9876:30;;9915:33;9943:4;9935:6;9915:33;:::i;:::-;9825:129;;;:::o;9960:308::-;10022:4;10112:18;10104:6;10101:30;10098:56;;;10134:18;;:::i;:::-;10098:56;10172:29;10194:6;10172:29;:::i;:::-;10164:37;;10256:4;10250;10246:15;10238:23;;9960:308;;;:::o;10274:146::-;10371:6;10366:3;10361;10348:30;10412:1;10403:6;10398:3;10394:16;10387:27;10274:146;;;:::o;10426:425::-;10504:5;10529:66;10545:49;10587:6;10545:49;:::i;:::-;10529:66;:::i;:::-;10520:75;;10618:6;10611:5;10604:21;10656:4;10649:5;10645:16;10694:3;10685:6;10680:3;10676:16;10673:25;10670:112;;;10701:79;;:::i;:::-;10670:112;10791:54;10838:6;10833:3;10828;10791:54;:::i;:::-;10510:341;10426:425;;;;;:::o;10871:340::-;10927:5;10976:3;10969:4;10961:6;10957:17;10953:27;10943:122;;10984:79;;:::i;:::-;10943:122;11101:6;11088:20;11126:79;11201:3;11193:6;11186:4;11178:6;11174:17;11126:79;:::i;:::-;11117:88;;10933:278;10871:340;;;;:::o;11217:654::-;11295:6;11303;11352:2;11340:9;11331:7;11327:23;11323:32;11320:119;;;11358:79;;:::i;:::-;11320:119;11506:1;11495:9;11491:17;11478:31;11536:18;11528:6;11525:30;11522:117;;;11558:79;;:::i;:::-;11522:117;11663:63;11718:7;11709:6;11698:9;11694:22;11663:63;:::i;:::-;11653:73;;11449:287;11775:2;11801:53;11846:7;11837:6;11826:9;11822:22;11801:53;:::i;:::-;11791:63;;11746:118;11217:654;;;;;:::o;11877:468::-;11942:6;11950;11999:2;11987:9;11978:7;11974:23;11970:32;11967:119;;;12005:79;;:::i;:::-;11967:119;12125:1;12150:53;12195:7;12186:6;12175:9;12171:22;12150:53;:::i;:::-;12140:63;;12096:117;12252:2;12278:50;12320:7;12311:6;12300:9;12296:22;12278:50;:::i;:::-;12268:60;;12223:115;11877:468;;;;;:::o;12368:568::-;12441:8;12451:6;12501:3;12494:4;12486:6;12482:17;12478:27;12468:122;;12509:79;;:::i;:::-;12468:122;12622:6;12609:20;12599:30;;12652:18;12644:6;12641:30;12638:117;;;12674:79;;:::i;:::-;12638:117;12788:4;12780:6;12776:17;12764:29;;12842:3;12834:4;12826:6;12822:17;12812:8;12808:32;12805:41;12802:128;;;12849:79;;:::i;:::-;12802:128;12368:568;;;;;:::o;12956:565::-;13026:8;13036:6;13086:3;13079:4;13071:6;13067:17;13063:27;13053:122;;13094:79;;:::i;:::-;13053:122;13207:6;13194:20;13184:30;;13237:18;13229:6;13226:30;13223:117;;;13259:79;;:::i;:::-;13223:117;13373:4;13365:6;13361:17;13349:29;;13427:3;13419:4;13411:6;13407:17;13397:8;13393:32;13390:41;13387:128;;;13434:79;;:::i;:::-;13387:128;12956:565;;;;;:::o;13527:928::-;13646:6;13654;13662;13670;13719:2;13707:9;13698:7;13694:23;13690:32;13687:119;;;13725:79;;:::i;:::-;13687:119;13873:1;13862:9;13858:17;13845:31;13903:18;13895:6;13892:30;13889:117;;;13925:79;;:::i;:::-;13889:117;14038:80;14110:7;14101:6;14090:9;14086:22;14038:80;:::i;:::-;14020:98;;;;13816:312;14195:2;14184:9;14180:18;14167:32;14226:18;14218:6;14215:30;14212:117;;;14248:79;;:::i;:::-;14212:117;14361:77;14430:7;14421:6;14410:9;14406:22;14361:77;:::i;:::-;14343:95;;;;14138:310;13527:928;;;;;;;:::o;14461:307::-;14522:4;14612:18;14604:6;14601:30;14598:56;;;14634:18;;:::i;:::-;14598:56;14672:29;14694:6;14672:29;:::i;:::-;14664:37;;14756:4;14750;14746:15;14738:23;;14461:307;;;:::o;14774:423::-;14851:5;14876:65;14892:48;14933:6;14892:48;:::i;:::-;14876:65;:::i;:::-;14867:74;;14964:6;14957:5;14950:21;15002:4;14995:5;14991:16;15040:3;15031:6;15026:3;15022:16;15019:25;15016:112;;;15047:79;;:::i;:::-;15016:112;15137:54;15184:6;15179:3;15174;15137:54;:::i;:::-;14857:340;14774:423;;;;;:::o;15216:338::-;15271:5;15320:3;15313:4;15305:6;15301:17;15297:27;15287:122;;15328:79;;:::i;:::-;15287:122;15445:6;15432:20;15470:78;15544:3;15536:6;15529:4;15521:6;15517:17;15470:78;:::i;:::-;15461:87;;15277:277;15216:338;;;;:::o;15560:943::-;15655:6;15663;15671;15679;15728:3;15716:9;15707:7;15703:23;15699:33;15696:120;;;15735:79;;:::i;:::-;15696:120;15855:1;15880:53;15925:7;15916:6;15905:9;15901:22;15880:53;:::i;:::-;15870:63;;15826:117;15982:2;16008:53;16053:7;16044:6;16033:9;16029:22;16008:53;:::i;:::-;15998:63;;15953:118;16110:2;16136:53;16181:7;16172:6;16161:9;16157:22;16136:53;:::i;:::-;16126:63;;16081:118;16266:2;16255:9;16251:18;16238:32;16297:18;16289:6;16286:30;16283:117;;;16319:79;;:::i;:::-;16283:117;16424:62;16478:7;16469:6;16458:9;16454:22;16424:62;:::i;:::-;16414:72;;16209:287;15560:943;;;;;;;:::o;16509:474::-;16577:6;16585;16634:2;16622:9;16613:7;16609:23;16605:32;16602:119;;;16640:79;;:::i;:::-;16602:119;16760:1;16785:53;16830:7;16821:6;16810:9;16806:22;16785:53;:::i;:::-;16775:63;;16731:117;16887:2;16913:53;16958:7;16949:6;16938:9;16934:22;16913:53;:::i;:::-;16903:63;;16858:118;16509:474;;;;;:::o;16989:180::-;17037:77;17034:1;17027:88;17134:4;17131:1;17124:15;17158:4;17155:1;17148:15;17175:320;17219:6;17256:1;17250:4;17246:12;17236:22;;17303:1;17297:4;17293:12;17324:18;17314:81;;17380:4;17372:6;17368:17;17358:27;;17314:81;17442:2;17434:6;17431:14;17411:18;17408:38;17405:84;;17461:18;;:::i;:::-;17405:84;17226:269;17175:320;;;:::o;17501:166::-;17641:18;17637:1;17629:6;17625:14;17618:42;17501:166;:::o;17673:366::-;17815:3;17836:67;17900:2;17895:3;17836:67;:::i;:::-;17829:74;;17912:93;18001:3;17912:93;:::i;:::-;18030:2;18025:3;18021:12;18014:19;;17673:366;;;:::o;18045:419::-;18211:4;18249:2;18238:9;18234:18;18226:26;;18298:9;18292:4;18288:20;18284:1;18273:9;18269:17;18262:47;18326:131;18452:4;18326:131;:::i;:::-;18318:139;;18045:419;;;:::o;18470:168::-;18610:20;18606:1;18598:6;18594:14;18587:44;18470:168;:::o;18644:366::-;18786:3;18807:67;18871:2;18866:3;18807:67;:::i;:::-;18800:74;;18883:93;18972:3;18883:93;:::i;:::-;19001:2;18996:3;18992:12;18985:19;;18644:366;;;:::o;19016:419::-;19182:4;19220:2;19209:9;19205:18;19197:26;;19269:9;19263:4;19259:20;19255:1;19244:9;19240:17;19233:47;19297:131;19423:4;19297:131;:::i;:::-;19289:139;;19016:419;;;:::o;19441:169::-;19581:21;19577:1;19569:6;19565:14;19558:45;19441:169;:::o;19616:366::-;19758:3;19779:67;19843:2;19838:3;19779:67;:::i;:::-;19772:74;;19855:93;19944:3;19855:93;:::i;:::-;19973:2;19968:3;19964:12;19957:19;;19616:366;;;:::o;19988:419::-;20154:4;20192:2;20181:9;20177:18;20169:26;;20241:9;20235:4;20231:20;20227:1;20216:9;20212:17;20205:47;20269:131;20395:4;20269:131;:::i;:::-;20261:139;;19988:419;;;:::o;20413:170::-;20553:22;20549:1;20541:6;20537:14;20530:46;20413:170;:::o;20589:366::-;20731:3;20752:67;20816:2;20811:3;20752:67;:::i;:::-;20745:74;;20828:93;20917:3;20828:93;:::i;:::-;20946:2;20941:3;20937:12;20930:19;;20589:366;;;:::o;20961:419::-;21127:4;21165:2;21154:9;21150:18;21142:26;;21214:9;21208:4;21204:20;21200:1;21189:9;21185:17;21178:47;21242:131;21368:4;21242:131;:::i;:::-;21234:139;;20961:419;;;:::o;21386:178::-;21526:30;21522:1;21514:6;21510:14;21503:54;21386:178;:::o;21570:366::-;21712:3;21733:67;21797:2;21792:3;21733:67;:::i;:::-;21726:74;;21809:93;21898:3;21809:93;:::i;:::-;21927:2;21922:3;21918:12;21911:19;;21570:366;;;:::o;21942:419::-;22108:4;22146:2;22135:9;22131:18;22123:26;;22195:9;22189:4;22185:20;22181:1;22170:9;22166:17;22159:47;22223:131;22349:4;22223:131;:::i;:::-;22215:139;;21942:419;;;:::o;22367:162::-;22507:14;22503:1;22495:6;22491:14;22484:38;22367:162;:::o;22535:366::-;22677:3;22698:67;22762:2;22757:3;22698:67;:::i;:::-;22691:74;;22774:93;22863:3;22774:93;:::i;:::-;22892:2;22887:3;22883:12;22876:19;;22535:366;;;:::o;22907:419::-;23073:4;23111:2;23100:9;23096:18;23088:26;;23160:9;23154:4;23150:20;23146:1;23135:9;23131:17;23124:47;23188:131;23314:4;23188:131;:::i;:::-;23180:139;;22907:419;;;:::o;23332:147::-;23433:11;23470:3;23455:18;;23332:147;;;;:::o;23485:114::-;;:::o;23605:398::-;23764:3;23785:83;23866:1;23861:3;23785:83;:::i;:::-;23778:90;;23877:93;23966:3;23877:93;:::i;:::-;23995:1;23990:3;23986:11;23979:18;;23605:398;;;:::o;24009:379::-;24193:3;24215:147;24358:3;24215:147;:::i;:::-;24208:154;;24379:3;24372:10;;24009:379;;;:::o;24394:174::-;24534:26;24530:1;24522:6;24518:14;24511:50;24394:174;:::o;24574:366::-;24716:3;24737:67;24801:2;24796:3;24737:67;:::i;:::-;24730:74;;24813:93;24902:3;24813:93;:::i;:::-;24931:2;24926:3;24922:12;24915:19;;24574:366;;;:::o;24946:419::-;25112:4;25150:2;25139:9;25135:18;25127:26;;25199:9;25193:4;25189:20;25185:1;25174:9;25170:17;25163:47;25227:131;25353:4;25227:131;:::i;:::-;25219:139;;24946:419;;;:::o;25371:97::-;25430:6;25458:3;25448:13;;25371:97;;;;:::o;25474:141::-;25523:4;25546:3;25538:11;;25569:3;25566:1;25559:14;25603:4;25600:1;25590:18;25582:26;;25474:141;;;:::o;25621:93::-;25658:6;25705:2;25700;25693:5;25689:14;25685:23;25675:33;;25621:93;;;:::o;25720:107::-;25764:8;25814:5;25808:4;25804:16;25783:37;;25720:107;;;;:::o;25833:393::-;25902:6;25952:1;25940:10;25936:18;25975:97;26005:66;25994:9;25975:97;:::i;:::-;26093:39;26123:8;26112:9;26093:39;:::i;:::-;26081:51;;26165:4;26161:9;26154:5;26150:21;26141:30;;26214:4;26204:8;26200:19;26193:5;26190:30;26180:40;;25909:317;;25833:393;;;;;:::o;26232:60::-;26260:3;26281:5;26274:12;;26232:60;;;:::o;26298:142::-;26348:9;26381:53;26399:34;26408:24;26426:5;26408:24;:::i;:::-;26399:34;:::i;:::-;26381:53;:::i;:::-;26368:66;;26298:142;;;:::o;26446:75::-;26489:3;26510:5;26503:12;;26446:75;;;:::o;26527:269::-;26637:39;26668:7;26637:39;:::i;:::-;26698:91;26747:41;26771:16;26747:41;:::i;:::-;26739:6;26732:4;26726:11;26698:91;:::i;:::-;26692:4;26685:105;26603:193;26527:269;;;:::o;26802:73::-;26847:3;26802:73;:::o;26881:189::-;26958:32;;:::i;:::-;26999:65;27057:6;27049;27043:4;26999:65;:::i;:::-;26934:136;26881:189;;:::o;27076:186::-;27136:120;27153:3;27146:5;27143:14;27136:120;;;27207:39;27244:1;27237:5;27207:39;:::i;:::-;27180:1;27173:5;27169:13;27160:22;;27136:120;;;27076:186;;:::o;27268:543::-;27369:2;27364:3;27361:11;27358:446;;;27403:38;27435:5;27403:38;:::i;:::-;27487:29;27505:10;27487:29;:::i;:::-;27477:8;27473:44;27670:2;27658:10;27655:18;27652:49;;;27691:8;27676:23;;27652:49;27714:80;27770:22;27788:3;27770:22;:::i;:::-;27760:8;27756:37;27743:11;27714:80;:::i;:::-;27373:431;;27358:446;27268:543;;;:::o;27817:117::-;27871:8;27921:5;27915:4;27911:16;27890:37;;27817:117;;;;:::o;27940:169::-;27984:6;28017:51;28065:1;28061:6;28053:5;28050:1;28046:13;28017:51;:::i;:::-;28013:56;28098:4;28092;28088:15;28078:25;;27991:118;27940:169;;;;:::o;28114:295::-;28190:4;28336:29;28361:3;28355:4;28336:29;:::i;:::-;28328:37;;28398:3;28395:1;28391:11;28385:4;28382:21;28374:29;;28114:295;;;;:::o;28414:1403::-;28538:44;28578:3;28573;28538:44;:::i;:::-;28647:18;28639:6;28636:30;28633:56;;;28669:18;;:::i;:::-;28633:56;28713:38;28745:4;28739:11;28713:38;:::i;:::-;28798:67;28858:6;28850;28844:4;28798:67;:::i;:::-;28892:1;28921:2;28913:6;28910:14;28938:1;28933:632;;;;29609:1;29626:6;29623:84;;;29682:9;29677:3;29673:19;29660:33;29651:42;;29623:84;29733:67;29793:6;29786:5;29733:67;:::i;:::-;29727:4;29720:81;29582:229;28903:908;;28933:632;28985:4;28981:9;28973:6;28969:22;29019:37;29051:4;29019:37;:::i;:::-;29078:1;29092:215;29106:7;29103:1;29100:14;29092:215;;;29192:9;29187:3;29183:19;29170:33;29162:6;29155:49;29243:1;29235:6;29231:14;29221:24;;29290:2;29279:9;29275:18;29262:31;;29129:4;29126:1;29122:12;29117:17;;29092:215;;;29335:6;29326:7;29323:19;29320:186;;;29400:9;29395:3;29391:19;29378:33;29443:48;29485:4;29477:6;29473:17;29462:9;29443:48;:::i;:::-;29435:6;29428:64;29343:163;29320:186;29552:1;29548;29540:6;29536:14;29532:22;29526:4;29519:36;28940:625;;;28903:908;;28513:1304;;;28414:1403;;;:::o;29823:170::-;29963:22;29959:1;29951:6;29947:14;29940:46;29823:170;:::o;29999:366::-;30141:3;30162:67;30226:2;30221:3;30162:67;:::i;:::-;30155:74;;30238:93;30327:3;30238:93;:::i;:::-;30356:2;30351:3;30347:12;30340:19;;29999:366;;;:::o;30371:419::-;30537:4;30575:2;30564:9;30560:18;30552:26;;30624:9;30618:4;30614:20;30610:1;30599:9;30595:17;30588:47;30652:131;30778:4;30652:131;:::i;:::-;30644:139;;30371:419;;;:::o;30796:165::-;30936:17;30932:1;30924:6;30920:14;30913:41;30796:165;:::o;30967:366::-;31109:3;31130:67;31194:2;31189:3;31130:67;:::i;:::-;31123:74;;31206:93;31295:3;31206:93;:::i;:::-;31324:2;31319:3;31315:12;31308:19;;30967:366;;;:::o;31339:419::-;31505:4;31543:2;31532:9;31528:18;31520:26;;31592:9;31586:4;31582:20;31578:1;31567:9;31563:17;31556:47;31620:131;31746:4;31620:131;:::i;:::-;31612:139;;31339:419;;;:::o;31764:553::-;31941:4;31979:3;31968:9;31964:19;31956:27;;31993:71;32061:1;32050:9;32046:17;32037:6;31993:71;:::i;:::-;32074:72;32142:2;32131:9;32127:18;32118:6;32074:72;:::i;:::-;32156;32224:2;32213:9;32209:18;32200:6;32156:72;:::i;:::-;32238;32306:2;32295:9;32291:18;32282:6;32238:72;:::i;:::-;31764:553;;;;;;;:::o;32323:242::-;32463:34;32459:1;32451:6;32447:14;32440:58;32532:25;32527:2;32519:6;32515:15;32508:50;32323:242;:::o;32571:366::-;32713:3;32734:67;32798:2;32793:3;32734:67;:::i;:::-;32727:74;;32810:93;32899:3;32810:93;:::i;:::-;32928:2;32923:3;32919:12;32912:19;;32571:366;;;:::o;32943:419::-;33109:4;33147:2;33136:9;33132:18;33124:26;;33196:9;33190:4;33186:20;33182:1;33171:9;33167:17;33160:47;33224:131;33350:4;33224:131;:::i;:::-;33216:139;;32943:419;;;:::o;33368:233::-;33508:34;33504:1;33496:6;33492:14;33485:58;33577:16;33572:2;33564:6;33560:15;33553:41;33368:233;:::o;33607:366::-;33749:3;33770:67;33834:2;33829:3;33770:67;:::i;:::-;33763:74;;33846:93;33935:3;33846:93;:::i;:::-;33964:2;33959:3;33955:12;33948:19;;33607:366;;;:::o;33979:419::-;34145:4;34183:2;34172:9;34168:18;34160:26;;34232:9;34226:4;34222:20;34218:1;34207:9;34203:17;34196:47;34260:131;34386:4;34260:131;:::i;:::-;34252:139;;33979:419;;;:::o;34404:1395::-;34521:37;34554:3;34521:37;:::i;:::-;34623:18;34615:6;34612:30;34609:56;;;34645:18;;:::i;:::-;34609:56;34689:38;34721:4;34715:11;34689:38;:::i;:::-;34774:67;34834:6;34826;34820:4;34774:67;:::i;:::-;34868:1;34892:4;34879:17;;34924:2;34916:6;34913:14;34941:1;34936:618;;;;35598:1;35615:6;35612:77;;;35664:9;35659:3;35655:19;35649:26;35640:35;;35612:77;35715:67;35775:6;35768:5;35715:67;:::i;:::-;35709:4;35702:81;35571:222;34906:887;;34936:618;34988:4;34984:9;34976:6;34972:22;35022:37;35054:4;35022:37;:::i;:::-;35081:1;35095:208;35109:7;35106:1;35103:14;35095:208;;;35188:9;35183:3;35179:19;35173:26;35165:6;35158:42;35239:1;35231:6;35227:14;35217:24;;35286:2;35275:9;35271:18;35258:31;;35132:4;35129:1;35125:12;35120:17;;35095:208;;;35331:6;35322:7;35319:19;35316:179;;;35389:9;35384:3;35380:19;35374:26;35432:48;35474:4;35466:6;35462:17;35451:9;35432:48;:::i;:::-;35424:6;35417:64;35339:156;35316:179;35541:1;35537;35529:6;35525:14;35521:22;35515:4;35508:36;34943:611;;;34906:887;;34496:1303;;;34404:1395;;:::o;35805:85::-;35850:7;35879:5;35868:16;;35805:85;;;:::o;35896:86::-;35931:7;35971:4;35964:5;35960:16;35949:27;;35896:86;;;:::o;35988:154::-;36044:9;36077:59;36093:42;36102:32;36128:5;36102:32;:::i;:::-;36093:42;:::i;:::-;36077:59;:::i;:::-;36064:72;;35988:154;;;:::o;36148:143::-;36241:43;36278:5;36241:43;:::i;:::-;36236:3;36229:56;36148:143;;:::o;36297:234::-;36396:4;36434:2;36423:9;36419:18;36411:26;;36447:77;36521:1;36510:9;36506:17;36497:6;36447:77;:::i;:::-;36297:234;;;;:::o;36537:442::-;36686:4;36724:2;36713:9;36709:18;36701:26;;36737:71;36805:1;36794:9;36790:17;36781:6;36737:71;:::i;:::-;36818:72;36886:2;36875:9;36871:18;36862:6;36818:72;:::i;:::-;36900;36968:2;36957:9;36953:18;36944:6;36900:72;:::i;:::-;36537:442;;;;;;:::o;36985:157::-;37125:9;37121:1;37113:6;37109:14;37102:33;36985:157;:::o;37148:365::-;37290:3;37311:66;37375:1;37370:3;37311:66;:::i;:::-;37304:73;;37386:93;37475:3;37386:93;:::i;:::-;37504:2;37499:3;37495:12;37488:19;;37148:365;;;:::o;37519:419::-;37685:4;37723:2;37712:9;37708:18;37700:26;;37772:9;37766:4;37762:20;37758:1;37747:9;37743:17;37736:47;37800:131;37926:4;37800:131;:::i;:::-;37792:139;;37519:419;;;:::o;37944:180::-;37992:77;37989:1;37982:88;38089:4;38086:1;38079:15;38113:4;38110:1;38103:15;38130:180;38178:77;38175:1;38168:88;38275:4;38272:1;38265:15;38299:4;38296:1;38289:15;38316:233;38355:3;38378:24;38396:5;38378:24;:::i;:::-;38369:33;;38424:66;38417:5;38414:77;38411:103;;38494:18;;:::i;:::-;38411:103;38541:1;38534:5;38530:13;38523:20;;38316:233;;;:::o;38555:165::-;38695:17;38691:1;38683:6;38679:14;38672:41;38555:165;:::o;38726:366::-;38868:3;38889:67;38953:2;38948:3;38889:67;:::i;:::-;38882:74;;38965:93;39054:3;38965:93;:::i;:::-;39083:2;39078:3;39074:12;39067:19;;38726:366;;;:::o;39098:419::-;39264:4;39302:2;39291:9;39287:18;39279:26;;39351:9;39345:4;39341:20;39337:1;39326:9;39322:17;39315:47;39379:131;39505:4;39379:131;:::i;:::-;39371:139;;39098:419;;;:::o;39523:225::-;39663:34;39659:1;39651:6;39647:14;39640:58;39732:8;39727:2;39719:6;39715:15;39708:33;39523:225;:::o;39754:366::-;39896:3;39917:67;39981:2;39976:3;39917:67;:::i;:::-;39910:74;;39993:93;40082:3;39993:93;:::i;:::-;40111:2;40106:3;40102:12;40095:19;;39754:366;;;:::o;40126:419::-;40292:4;40330:2;40319:9;40315:18;40307:26;;40379:9;40373:4;40369:20;40365:1;40354:9;40350:17;40343:47;40407:131;40533:4;40407:131;:::i;:::-;40399:139;;40126:419;;;:::o;40551:182::-;40691:34;40687:1;40679:6;40675:14;40668:58;40551:182;:::o;40739:366::-;40881:3;40902:67;40966:2;40961:3;40902:67;:::i;:::-;40895:74;;40978:93;41067:3;40978:93;:::i;:::-;41096:2;41091:3;41087:12;41080:19;;40739:366;;;:::o;41111:419::-;41277:4;41315:2;41304:9;41300:18;41292:26;;41364:9;41358:4;41354:20;41350:1;41339:9;41335:17;41328:47;41392:131;41518:4;41392:131;:::i;:::-;41384:139;;41111:419;;;:::o;41536:165::-;41676:17;41672:1;41664:6;41660:14;41653:41;41536:165;:::o;41707:366::-;41849:3;41870:67;41934:2;41929:3;41870:67;:::i;:::-;41863:74;;41946:93;42035:3;41946:93;:::i;:::-;42064:2;42059:3;42055:12;42048:19;;41707:366;;;:::o;42079:419::-;42245:4;42283:2;42272:9;42268:18;42260:26;;42332:9;42326:4;42322:20;42318:1;42307:9;42303:17;42296:47;42360:131;42486:4;42360:131;:::i;:::-;42352:139;;42079:419;;;:::o;42504:167::-;42644:19;42640:1;42632:6;42628:14;42621:43;42504:167;:::o;42677:366::-;42819:3;42840:67;42904:2;42899:3;42840:67;:::i;:::-;42833:74;;42916:93;43005:3;42916:93;:::i;:::-;43034:2;43029:3;43025:12;43018:19;;42677:366;;;:::o;43049:419::-;43215:4;43253:2;43242:9;43238:18;43230:26;;43302:9;43296:4;43292:20;43288:1;43277:9;43273:17;43266:47;43330:131;43456:4;43330:131;:::i;:::-;43322:139;;43049:419;;;:::o;43474:177::-;43614:29;43610:1;43602:6;43598:14;43591:53;43474:177;:::o;43657:366::-;43799:3;43820:67;43884:2;43879:3;43820:67;:::i;:::-;43813:74;;43896:93;43985:3;43896:93;:::i;:::-;44014:2;44009:3;44005:12;43998:19;;43657:366;;;:::o;44029:419::-;44195:4;44233:2;44222:9;44218:18;44210:26;;44282:9;44276:4;44272:20;44268:1;44257:9;44253:17;44246:47;44310:131;44436:4;44310:131;:::i;:::-;44302:139;;44029:419;;;:::o;44454:191::-;44494:3;44513:20;44531:1;44513:20;:::i;:::-;44508:25;;44547:20;44565:1;44547:20;:::i;:::-;44542:25;;44590:1;44587;44583:9;44576:16;;44611:3;44608:1;44605:10;44602:36;;;44618:18;;:::i;:::-;44602:36;44454:191;;;;:::o;44651:173::-;44791:25;44787:1;44779:6;44775:14;44768:49;44651:173;:::o;44830:366::-;44972:3;44993:67;45057:2;45052:3;44993:67;:::i;:::-;44986:74;;45069:93;45158:3;45069:93;:::i;:::-;45187:2;45182:3;45178:12;45171:19;;44830:366;;;:::o;45202:419::-;45368:4;45406:2;45395:9;45391:18;45383:26;;45455:9;45449:4;45445:20;45441:1;45430:9;45426:17;45419:47;45483:131;45609:4;45483:131;:::i;:::-;45475:139;;45202:419;;;:::o;45627:171::-;45666:3;45689:24;45707:5;45689:24;:::i;:::-;45680:33;;45735:4;45728:5;45725:15;45722:41;;45743:18;;:::i;:::-;45722:41;45790:1;45783:5;45779:13;45772:20;;45627:171;;;:::o;45804:230::-;45944:34;45940:1;45932:6;45928:14;45921:58;46013:13;46008:2;46000:6;45996:15;45989:38;45804:230;:::o;46040:366::-;46182:3;46203:67;46267:2;46262:3;46203:67;:::i;:::-;46196:74;;46279:93;46368:3;46279:93;:::i;:::-;46397:2;46392:3;46388:12;46381:19;;46040:366;;;:::o;46412:419::-;46578:4;46616:2;46605:9;46601:18;46593:26;;46665:9;46659:4;46655:20;46651:1;46640:9;46636:17;46629:47;46693:131;46819:4;46693:131;:::i;:::-;46685:139;;46412:419;;;:::o;46837:163::-;46977:15;46973:1;46965:6;46961:14;46954:39;46837:163;:::o;47006:366::-;47148:3;47169:67;47233:2;47228:3;47169:67;:::i;:::-;47162:74;;47245:93;47334:3;47245:93;:::i;:::-;47363:2;47358:3;47354:12;47347:19;;47006:366;;;:::o;47378:419::-;47544:4;47582:2;47571:9;47567:18;47559:26;;47631:9;47625:4;47621:20;47617:1;47606:9;47602:17;47595:47;47659:131;47785:4;47659:131;:::i;:::-;47651:139;;47378:419;;;:::o;47803:239::-;47943:34;47939:1;47931:6;47927:14;47920:58;48012:22;48007:2;47999:6;47995:15;47988:47;47803:239;:::o;48048:366::-;48190:3;48211:67;48275:2;48270:3;48211:67;:::i;:::-;48204:74;;48287:93;48376:3;48287:93;:::i;:::-;48405:2;48400:3;48396:12;48389:19;;48048:366;;;:::o;48420:419::-;48586:4;48624:2;48613:9;48609:18;48601:26;;48673:9;48667:4;48663:20;48659:1;48648:9;48644:17;48637:47;48701:131;48827:4;48701:131;:::i;:::-;48693:139;;48420:419;;;:::o;48845:98::-;48896:6;48930:5;48924:12;48914:22;;48845:98;;;:::o;48949:168::-;49032:11;49066:6;49061:3;49054:19;49106:4;49101:3;49097:14;49082:29;;48949:168;;;;:::o;49123:373::-;49209:3;49237:38;49269:5;49237:38;:::i;:::-;49291:70;49354:6;49349:3;49291:70;:::i;:::-;49284:77;;49370:65;49428:6;49423:3;49416:4;49409:5;49405:16;49370:65;:::i;:::-;49460:29;49482:6;49460:29;:::i;:::-;49455:3;49451:39;49444:46;;49213:283;49123:373;;;;:::o;49502:640::-;49697:4;49735:3;49724:9;49720:19;49712:27;;49749:71;49817:1;49806:9;49802:17;49793:6;49749:71;:::i;:::-;49830:72;49898:2;49887:9;49883:18;49874:6;49830:72;:::i;:::-;49912;49980:2;49969:9;49965:18;49956:6;49912:72;:::i;:::-;50031:9;50025:4;50021:20;50016:2;50005:9;50001:18;49994:48;50059:76;50130:4;50121:6;50059:76;:::i;:::-;50051:84;;49502:640;;;;;;;:::o;50148:141::-;50204:5;50235:6;50229:13;50220:22;;50251:32;50277:5;50251:32;:::i;:::-;50148:141;;;;:::o;50295:349::-;50364:6;50413:2;50401:9;50392:7;50388:23;50384:32;50381:119;;;50419:79;;:::i;:::-;50381:119;50539:1;50564:63;50619:7;50610:6;50599:9;50595:22;50564:63;:::i;:::-;50554:73;;50510:127;50295:349;;;;:::o
Swarm Source
ipfs://7aa42ed34c05c31bc63088a295d18c860b3da493e3e0cb66675971fd0a271312
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 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.