Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
VeSixUpgradeable
Compiler Version
v0.8.27+commit.40a35a09
Contract Source Code (Solidity)
/** *Submitted for verification at SonicScan.org on 2025-02-22 */ // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * 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[ERC 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); } pragma solidity ^0.8.20; /** * @dev Required interface of an ERC-721 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 ERC-721 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 ERC-721 * 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 address zero. * * 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); } pragma solidity ^0.8.20; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @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); } pragma solidity ^0.8.20; /** * @title ERC-721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC-721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be * reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } pragma solidity ^0.8.20; /** * @dev Standard ERC-20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC-721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC-1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); } pragma solidity ^0.8.20; /** * @dev Library that provide common ERC-721 utility functions. * * See https://eips.ethereum.org/EIPS/eip-721[ERC-721]. * * _Available since v5.1._ */ library ERC721Utils { /** * @dev Performs an acceptance check for the provided `operator` by calling {IERC721-onERC721Received} * on the `to` address. The `operator` is generally the address that initiated the token transfer (i.e. `msg.sender`). * * The acceptance call is not executed and treated as a no-op if the target address doesn't contain code (i.e. an EOA). * Otherwise, the recipient must implement {IERC721Receiver-onERC721Received} and return the acceptance magic value to accept * the transfer. */ function checkOnERC721Received( address operator, address from, address to, uint256 tokenId, bytes memory data ) internal { if (to.code.length > 0) { try IERC721Receiver(to).onERC721Received(operator, from, tokenId, data) returns (bytes4 retval) { if (retval != IERC721Receiver.onERC721Received.selector) { // Token rejected revert IERC721Errors.ERC721InvalidReceiver(to); } } catch (bytes memory reason) { if (reason.length == 0) { // non-IERC721Receiver implementer revert IERC721Errors.ERC721InvalidReceiver(to); } else { assembly ("memory-safe") { revert(add(32, reason), mload(reason)) } } } } } } pragma solidity ^0.8.20; /** * @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 Storage of the initializable contract. * * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions * when using with upgradeable contracts. * * @custom:storage-location erc7201:openzeppelin.storage.Initializable */ struct InitializableStorage { /** * @dev Indicates that the contract has been initialized. */ uint64 _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool _initializing; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00; /** * @dev The contract is already initialized. */ error InvalidInitialization(); /** * @dev The contract is not initializing. */ error NotInitializing(); /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint64 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 in the context of a constructor an `initializer` may be invoked any * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in * production. * * Emits an {Initialized} event. */ modifier initializer() { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); // Cache values to avoid duplicated sloads bool isTopLevelCall = !$._initializing; uint64 initialized = $._initialized; // Allowed calls: // - initialSetup: the contract is not in the initializing state and no previous version was // initialized // - construction: the contract is initialized at version 1 (no reininitialization) and the // current contract is just being deployed bool initialSetup = initialized == 0 && isTopLevelCall; bool construction = initialized == 1 && address(this).code.length == 0; if (!initialSetup && !construction) { revert InvalidInitialization(); } $._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 2**64 - 1 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint64 version) { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing || $._initialized >= version) { revert InvalidInitialization(); } $._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() { _checkInitializing(); _; } /** * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}. */ function _checkInitializing() internal view virtual { if (!_isInitializing()) { revert NotInitializing(); } } /** * @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 { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing) { revert InvalidInitialization(); } if ($._initialized != type(uint64).max) { $._initialized = type(uint64).max; emit Initialized(type(uint64).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint64) { return _getInitializableStorage()._initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _getInitializableStorage()._initializing; } /** * @dev Returns a pointer to the storage namespace. */ // solhint-disable-next-line var-name-mixedcase function _getInitializableStorage() private pure returns (InitializableStorage storage $) { assembly { $.slot := INITIALIZABLE_STORAGE } } } pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract 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; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } } pragma solidity ^0.8.20; /** * @dev Helper library for emitting standardized panic codes. * * ```solidity * contract Example { * using Panic for uint256; * * // Use any of the declared internal constants * function foo() { Panic.GENERIC.panic(); } * * // Alternatively * function foo() { Panic.panic(Panic.GENERIC); } * } * ``` * * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil]. * * _Available since v5.1._ */ // slither-disable-next-line unused-state library Panic { /// @dev generic / unspecified error uint256 internal constant GENERIC = 0x00; /// @dev used by the assert() builtin uint256 internal constant ASSERT = 0x01; /// @dev arithmetic underflow or overflow uint256 internal constant UNDER_OVERFLOW = 0x11; /// @dev division or modulo by zero uint256 internal constant DIVISION_BY_ZERO = 0x12; /// @dev enum conversion error uint256 internal constant ENUM_CONVERSION_ERROR = 0x21; /// @dev invalid encoding in storage uint256 internal constant STORAGE_ENCODING_ERROR = 0x22; /// @dev empty array pop uint256 internal constant EMPTY_ARRAY_POP = 0x31; /// @dev array out of bounds access uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32; /// @dev resource error (too large allocation or too large array) uint256 internal constant RESOURCE_ERROR = 0x41; /// @dev calling invalid internal function uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51; /// @dev Reverts with a panic code. Recommended to use with /// the internal constants with predefined codes. function panic(uint256 code) internal pure { assembly ("memory-safe") { mstore(0x00, 0x4e487b71) mstore(0x20, code) revert(0x1c, 0x24) } } } // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.20; /** * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeCast { /** * @dev Value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); /** * @dev An int value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedIntToUint(int256 value); /** * @dev Value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedIntDowncast(uint8 bits, int256 value); /** * @dev An uint value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedUintToInt(uint256 value); /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits */ function toUint248(uint256 value) internal pure returns (uint248) { if (value > type(uint248).max) { revert SafeCastOverflowedUintDowncast(248, value); } return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits */ function toUint240(uint256 value) internal pure returns (uint240) { if (value > type(uint240).max) { revert SafeCastOverflowedUintDowncast(240, value); } return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits */ function toUint232(uint256 value) internal pure returns (uint232) { if (value > type(uint232).max) { revert SafeCastOverflowedUintDowncast(232, value); } return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { if (value > type(uint224).max) { revert SafeCastOverflowedUintDowncast(224, value); } return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits */ function toUint216(uint256 value) internal pure returns (uint216) { if (value > type(uint216).max) { revert SafeCastOverflowedUintDowncast(216, value); } return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits */ function toUint208(uint256 value) internal pure returns (uint208) { if (value > type(uint208).max) { revert SafeCastOverflowedUintDowncast(208, value); } return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits */ function toUint200(uint256 value) internal pure returns (uint200) { if (value > type(uint200).max) { revert SafeCastOverflowedUintDowncast(200, value); } return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits */ function toUint192(uint256 value) internal pure returns (uint192) { if (value > type(uint192).max) { revert SafeCastOverflowedUintDowncast(192, value); } return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits */ function toUint184(uint256 value) internal pure returns (uint184) { if (value > type(uint184).max) { revert SafeCastOverflowedUintDowncast(184, value); } return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits */ function toUint176(uint256 value) internal pure returns (uint176) { if (value > type(uint176).max) { revert SafeCastOverflowedUintDowncast(176, value); } return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits */ function toUint168(uint256 value) internal pure returns (uint168) { if (value > type(uint168).max) { revert SafeCastOverflowedUintDowncast(168, value); } return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits */ function toUint160(uint256 value) internal pure returns (uint160) { if (value > type(uint160).max) { revert SafeCastOverflowedUintDowncast(160, value); } return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits */ function toUint152(uint256 value) internal pure returns (uint152) { if (value > type(uint152).max) { revert SafeCastOverflowedUintDowncast(152, value); } return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits */ function toUint144(uint256 value) internal pure returns (uint144) { if (value > type(uint144).max) { revert SafeCastOverflowedUintDowncast(144, value); } return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits */ function toUint136(uint256 value) internal pure returns (uint136) { if (value > type(uint136).max) { revert SafeCastOverflowedUintDowncast(136, value); } return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { if (value > type(uint128).max) { revert SafeCastOverflowedUintDowncast(128, value); } return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits */ function toUint120(uint256 value) internal pure returns (uint120) { if (value > type(uint120).max) { revert SafeCastOverflowedUintDowncast(120, value); } return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits */ function toUint112(uint256 value) internal pure returns (uint112) { if (value > type(uint112).max) { revert SafeCastOverflowedUintDowncast(112, value); } return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits */ function toUint104(uint256 value) internal pure returns (uint104) { if (value > type(uint104).max) { revert SafeCastOverflowedUintDowncast(104, value); } return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { if (value > type(uint96).max) { revert SafeCastOverflowedUintDowncast(96, value); } return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits */ function toUint88(uint256 value) internal pure returns (uint88) { if (value > type(uint88).max) { revert SafeCastOverflowedUintDowncast(88, value); } return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits */ function toUint80(uint256 value) internal pure returns (uint80) { if (value > type(uint80).max) { revert SafeCastOverflowedUintDowncast(80, value); } return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits */ function toUint72(uint256 value) internal pure returns (uint72) { if (value > type(uint72).max) { revert SafeCastOverflowedUintDowncast(72, value); } return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { if (value > type(uint64).max) { revert SafeCastOverflowedUintDowncast(64, value); } return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits */ function toUint56(uint256 value) internal pure returns (uint56) { if (value > type(uint56).max) { revert SafeCastOverflowedUintDowncast(56, value); } return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits */ function toUint48(uint256 value) internal pure returns (uint48) { if (value > type(uint48).max) { revert SafeCastOverflowedUintDowncast(48, value); } return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits */ function toUint40(uint256 value) internal pure returns (uint40) { if (value > type(uint40).max) { revert SafeCastOverflowedUintDowncast(40, value); } return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { if (value > type(uint32).max) { revert SafeCastOverflowedUintDowncast(32, value); } return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits */ function toUint24(uint256 value) internal pure returns (uint24) { if (value > type(uint24).max) { revert SafeCastOverflowedUintDowncast(24, value); } return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { if (value > type(uint16).max) { revert SafeCastOverflowedUintDowncast(16, value); } return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits */ function toUint8(uint256 value) internal pure returns (uint8) { if (value > type(uint8).max) { revert SafeCastOverflowedUintDowncast(8, value); } return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { if (value < 0) { revert SafeCastOverflowedIntToUint(value); } return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(248, value); } } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(240, value); } } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(232, value); } } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(224, value); } } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(216, value); } } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(208, value); } } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(200, value); } } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(192, value); } } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(184, value); } } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(176, value); } } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(168, value); } } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(160, value); } } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(152, value); } } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(144, value); } } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(136, value); } } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(128, value); } } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(120, value); } } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(112, value); } } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(104, value); } } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(96, value); } } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(88, value); } } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(80, value); } } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(72, value); } } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(64, value); } } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(56, value); } } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(48, value); } } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(40, value); } } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(32, value); } } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(24, value); } } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(16, value); } } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(8, value); } } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive if (value > uint256(type(int256).max)) { revert SafeCastOverflowedUintToInt(value); } return int256(value); } /** * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump. */ function toUint(bool b) internal pure returns (uint256 u) { assembly ("memory-safe") { u := iszero(iszero(b)) } } } pragma solidity ^0.8.20; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an success flag (no overflow). */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an success flag (no overflow). */ function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an success flag (no overflow). */ function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a success flag (no division by zero). */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero). */ function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. * * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute * one branch when needed, making this function more expensive. */ function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) { unchecked { // branchless ternary works because: // b ^ (a ^ b) == a // b ^ 0 == b return b ^ ((a ^ b) * SafeCast.toUint(condition)); } } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return ternary(a > b, a, b); } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return ternary(a < b, a, b); } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. Panic.panic(Panic.DIVISION_BY_ZERO); } // The following calculation ensures accurate ceiling division without overflow. // Since a is non-zero, (a - 1) / b will not overflow. // The largest possible result occurs when (a - 1) / b is type(uint256).max, // but the largest value we can obtain is type(uint256).max - 1, which happens // when a = type(uint256).max and b = 1. unchecked { return SafeCast.toUint(a > 0) * ((a - 1) / b + 1); } } /** * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or * denominator == 0. * * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by * Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2²⁵⁶ + prod0. uint256 prod0 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0. if (denominator <= prod1) { Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW)); } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. // Always >= 1. See https://cs.stackexchange.com/q/138556/92363. uint256 twos = denominator & (0 - denominator); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv ≡ 1 mod 2⁴. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also // works in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2⁸ inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶ inverse *= 2 - denominator * inverse; // inverse mod 2³² inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴ inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸ inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶ // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @dev Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0); } /** * @dev Calculate the modular multiplicative inverse of a number in Z/nZ. * * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0. * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible. * * If the input value is not inversible, 0 is returned. * * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}. */ function invMod(uint256 a, uint256 n) internal pure returns (uint256) { unchecked { if (n == 0) return 0; // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version) // Used to compute integers x and y such that: ax + ny = gcd(a, n). // When the gcd is 1, then the inverse of a modulo n exists and it's x. // ax + ny = 1 // ax = 1 + (-y)n // ax ≡ 1 (mod n) # x is the inverse of a modulo n // If the remainder is 0 the gcd is n right away. uint256 remainder = a % n; uint256 gcd = n; // Therefore the initial coefficients are: // ax + ny = gcd(a, n) = n // 0a + 1n = n int256 x = 0; int256 y = 1; while (remainder != 0) { uint256 quotient = gcd / remainder; (gcd, remainder) = ( // The old remainder is the next gcd to try. remainder, // Compute the next remainder. // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd // where gcd is at most n (capped to type(uint256).max) gcd - remainder * quotient ); (x, y) = ( // Increment the coefficient of a. y, // Decrement the coefficient of n. // Can overflow, but the result is casted to uint256 so that the // next value of y is "wrapped around" to a value between 0 and n - 1. x - y * int256(quotient) ); } if (gcd != 1) return 0; // No inverse exists. return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative. } } /** * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`. * * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that * `a**(p-2)` is the modular multiplicative inverse of a in Fp. * * NOTE: this function does NOT check that `p` is a prime greater than `2`. */ function invModPrime(uint256 a, uint256 p) internal view returns (uint256) { unchecked { return Math.modExp(a, p - 2, p); } } /** * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m) * * Requirements: * - modulus can't be zero * - underlying staticcall to precompile must succeed * * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make * sure the chain you're using it on supports the precompiled contract for modular exponentiation * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, * the underlying function will succeed given the lack of a revert, but the result may be incorrectly * interpreted as 0. */ function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) { (bool success, uint256 result) = tryModExp(b, e, m); if (!success) { Panic.panic(Panic.DIVISION_BY_ZERO); } return result; } /** * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m). * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying * to operate modulo 0 or if the underlying precompile reverted. * * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack * of a revert, but the result may be incorrectly interpreted as 0. */ function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) { if (m == 0) return (false, 0); assembly ("memory-safe") { let ptr := mload(0x40) // | Offset | Content | Content (Hex) | // |-----------|------------|--------------------------------------------------------------------| // | 0x00:0x1f | size of b | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x20:0x3f | size of e | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x40:0x5f | size of m | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x60:0x7f | value of b | 0x<.............................................................b> | // | 0x80:0x9f | value of e | 0x<.............................................................e> | // | 0xa0:0xbf | value of m | 0x<.............................................................m> | mstore(ptr, 0x20) mstore(add(ptr, 0x20), 0x20) mstore(add(ptr, 0x40), 0x20) mstore(add(ptr, 0x60), b) mstore(add(ptr, 0x80), e) mstore(add(ptr, 0xa0), m) // Given the result < m, it's guaranteed to fit in 32 bytes, // so we can use the memory scratch space located at offset 0. success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20) result := mload(0x00) } } /** * @dev Variant of {modExp} that supports inputs of arbitrary length. */ function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) { (bool success, bytes memory result) = tryModExp(b, e, m); if (!success) { Panic.panic(Panic.DIVISION_BY_ZERO); } return result; } /** * @dev Variant of {tryModExp} that supports inputs of arbitrary length. */ function tryModExp( bytes memory b, bytes memory e, bytes memory m ) internal view returns (bool success, bytes memory result) { if (_zeroBytes(m)) return (false, new bytes(0)); uint256 mLen = m.length; // Encode call args in result and move the free memory pointer result = abi.encodePacked(b.length, e.length, mLen, b, e, m); assembly ("memory-safe") { let dataPtr := add(result, 0x20) // Write result on top of args to avoid allocating extra memory. success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen) // Overwrite the length. // result.length > returndatasize() is guaranteed because returndatasize() == m.length mstore(result, mLen) // Set the memory pointer after the returned data. mstore(0x40, add(dataPtr, mLen)) } } /** * @dev Returns whether the provided byte array is zero. */ function _zeroBytes(bytes memory byteArray) private pure returns (bool) { for (uint256 i = 0; i < byteArray.length; ++i) { if (byteArray[i] != 0) { return false; } } return true; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded * towards zero. * * This method is based on Newton's method for computing square roots; the algorithm is restricted to only * using integer operations. */ function sqrt(uint256 a) internal pure returns (uint256) { unchecked { // Take care of easy edge cases when a == 0 or a == 1 if (a <= 1) { return a; } // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between // the current value as `ε_n = | x_n - sqrt(a) |`. // // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is // bigger than any uint256. // // By noticing that // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)` // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar // to the msb function. uint256 aa = a; uint256 xn = 1; if (aa >= (1 << 128)) { aa >>= 128; xn <<= 64; } if (aa >= (1 << 64)) { aa >>= 64; xn <<= 32; } if (aa >= (1 << 32)) { aa >>= 32; xn <<= 16; } if (aa >= (1 << 16)) { aa >>= 16; xn <<= 8; } if (aa >= (1 << 8)) { aa >>= 8; xn <<= 4; } if (aa >= (1 << 4)) { aa >>= 4; xn <<= 2; } if (aa >= (1 << 2)) { xn <<= 1; } // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1). // // We can refine our estimation by noticing that the middle of that interval minimizes the error. // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2). // This is going to be our x_0 (and ε_0) xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2) // From here, Newton's method give us: // x_{n+1} = (x_n + a / x_n) / 2 // // One should note that: // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a // = ((x_n² + a) / (2 * x_n))² - a // = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a // = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²) // = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²) // = (x_n² - a)² / (2 * x_n)² // = ((x_n² - a) / (2 * x_n))² // ≥ 0 // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n // // This gives us the proof of quadratic convergence of the sequence: // ε_{n+1} = | x_{n+1} - sqrt(a) | // = | (x_n + a / x_n) / 2 - sqrt(a) | // = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) | // = | (x_n - sqrt(a))² / (2 * x_n) | // = | ε_n² / (2 * x_n) | // = ε_n² / | (2 * x_n) | // // For the first iteration, we have a special case where x_0 is known: // ε_1 = ε_0² / | (2 * x_0) | // ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2))) // ≤ 2**(2*e-4) / (3 * 2**(e-1)) // ≤ 2**(e-3) / 3 // ≤ 2**(e-3-log2(3)) // ≤ 2**(e-4.5) // // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n: // ε_{n+1} = ε_n² / | (2 * x_n) | // ≤ (2**(e-k))² / (2 * 2**(e-1)) // ≤ 2**(2*e-2*k) / 2**e // ≤ 2**(e-2*k) xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5) -- special case, see above xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9) -- general case with k = 4.5 xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18) -- general case with k = 9 xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36) -- general case with k = 18 xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72) -- general case with k = 36 xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144) -- general case with k = 72 // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either // sqrt(a) or sqrt(a) + 1. return xn - SafeCast.toUint(xn > a / xn); } } /** * @dev Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; uint256 exp; unchecked { exp = 128 * SafeCast.toUint(value > (1 << 128) - 1); value >>= exp; result += exp; exp = 64 * SafeCast.toUint(value > (1 << 64) - 1); value >>= exp; result += exp; exp = 32 * SafeCast.toUint(value > (1 << 32) - 1); value >>= exp; result += exp; exp = 16 * SafeCast.toUint(value > (1 << 16) - 1); value >>= exp; result += exp; exp = 8 * SafeCast.toUint(value > (1 << 8) - 1); value >>= exp; result += exp; exp = 4 * SafeCast.toUint(value > (1 << 4) - 1); value >>= exp; result += exp; exp = 2 * SafeCast.toUint(value > (1 << 2) - 1); value >>= exp; result += exp; result += SafeCast.toUint(value > 1); } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; uint256 isGt; unchecked { isGt = SafeCast.toUint(value > (1 << 128) - 1); value >>= isGt * 128; result += isGt * 16; isGt = SafeCast.toUint(value > (1 << 64) - 1); value >>= isGt * 64; result += isGt * 8; isGt = SafeCast.toUint(value > (1 << 32) - 1); value >>= isGt * 32; result += isGt * 4; isGt = SafeCast.toUint(value > (1 << 16) - 1); value >>= isGt * 16; result += isGt * 2; result += SafeCast.toUint(value > (1 << 8) - 1); } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } } pragma solidity ^0.8.20; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. * * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute * one branch when needed, making this function more expensive. */ function ternary(bool condition, int256 a, int256 b) internal pure returns (int256) { unchecked { // branchless ternary works because: // b ^ (a ^ b) == a // b ^ 0 == b return b ^ ((a ^ b) * int256(SafeCast.toUint(condition))); } } /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return ternary(a > b, a, b); } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return ternary(a < b, a, b); } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // Formula from the "Bit Twiddling Hacks" by Sean Eron Anderson. // Since `n` is a signed integer, the generated bytecode will use the SAR opcode to perform the right shift, // taking advantage of the most significant (or "sign" bit) in two's complement representation. // This opcode adds new most significant bits set to the value of the previous most significant bit. As a result, // the mask will either be `bytes32(0)` (if n is positive) or `~bytes32(0)` (if n is negative). int256 mask = n >> 255; // A `bytes32(0)` mask leaves the input unchanged, while a `~bytes32(0)` mask complements it. return uint256((n + mask) ^ mask); } } } pragma solidity ^0.8.20; /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; assembly ("memory-safe") { ptr := add(buffer, add(32, length)) } while (true) { ptr--; assembly ("memory-safe") { mstore8(ptr, byte(mod(value, 10), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { uint256 localValue = value; bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = HEX_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal * representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH); } /** * @dev Converts an `address` with fixed length of 20 bytes to its checksummed ASCII `string` hexadecimal * representation, according to EIP-55. */ function toChecksumHexString(address addr) internal pure returns (string memory) { bytes memory buffer = bytes(toHexString(addr)); // hash the hex part of buffer (skip length + 2 bytes, length 40) uint256 hashValue; assembly ("memory-safe") { hashValue := shr(96, keccak256(add(buffer, 0x22), 40)) } for (uint256 i = 41; i > 1; --i) { // possible values for buffer[i] are 48 (0) to 57 (9) and 97 (a) to 102 (f) if (hashValue & 0xf > 7 && uint8(buffer[i]) > 96) { // case shift by xoring with 0x20 buffer[i] ^= 0x20; } hashValue >>= 4; } return string(buffer); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } } pragma solidity ^0.8.20; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` */ abstract contract ERC165Upgradeable is Initializable, IERC165 { function __ERC165_init() internal onlyInitializing { } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } } pragma solidity ^0.8.20; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC-721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ abstract contract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721, IERC721Metadata, IERC721Errors { using Strings for uint256; /// @custom:storage-location erc7201:openzeppelin.storage.ERC721 struct ERC721Storage { // Token name string _name; // Token symbol string _symbol; mapping(uint256 tokenId => address) _owners; mapping(address owner => uint256) _balances; mapping(uint256 tokenId => address) _tokenApprovals; mapping(address owner => mapping(address operator => bool)) _operatorApprovals; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ERC721")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant ERC721StorageLocation = 0x80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079300; function _getERC721Storage() private pure returns (ERC721Storage storage $) { assembly { $.slot := ERC721StorageLocation } } /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing { __ERC721_init_unchained(name_, symbol_); } function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { ERC721Storage storage $ = _getERC721Storage(); $._name = name_; $._symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual returns (uint256) { ERC721Storage storage $ = _getERC721Storage(); if (owner == address(0)) { revert ERC721InvalidOwner(address(0)); } return $._balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual returns (address) { return _requireOwned(tokenId); } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual returns (string memory) { ERC721Storage storage $ = _getERC721Storage(); return $._name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual returns (string memory) { ERC721Storage storage $ = _getERC721Storage(); return $._symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual returns (string memory) { _requireOwned(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string.concat(baseURI, tokenId.toString()) : ""; } /** * @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, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual { _approve(to, tokenId, _msgSender()); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual returns (address) { _requireOwned(tokenId); return _getApproved(tokenId); } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual returns (bool) { ERC721Storage storage $ = _getERC721Storage(); return $._operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } // Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here. address previousOwner = _update(to, tokenId, _msgSender()); if (previousOwner != from) { revert ERC721IncorrectOwner(from, tokenId, previousOwner); } } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual { transferFrom(from, to, tokenId); ERC721Utils.checkOnERC721Received(_msgSender(), from, to, tokenId, data); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist * * IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the * core ERC-721 logic MUST be matched with the use of {_increaseBalance} to keep balances * consistent with ownership. The invariant to preserve is that for any address `a` the value returned by * `balanceOf(a)` must be equal to the number of tokens such that `_ownerOf(tokenId)` is `a`. */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { ERC721Storage storage $ = _getERC721Storage(); return $._owners[tokenId]; } /** * @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted. */ function _getApproved(uint256 tokenId) internal view virtual returns (address) { ERC721Storage storage $ = _getERC721Storage(); return $._tokenApprovals[tokenId]; } /** * @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in * particular (ignoring whether it is owned by `owner`). * * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this * assumption. */ function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) { return spender != address(0) && (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender); } /** * @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner. * Reverts if: * - `spender` does not have approval from `owner` for `tokenId`. * - `spender` does not have approval to manage all of `owner`'s assets. * * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this * assumption. */ function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual { if (!_isAuthorized(owner, spender, tokenId)) { if (owner == address(0)) { revert ERC721NonexistentToken(tokenId); } else { revert ERC721InsufficientApproval(spender, tokenId); } } } /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that * a uint256 would ever overflow from increments when these increments are bounded to uint128 values. * * WARNING: Increasing an account's balance using this function tends to be paired with an override of the * {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership * remain consistent with one another. */ function _increaseBalance(address account, uint128 value) internal virtual { ERC721Storage storage $ = _getERC721Storage(); unchecked { $._balances[account] += value; } } /** * @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner * (or `to`) is the zero address. Returns the owner of the `tokenId` before the update. * * The `auth` argument is optional. If the value passed is non 0, then this function will check that * `auth` is either the owner of the token, or approved to operate on the token (by the owner). * * Emits a {Transfer} event. * * NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}. */ function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) { ERC721Storage storage $ = _getERC721Storage(); address from = _ownerOf(tokenId); // Perform (optional) operator check if (auth != address(0)) { _checkAuthorized(from, auth, tokenId); } // Execute the update if (from != address(0)) { // Clear approval. No need to re-authorize or emit the Approval event _approve(address(0), tokenId, address(0), false); unchecked { $._balances[from] -= 1; } } if (to != address(0)) { unchecked { $._balances[to] += 1; } } $._owners[tokenId] = to; emit Transfer(from, to, tokenId); return from; } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } address previousOwner = _update(to, tokenId, address(0)); if (previousOwner != address(0)) { revert ERC721InvalidSender(address(0)); } } /** * @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual { _mint(to, tokenId); ERC721Utils.checkOnERC721Received(_msgSender(), address(0), to, tokenId, data); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal { address previousOwner = _update(address(0), tokenId, address(0)); if (previousOwner == address(0)) { revert ERC721NonexistentToken(tokenId); } } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } address previousOwner = _update(to, tokenId, address(0)); if (previousOwner == address(0)) { revert ERC721NonexistentToken(tokenId); } else if (previousOwner != from) { revert ERC721IncorrectOwner(from, tokenId, previousOwner); } } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients * are aware of the ERC-721 standard to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is like {safeTransferFrom} in the sense that it invokes * {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `tokenId` token must exist and be owned by `from`. * - `to` cannot be the zero address. * - `from` cannot be the zero address. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId) internal { _safeTransfer(from, to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { _transfer(from, to, tokenId); ERC721Utils.checkOnERC721Received(_msgSender(), from, to, tokenId, data); } /** * @dev Approve `to` to operate on `tokenId` * * The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is * either the owner of the token, or approved to operate on all tokens held by this owner. * * Emits an {Approval} event. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address to, uint256 tokenId, address auth) internal { _approve(to, tokenId, auth, true); } /** * @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not * emitted in the context of transfers. */ function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual { ERC721Storage storage $ = _getERC721Storage(); // Avoid reading the owner unless necessary if (emitEvent || auth != address(0)) { address owner = _requireOwned(tokenId); // We do not use _isAuthorized because single-token approvals should not be able to call approve if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) { revert ERC721InvalidApprover(auth); } if (emitEvent) { emit Approval(owner, to, tokenId); } } $._tokenApprovals[tokenId] = to; } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Requirements: * - operator can't be the address zero. * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { ERC721Storage storage $ = _getERC721Storage(); if (operator == address(0)) { revert ERC721InvalidOperator(operator); } $._operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned). * Returns the owner. * * Overrides to ownership logic should be done to {_ownerOf}. */ function _requireOwned(uint256 tokenId) internal view returns (address) { address owner = _ownerOf(tokenId); if (owner == address(0)) { revert ERC721NonexistentToken(tokenId); } return owner; } } pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); } pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20PermitUpgradeable { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } 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); } } } pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20Upgradeable { using AddressUpgradeable for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20Upgradeable token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20PermitUpgradeable token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token)); } } pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal onlyInitializing { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal onlyInitializing { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } /** * @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; } pragma solidity ^0.8.0; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } /** * @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; } pragma solidity ^0.8.20; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { /// @custom:storage-location erc7201:openzeppelin.storage.Ownable struct OwnableStorage { address _owner; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300; function _getOwnableStorage() private pure returns (OwnableStorage storage $) { assembly { $.slot := OwnableStorageLocation } } /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ function __Ownable_init(address initialOwner) internal onlyInitializing { __Ownable_init_unchained(initialOwner); } function __Ownable_init_unchained(address initialOwner) internal onlyInitializing { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { OwnableStorage storage $ = _getOwnableStorage(); return $._owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { OwnableStorage storage $ = _getOwnableStorage(); address oldOwner = $._owner; $._owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } pragma solidity 0.8.27; interface IRewardsDistributor { function claim(uint256 tokenId) external returns (uint256); function claimable(uint256 tokenId) external view returns (uint256); function checkpoint_token() external; function checkpoint_total_supply() external; function getRewardForDuration() external view returns (uint256); } contract VeSixUpgradeable is ERC721Upgradeable, ReentrancyGuardUpgradeable, PausableUpgradeable, OwnableUpgradeable { using SafeERC20Upgradeable for IERC20Upgradeable; // Custom errors error InvalidAmount(); error InvalidDuration(); error TransferFailed(); error NotTokenOwner(); error LockNotExpired(); error ZeroReward(); error InvalidToken(); error InvalidArtProxy(); error ZeroAddress(); error DeadlineExpired(); error LockExpired(); error ExceedsMaxLocks(); error InvalidRewardRate(); error SlippageExceeded(); error MaxRewardRateExceeded(); error TokenNotExists(); error LockNotExists(); error MultiplierTooHigh(); error InvalidMultiplier(); error ArithmeticError(); struct Point { int128 bias; // Current farming power int128 slope; // Farming power decrease rate uint32 ts; // Timestamp of point uint32 blk; // Block number } struct LockedBalance { int128 amount; uint32 end; } struct LockPosition { uint128 amount; uint128 slope; uint32 endTime; uint32 lastUpdate; } // Constants uint32 private constant MAXTIME = 180 days; uint32 private constant WEEK = 7 * 86400; uint128 private constant MAX_MULTIPLIER = 4e18; uint128 private constant BASE_MULTIPLIER = 1e18; uint128 private constant PRECISION = 1e18; uint8 private constant MAX_LOCKS_PER_USER = 100; uint128 private constant MAX_REWARD_RATE = 1000e18; int128 private constant iMAXTIME = int128(uint128(MAXTIME)); // State variables IERC20Upgradeable private _lockedToken; IRewardsDistributor private _distributor; uint32 private _nextTokenId; mapping(uint256 => LockPosition) public _locks; mapping(address => uint8) public _userLockCount; // Point history state mapping(uint32 => Point) public pointHistory; uint32 public epoch; mapping(uint256 => uint32) public userPointEpoch; mapping(uint256 => mapping(uint32 => Point)) public userPointHistory; mapping(uint32 => int128) public slopeChanges; address public artProxy; uint32 MAX_BLOCK_DRIFT = 15; uint128 private _totalWeightedSupply; // Emergency recovery address private _emergencyRecoveryAddress; bool private _emergencyMode; // Events event Deposit( address indexed user, uint256 indexed tokenId, uint128 amount, uint32 lockTime ); event Withdraw( address indexed user, uint256 indexed tokenId, uint128 amount ); event RewardClaimed( address indexed user, uint256 indexed tokenId, uint128 reward ); event EmergencyModeEnabled(address recoveryAddress); event EmergencyWithdraw( address indexed user, uint256 indexed tokenId, uint128 amount ); event LockExtended( address indexed user, uint256 indexed tokenId, uint32 newEndTime, uint128 newMultiplier ); event AmountIncreased( address indexed user, uint256 indexed tokenId, uint128 additionalAmount, uint128 newTotalAmount, uint128 newMultiplier ); mapping(uint256 => uint256) public tokenEpoch; // tokenId => creation epoch // Storage gap for future upgrades uint256[50] private __gap; /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } function initialize( address lockedToken_, address emergencyRecovery, string memory name, string memory symbol ) public initializer { if (lockedToken_ == address(0) || emergencyRecovery == address(0)) revert ZeroAddress(); __ERC721_init(name, symbol); __ReentrancyGuard_init(); __Pausable_init(); __Ownable_init(msg.sender); _pause(); _lockedToken = IERC20Upgradeable(lockedToken_); _emergencyRecoveryAddress = emergencyRecovery; // Initialize point history pointHistory[0].blk = uint32(block.number); pointHistory[0].ts = uint32(block.timestamp); } function setDistributor(address distributor_) external onlyOwner { if (distributor_ == address(0)) revert ZeroAddress(); if (address(_distributor) != address(0)) revert("Distributor already set"); _distributor = IRewardsDistributor(distributor_); } // Modifiers modifier validDeadline(uint256 deadline) { if (block.timestamp > deadline) revert DeadlineExpired(); _; } modifier checkRewardRate() { if (_distributor.getRewardForDuration() > MAX_REWARD_RATE) revert MaxRewardRateExceeded(); _; } function getCurrentMultiplier(uint256 tokenId) public view returns (uint128) { LockPosition memory lock = _locks[tokenId]; if (uint32(block.timestamp) >= lock.endTime) return BASE_MULTIPLIER; // Recalculate slope properly with PRECISION scaling uint256 slopeCalc = (uint256(lock.amount) * (MAX_MULTIPLIER - BASE_MULTIPLIER)) / (MAXTIME * PRECISION); if (slopeCalc > type(uint128).max) revert InvalidAmount(); uint128 slope = uint128(slopeCalc); uint32 timeLeft = lock.endTime - uint32(block.timestamp); uint128 multiplier = uint128(BASE_MULTIPLIER + (uint256(slope) * timeLeft)); if (multiplier > MAX_MULTIPLIER) return MAX_MULTIPLIER; if (multiplier < BASE_MULTIPLIER) return BASE_MULTIPLIER; return multiplier; } function _checkpoint( uint256 tokenId, LockedBalance memory oldLocked, LockedBalance memory newLocked ) internal { _checkpointGlobal(); if (tokenId != 0) { _checkpointToken( tokenId, oldLocked, newLocked ); } } function _checkpointGlobal() internal { uint32 _epoch = epoch; Point memory lastPoint; if (_epoch > 0) { lastPoint = pointHistory[_epoch - 1]; } else { lastPoint = Point({ bias: 0, slope: 0, ts: uint32(block.timestamp), blk: uint32(block.number) }); } uint32 lastCheckpoint = lastPoint.ts; uint128 blockSlope = 0; if (uint32(block.timestamp) > lastCheckpoint) { blockSlope = uint128((PRECISION * (block.number - lastPoint.blk)) / (block.timestamp - lastPoint.ts)); } // Process weekly checkpoints lastPoint = _processWeeklyCheckpoints( lastPoint, lastCheckpoint, blockSlope, _epoch ); epoch = _epoch + 1; } function _processWeeklyCheckpoints( Point memory lastPoint, uint32 lastCheckpoint, uint128 blockSlope, uint32 _epoch ) internal returns (Point memory) { Point memory initialLastPoint = lastPoint; uint32 ti = (lastCheckpoint / WEEK) * WEEK; for (uint256 i = 0; i < 255; ++i) { ti += WEEK; int128 dslope = 0; if (ti > uint32(block.timestamp)) { ti = uint32(block.timestamp); } else { dslope = slopeChanges[ti]; } lastPoint.bias -= lastPoint.slope * int128(uint128(ti - lastCheckpoint)); lastPoint.slope += dslope; lastPoint.ts = ti; lastPoint.blk = uint32(initialLastPoint.blk + (uint256(blockSlope) * (ti - initialLastPoint.ts)) / PRECISION); if (ti == uint32(block.timestamp)) { lastPoint.blk = uint32(block.number); break; } else { pointHistory[_epoch + 1 + uint32(i)] = lastPoint; } lastCheckpoint = ti; } return lastPoint; } function _checkpointToken( uint256 tokenId, LockedBalance memory oldLocked, LockedBalance memory newLocked ) internal { Point memory uOld; Point memory uNew; if (oldLocked.end > uint32(block.timestamp) && oldLocked.amount > 0) { uOld.slope = oldLocked.amount / iMAXTIME; uOld.bias = uOld.slope * int128(uint128(oldLocked.end - uint32(block.timestamp))); } if (newLocked.end > uint32(block.timestamp) && newLocked.amount > 0) { uNew.slope = newLocked.amount / iMAXTIME; uNew.bias = uNew.slope * int128(uint128(newLocked.end - uint32(block.timestamp))); } _processTokenSlopeChanges( oldLocked, newLocked, uOld.slope, uNew.slope ); uint32 userEpoch = userPointEpoch[tokenId] + 1; userPointEpoch[tokenId] = userEpoch; uNew.ts = uint32(block.timestamp); uNew.blk = uint32(block.number); userPointHistory[tokenId][userEpoch] = uNew; } function _processTokenSlopeChanges( LockedBalance memory oldLocked, LockedBalance memory newLocked, int128 oldSlope, int128 newSlope ) internal { if (oldLocked.end > uint32(block.timestamp)) { int128 oldDslope = slopeChanges[oldLocked.end]; oldDslope += oldSlope; if (newLocked.end == oldLocked.end) { oldDslope -= newSlope; } slopeChanges[oldLocked.end] = oldDslope; } if (newLocked.end > uint32(block.timestamp)) { if (newLocked.end > oldLocked.end) { int128 newDslope = slopeChanges[newLocked.end]; newDslope -= newSlope; slopeChanges[newLocked.end] = newDslope; } } } function _beforeTokenTransfer( address from, uint256 tokenId ) internal { if (from != address(0) && address(_distributor) != address(0)) { // Skip if minting _distributor.claim(tokenId); } } function transferFrom(address from, address to, uint256 tokenId) public virtual override { _beforeTokenTransfer(from, tokenId); super.transferFrom(from,to, tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override { _beforeTokenTransfer(from, tokenId); super.safeTransferFrom(from, to, tokenId, data); } function withdraw(uint256 tokenId) external nonReentrant { address owner = _ownerOf(tokenId); if (owner == address(0)) revert TokenNotExists(); if (owner != msg.sender) revert NotTokenOwner(); LockPosition memory lock = _locks[tokenId]; if (lock.amount == 0) revert LockNotExists(); if (uint32(block.timestamp) < lock.endTime) revert LockNotExpired(); uint128 amount = lock.amount; LockedBalance memory oldLock = LockedBalance({ amount: int128(uint128(amount)), end: lock.endTime }); delete _locks[tokenId]; uint128 multiplier = getCurrentMultiplier(tokenId); uint256 weightedAmount = (uint256(amount) * uint256(multiplier)) / PRECISION; if (weightedAmount / uint256(amount) != uint256(multiplier)) revert ArithmeticError(); uint256 weightedSupplyIncrease = weightedAmount / PRECISION; if (weightedSupplyIncrease > type(uint128).max) revert InvalidAmount(); _totalWeightedSupply -= uint128(weightedSupplyIncrease); _checkpoint(tokenId, oldLock, LockedBalance(0, 0)); delete userPointEpoch[tokenId]; _burn(tokenId); unchecked { _userLockCount[msg.sender]--; } _lockedToken.safeTransfer(msg.sender, amount); emit Withdraw(msg.sender, tokenId, amount); } function _calculateLockParameters( uint128 amount, uint32 lockDuration, uint128 minMultiplier ) internal pure returns (uint128 slope, uint128 multiplier) { // First scale down amount by PRECISION uint256 scaledAmount = uint256(amount) / PRECISION; // = 6.48 // Calculate slope with better scaling // Instead of: slopeCalc = (scaledAmount * multiplierDiff) / MAXTIME // Use: slopeCalc = (scaledAmount * multiplierDiff) / (MAXTIME * PRECISION) uint256 multiplierDiff = MAX_MULTIPLIER - BASE_MULTIPLIER; // = 3e18 uint256 slopeCalc = (scaledAmount * multiplierDiff) / (MAXTIME * PRECISION); if (slopeCalc > type(uint128).max) revert InvalidAmount(); slope = uint128(slopeCalc); // Calculate multiplier with additional scaling uint256 multiplierIncrease = (uint256(slope) * lockDuration) / PRECISION; multiplier = uint128(BASE_MULTIPLIER + multiplierIncrease); if (multiplier > MAX_MULTIPLIER) revert MultiplierTooHigh(); if (multiplier < minMultiplier) revert SlippageExceeded(); } function _updateWeightedSupply(uint128 amount, uint128 multiplier) internal { uint256 weightedAmount = uint256(amount) * uint256(multiplier) / PRECISION; _totalWeightedSupply += uint128(weightedAmount); } function createLock( uint128 amount, uint32 lockDuration, uint256 deadline, uint128 minMultiplier ) external nonReentrant whenNotPaused validDeadline(deadline) returns (uint256 tokenId) { if (amount == 0) revert InvalidAmount(); if (lockDuration == 0 || lockDuration > MAXTIME) revert InvalidDuration(); if (_userLockCount[msg.sender] >= MAX_LOCKS_PER_USER) revert ExceedsMaxLocks(); uint32 unlockTime = uint32(block.timestamp) + lockDuration; (uint128 slope, uint128 multiplier) = _calculateLockParameters(amount, lockDuration, minMultiplier); // Create new lock balance LockedBalance memory newLock = LockedBalance({ amount: int128(uint128(amount)), end: unlockTime }); // Checkpoint before modifying state _checkpoint(0, LockedBalance(0, 0), newLock); // Transfer tokens using SafeERC20 uint256 balanceBefore = _lockedToken.balanceOf(address(this)); _lockedToken.safeTransferFrom(msg.sender, address(this), amount); if (_lockedToken.balanceOf(address(this)) != balanceBefore + amount) revert TransferFailed(); unchecked { tokenId = _nextTokenId++; _userLockCount[msg.sender]++; } _safeMint(msg.sender, tokenId); _locks[tokenId] = LockPosition({ amount: amount, endTime: unlockTime, lastUpdate: uint32(block.timestamp), slope: slope }); _updateWeightedSupply(amount, multiplier); emit Deposit(msg.sender, tokenId, amount, unlockTime); } function extendLock( uint256 tokenId, uint32 additionalDuration, uint256 deadline, uint128 minMultiplier ) external nonReentrant whenNotPaused validDeadline(deadline) { if (ownerOf(tokenId) != msg.sender) revert NotTokenOwner(); LockPosition memory lock = _locks[tokenId]; if (lock.amount == 0) revert LockNotExists(); // Calculate new end time uint32 newEndTime = lock.endTime + additionalDuration; uint32 totalRemainingDuration = newEndTime - uint32(block.timestamp); if (totalRemainingDuration > MAXTIME) revert InvalidDuration(); // Calculate new slope and multiplier with proper scaling uint128 newSlope = _calculateNewSlope(lock.amount); uint128 multiplier = _calculateMultiplier(newSlope, totalRemainingDuration); if (multiplier < minMultiplier) revert SlippageExceeded(); // Update weighted supply _updateWeightedSupply( lock.amount, multiplier ); // Checkpoint _checkpoint( tokenId, LockedBalance(int128(uint128(lock.amount)), lock.endTime), LockedBalance(int128(uint128(lock.amount)), newEndTime) ); // Update lock state _locks[tokenId] = LockPosition({ amount: lock.amount, endTime: newEndTime, lastUpdate: uint32(block.timestamp), slope: newSlope }); emit LockExtended(msg.sender, tokenId, newEndTime, multiplier); } function increaseLockAmount( uint256 tokenId, uint128 additionalAmount, uint256 deadline, uint128 minMultiplier ) external nonReentrant whenNotPaused validDeadline(deadline) { if (ownerOf(tokenId) != msg.sender) revert NotTokenOwner(); if (additionalAmount == 0) revert InvalidAmount(); LockPosition memory lock = _locks[tokenId]; if (lock.amount == 0) revert LockNotExists(); if (uint32(block.timestamp) >= lock.endTime) revert LockExpired(); uint128 newAmount = lock.amount + additionalAmount; uint128 newSlope = _calculateNewSlope(newAmount); uint32 remainingDuration = lock.endTime - uint32(block.timestamp); uint128 multiplier = uint128(BASE_MULTIPLIER + (uint256(newSlope) * remainingDuration)); if (multiplier > MAX_MULTIPLIER) revert MultiplierTooHigh(); if (multiplier < minMultiplier) revert SlippageExceeded(); // Transfer tokens uint256 balanceBefore = _lockedToken.balanceOf(address(this)); _lockedToken.safeTransferFrom(msg.sender, address(this), additionalAmount); if (_lockedToken.balanceOf(address(this)) != balanceBefore + additionalAmount) revert TransferFailed(); // Update weighted supply _updateWeightedSupply( lock.amount, multiplier ); // Checkpoint _checkpoint( tokenId, LockedBalance(int128(uint128(lock.amount)), lock.endTime), LockedBalance(int128(uint128(newAmount)), lock.endTime) ); // Update lock state _locks[tokenId] = LockPosition({ amount: newAmount, endTime: lock.endTime, lastUpdate: uint32(block.timestamp), slope: newSlope }); emit AmountIncreased(msg.sender, tokenId, additionalAmount, newAmount, multiplier); } function getTotalFarmingPower(uint32 timestamp) public view returns (uint128) { Point memory lastPoint = pointHistory[epoch]; return uint128(_supplyAt(lastPoint, timestamp)); } function _supplyAt(Point memory point, uint32 t) internal view returns (uint128) { Point memory lastPoint = point; uint32 ti = (lastPoint.ts / WEEK) * WEEK; for (uint256 i = 0; i < 255; ++i) { ti += WEEK; int128 dslope = 0; if (ti > t) { ti = t; } else { dslope = slopeChanges[ti]; } lastPoint.bias -= lastPoint.slope * int128(uint128(ti - lastPoint.ts)); if (ti == t) { break; } lastPoint.slope += dslope; lastPoint.ts = ti; } if (lastPoint.bias < 0) { lastPoint.bias = 0; } return uint128(uint256(uint128(lastPoint.bias))); } function _calculateNewSlope(uint128 amount) private pure returns (uint128) { uint256 value = uint256(amount); uint256 slopeCalc = value / MAXTIME; if (slopeCalc > type(uint128).max) revert InvalidAmount(); return uint128(slopeCalc); } function _calculateMultiplier(uint128 slope, uint32 duration) internal pure returns (uint128) { // Calculate bias like veRAM uint256 bias = uint256(slope) * duration; // Convert to multiplier (1x-4x range) uint256 multiplier = BASE_MULTIPLIER + ((bias * (MAX_MULTIPLIER - BASE_MULTIPLIER)) / (uint256(slope) * MAXTIME)); if (multiplier > MAX_MULTIPLIER) return MAX_MULTIPLIER; if (multiplier < BASE_MULTIPLIER) return BASE_MULTIPLIER; return uint128(multiplier); } function merge( uint256[] calldata tokenIds, uint256 deadline ) external nonReentrant whenNotPaused validDeadline(deadline) { if (tokenIds.length < 2) revert InvalidAmount(); uint128 totalAmount; uint32 latestEndTime; // First pass: validate ownership and calculate totals for (uint256 i = 0; i < tokenIds.length; i++) { if (ownerOf(tokenIds[i]) != msg.sender) revert NotTokenOwner(); LockPosition memory lock = _locks[tokenIds[i]]; totalAmount += lock.amount; if (lock.endTime > latestEndTime) { latestEndTime = lock.endTime; } } // Create new merged position uint32 remainingDuration = latestEndTime - uint32(block.timestamp); if (remainingDuration > MAXTIME) revert InvalidDuration(); uint256 slopeCalc = (uint256(totalAmount) * (MAX_MULTIPLIER - BASE_MULTIPLIER)) / MAXTIME; if (slopeCalc > type(uint128).max) revert InvalidAmount(); uint128 newSlope = uint128(slopeCalc); uint256 newTokenId = ++_nextTokenId; _safeMint(msg.sender, newTokenId); // Checkpoint and cleanup old positions for (uint256 i = 0; i < tokenIds.length; i++) { uint256 tokenId = tokenIds[i]; LockPosition memory oldLock = _locks[tokenId]; LockedBalance memory oldLockedBalance = LockedBalance({ amount: int128(uint128(oldLock.amount)), end: oldLock.endTime }); _checkpoint(tokenId, oldLockedBalance, LockedBalance(0, 0)); delete _locks[tokenId]; _burn(tokenId); } // Create new lock LockedBalance memory newLock = LockedBalance({ amount: int128(uint128(totalAmount)), end: latestEndTime }); _checkpoint(newTokenId, LockedBalance(0, 0), newLock); _locks[newTokenId] = LockPosition({ amount: totalAmount, endTime: latestEndTime, lastUpdate: uint32(block.timestamp), slope: newSlope }); unchecked { _userLockCount[msg.sender] = uint8(_userLockCount[msg.sender] - uint8(tokenIds.length) + 1); } emit Deposit(msg.sender, newTokenId, totalAmount, latestEndTime); } function getFarmingPower(uint256 tokenId, uint32 timestamp) public view returns (uint128) { uint32 userEpoch = userPointEpoch[tokenId]; if (userEpoch == 0) return 0; Point memory lastPoint = userPointHistory[tokenId][userEpoch]; lastPoint.bias -= lastPoint.slope * int128(uint128(timestamp - lastPoint.ts)); if (lastPoint.bias < 0) { lastPoint.bias = 0; } return uint128(uint256(uint128(lastPoint.bias))); } function getMinMultiplier(uint128 amount, uint32 lockDuration) public view returns (uint128) { // Reduce duration by max block drift uint32 minDuration = lockDuration > MAX_BLOCK_DRIFT ? lockDuration - MAX_BLOCK_DRIFT : lockDuration; // Calculate multiplier with reduced duration uint256 slopeCalc = (uint256(amount) * (MAX_MULTIPLIER - BASE_MULTIPLIER)) / MAXTIME; uint128 slope = uint128(slopeCalc); return uint128(BASE_MULTIPLIER + (uint256(slope) * minDuration)); } // Emergency functions function enableEmergencyMode() external onlyOwner { _emergencyMode = true; _pause(); emit EmergencyModeEnabled(_emergencyRecoveryAddress); } function emergencyWithdraw(uint256 tokenId) external nonReentrant { require(_emergencyMode, "Not in emergency mode"); if (ownerOf(tokenId) != msg.sender) revert NotTokenOwner(); LockPosition memory lock = _locks[tokenId]; uint128 amount = lock.amount; delete _locks[tokenId]; _burn(tokenId); unchecked { _userLockCount[msg.sender]--; } _lockedToken.safeTransfer(msg.sender, amount); emit EmergencyWithdraw(msg.sender, tokenId, amount); } function unPause () external onlyOwner { _unpause(); } // View functions function getUserLockCount(address user) external view returns (uint8) { return _userLockCount[user]; } function lockedToken() external view returns (IERC20Upgradeable) { return _lockedToken; } function isEmergencyMode() external view returns (bool) { return _emergencyMode; } function totalWeightedSupply() external view returns (uint128) { return _totalWeightedSupply; } function setArtProxy(address _artProxy) external onlyOwner { if (_artProxy == address(0)) revert ZeroAddress(); artProxy = _artProxy; } function tokensForOwner(address owner) external view returns(uint256[] memory tokenIds) { uint8 count = _userLockCount[owner]; tokenIds = new uint256[](count); if (count == 0) return tokenIds; uint256 currentIndex = 0; for (uint256 id = 0; id < _nextTokenId; id++) { if (_ownerOf(id) == owner) { tokenIds[currentIndex] = id; currentIndex++; if (currentIndex >= count) break; } } return tokenIds; } function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (_ownerOf(tokenId) == address(0)) revert TokenNotExists(); if (artProxy == address(0)) revert InvalidArtProxy(); // Delegate tokenURI call to art proxy (bool success, bytes memory data) = artProxy.staticcall( abi.encodeWithSignature("tokenURI(uint256)", tokenId) ); require(success, "Art proxy call failed"); return abi.decode(data, (string)); } function getExpectedMultiplier(uint128 amount, uint32 duration) public pure returns (uint128) { if (duration == 0 || duration > MAXTIME) revert InvalidDuration(); if (amount == 0) revert InvalidAmount(); uint128 slope = _calculateNewSlope(amount); return _calculateMultiplier(slope, duration); } function getExpectedExtendedMultiplier(uint256 tokenId, uint32 additionalDuration) public view returns (uint128) { if (additionalDuration == 0) revert InvalidDuration(); LockPosition memory lock = _locks[tokenId]; if (lock.amount == 0) revert LockNotExists(); uint32 newEndTime = lock.endTime + additionalDuration; uint32 remainingDuration = newEndTime - uint32(block.timestamp); if (remainingDuration > MAXTIME) revert InvalidDuration(); uint128 slope = _calculateNewSlope(lock.amount); return _calculateMultiplier(slope, remainingDuration); } function adminRecalculateAllLocks(uint256 startId, uint256 endId) external onlyOwner { if (endId > _nextTokenId) { endId = _nextTokenId; } uint256 batchSize = endId - startId; if (batchSize > 100) revert(); // Prevent gas issues for (uint256 tokenId = startId; tokenId < endId; tokenId++) { // Skip if token doesn't exist or is expired if (_ownerOf(tokenId) == address(0)) continue; LockPosition memory lock = _locks[tokenId]; if (lock.amount == 0 || uint32(block.timestamp) >= lock.endTime) continue; // Recalculate slope using veRAM's method uint256 value = uint256(lock.amount); uint256 slopeCalc = value / MAXTIME; if (slopeCalc > type(uint128).max) continue; // Skip invalid amounts uint128 newSlope = uint128(slopeCalc); // Skip if slope is already correct if (lock.slope == newSlope) continue; // Calculate new multiplier uint32 remainingDuration = lock.endTime - uint32(block.timestamp); uint256 bias = uint256(newSlope) * remainingDuration; uint256 multiplier = BASE_MULTIPLIER + ((bias * (MAX_MULTIPLIER - BASE_MULTIPLIER)) / (uint256(newSlope) * MAXTIME)); if (multiplier > MAX_MULTIPLIER) multiplier = MAX_MULTIPLIER; if (multiplier < BASE_MULTIPLIER) multiplier = BASE_MULTIPLIER; // Checkpoint and update _checkpoint( tokenId, LockedBalance(int128(uint128(lock.amount)), lock.endTime), LockedBalance(int128(uint128(lock.amount)), lock.endTime) ); _locks[tokenId] = LockPosition({ amount: lock.amount, endTime: lock.endTime, lastUpdate: uint32(block.timestamp), slope: newSlope }); emit LockExtended( _ownerOf(tokenId), tokenId, lock.endTime, uint128(multiplier) ); } } // Helper view function also needs the same fix function checkLocksNeedingRecalculation(uint256 startId, uint256 endId) external view returns (uint256) { if (endId > _nextTokenId) { endId = _nextTokenId; } uint256 count = 0; for (uint256 tokenId = startId; tokenId < endId; tokenId++) { if (_ownerOf(tokenId) == address(0)) continue; LockPosition memory lock = _locks[tokenId]; if (lock.amount == 0 || uint32(block.timestamp) >= lock.endTime) continue; uint256 value = uint256(lock.amount); uint256 slopeCalc = value / MAXTIME; if (slopeCalc > type(uint128).max) continue; uint128 newSlope = uint128(slopeCalc); if (lock.slope != newSlope) count++; } return count; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ArithmeticError","type":"error"},{"inputs":[],"name":"DeadlineExpired","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721IncorrectOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721InsufficientApproval","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC721InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC721InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721InvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC721InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC721InvalidSender","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721NonexistentToken","type":"error"},{"inputs":[],"name":"ExceedsMaxLocks","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidArtProxy","type":"error"},{"inputs":[],"name":"InvalidDuration","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"InvalidMultiplier","type":"error"},{"inputs":[],"name":"InvalidRewardRate","type":"error"},{"inputs":[],"name":"InvalidToken","type":"error"},{"inputs":[],"name":"LockExpired","type":"error"},{"inputs":[],"name":"LockNotExists","type":"error"},{"inputs":[],"name":"LockNotExpired","type":"error"},{"inputs":[],"name":"MaxRewardRateExceeded","type":"error"},{"inputs":[],"name":"MultiplierTooHigh","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[],"name":"NotTokenOwner","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"SlippageExceeded","type":"error"},{"inputs":[],"name":"TokenNotExists","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroReward","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"additionalAmount","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"newTotalAmount","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"newMultiplier","type":"uint128"}],"name":"AmountIncreased","type":"event"},{"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":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"amount","type":"uint128"},{"indexed":false,"internalType":"uint32","name":"lockTime","type":"uint32"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"recoveryAddress","type":"address"}],"name":"EmergencyModeEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"amount","type":"uint128"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"newEndTime","type":"uint32"},{"indexed":false,"internalType":"uint128","name":"newMultiplier","type":"uint128"}],"name":"LockExtended","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":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"reward","type":"uint128"}],"name":"RewardClaimed","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":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"amount","type":"uint128"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_locks","outputs":[{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint128","name":"slope","type":"uint128"},{"internalType":"uint32","name":"endTime","type":"uint32"},{"internalType":"uint32","name":"lastUpdate","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_userLockCount","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"startId","type":"uint256"},{"internalType":"uint256","name":"endId","type":"uint256"}],"name":"adminRecalculateAllLocks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"artProxy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"startId","type":"uint256"},{"internalType":"uint256","name":"endId","type":"uint256"}],"name":"checkLocksNeedingRecalculation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint32","name":"lockDuration","type":"uint32"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint128","name":"minMultiplier","type":"uint128"}],"name":"createLock","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableEmergencyMode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"epoch","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint32","name":"additionalDuration","type":"uint32"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint128","name":"minMultiplier","type":"uint128"}],"name":"extendLock","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":"uint256","name":"tokenId","type":"uint256"}],"name":"getCurrentMultiplier","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint32","name":"additionalDuration","type":"uint32"}],"name":"getExpectedExtendedMultiplier","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint32","name":"duration","type":"uint32"}],"name":"getExpectedMultiplier","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint32","name":"timestamp","type":"uint32"}],"name":"getFarmingPower","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint32","name":"lockDuration","type":"uint32"}],"name":"getMinMultiplier","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"timestamp","type":"uint32"}],"name":"getTotalFarmingPower","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserLockCount","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint128","name":"additionalAmount","type":"uint128"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint128","name":"minMultiplier","type":"uint128"}],"name":"increaseLockAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"lockedToken_","type":"address"},{"internalType":"address","name":"emergencyRecovery","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isEmergencyMode","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockedToken","outputs":[{"internalType":"contract IERC20Upgradeable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"merge","outputs":[],"stateMutability":"nonpayable","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":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"pointHistory","outputs":[{"internalType":"int128","name":"bias","type":"int128"},{"internalType":"int128","name":"slope","type":"int128"},{"internalType":"uint32","name":"ts","type":"uint32"},{"internalType":"uint32","name":"blk","type":"uint32"}],"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":"nonpayable","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":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_artProxy","type":"address"}],"name":"setArtProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"distributor_","type":"address"}],"name":"setDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"slopeChanges","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","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":"","type":"uint256"}],"name":"tokenEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensForOwner","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWeightedSupply","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"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":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"userPointEpoch","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint32","name":"","type":"uint32"}],"name":"userPointHistory","outputs":[{"internalType":"int128","name":"bias","type":"int128"},{"internalType":"int128","name":"slope","type":"int128"},{"internalType":"uint32","name":"ts","type":"uint32"},{"internalType":"uint32","name":"blk","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052606d805463ffffffff60a01b1916600f60a01b1790553480156024575f5ffd5b50602b602f565b60df565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff1615607e5760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460dc5780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b615330806100ec5f395ff3fe608060405234801561000f575f5ffd5b50600436106102cb575f3560e01c80638981be0e1161017b578063bbe33ea5116100e4578063ddacc94a1161009e578063e58f594711610079578063e58f59471461081b578063e985e9c514610840578063f2fde38b14610853578063f7b188a514610866575f5ffd5b8063ddacc94a146107e2578063df0c78ef146107f5578063df21515714610808575f5ffd5b8063bbe33ea51461076c578063bcc002251461077f578063beb83109146107a1578063c5b1c7d0146107b4578063c87b56dd146107bc578063d89dd269146107cf575f5ffd5b806395d89b411161013557806395d89b41146106cf57806397612d4b146106d757806398a3f422146106ea5780639b7d02ad14610709578063a22cb46514610746578063b88d4fde14610759575f5ffd5b80638981be0e1461058a57806389f839c61461059d5780638b25e8c1146106205780638da5cb5b146106335780638ff4249014610663578063900cf0cf146106aa575f5ffd5b8063268dc19911610237578063586c2600116101f157806370a08231116101cc57806370a082311461053b578063715018a61461055c57806375619ab5146105645780638125bae514610577575f5ffd5b8063586c2600146104e85780635c975abb1461051d5780636352211e14610528575f5ffd5b8063268dc199146104785780632e1a7d4d146104895780632e720f7d1461049c57806342842e0e146104af5780635312ea8e146104c25780635594a045146104d5575f5ffd5b80631d237a49116102885780631d237a491461037d5780631f5ab022146104025780632016a0d21461041557806320a194b81461042857806323b872dd1461043a57806324c44c5b1461044d575f5ffd5b806301ffc9a7146102cf57806306fdde03146102f7578063081812fc1461030c578063095ea7b3146103375780630f45cc811461034c57806313de148b1461035d575b5f5ffd5b6102e26102dd366004614915565b61086e565b60405190151581526020015b60405180910390f35b6102ff6108bf565b6040516102ee919061495e565b61031f61031a366004614970565b610960565b6040516001600160a01b0390911681526020016102ee565b61034a6103453660046149a2565b610974565b005b6064546001600160a01b031661031f565b61037061036b3660046149ca565b610983565b6040516102ee91906149e3565b6103cf61038b366004614a38565b606b60209081525f928352604080842090915290825290208054600190910154600f82810b92600160801b9004900b9063ffffffff80821691600160201b90041684565b60408051600f95860b81529390940b602084015263ffffffff9182169383019390935290911660608201526080016102ee565b61034a610410366004614a78565b610a78565b61034a610423366004614b80565b610db6565b606f54600160a01b900460ff166102e2565b61034a610448366004614c05565b610fb1565b61046061045b366004614a38565b610fcb565b6040516001600160801b0390911681526020016102ee565b606e546001600160801b0316610460565b61034a610497366004614970565b6110db565b61034a6104aa3660046149ca565b611404565b61034a6104bd366004614c05565b611455565b61034a6104d0366004614970565b61146f565b606d5461031f906001600160a01b031681565b61050a6104f6366004614c3f565b606c6020525f9081526040902054600f0b81565b604051600f9190910b81526020016102ee565b60325460ff166102e2565b61031f610536366004614970565b611608565b61054e6105493660046149ca565b611612565b6040519081526020016102ee565b61034a61166a565b61034a6105723660046149ca565b61167d565b61054e610585366004614c58565b611727565b61034a610598366004614c58565b611870565b6105e96105ab366004614970565b60666020525f9081526040902080546001909101546001600160801b0380831692600160801b9004169063ffffffff80821691600160201b90041684565b604080516001600160801b03958616815294909316602085015263ffffffff918216928401929092521660608201526080016102ee565b61046061062e366004614970565b611c46565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031661031f565b6103cf610671366004614c3f565b60686020525f908152604090208054600190910154600f82810b92600160801b9004900b9063ffffffff80821691600160201b90041684565b6069546106ba9063ffffffff1681565b60405163ffffffff90911681526020016102ee565b6102ff611de2565b6104606106e5366004614c3f565b611e20565b61054e6106f8366004614970565b60706020525f908152604090205481565b6107346107173660046149ca565b6001600160a01b03165f9081526067602052604090205460ff1690565b60405160ff90911681526020016102ee565b61034a610754366004614c85565b611e8c565b61034a610767366004614cba565b611e97565b61034a61077a366004614d25565b611ead565b61073461078d3660046149ca565b60676020525f908152604090205460ff1681565b61034a6107af366004614d9a565b612402565b61034a6128ef565b6102ff6107ca366004614970565b612955565b6104606107dd366004614dbd565b612aa8565b6104606107f0366004614a38565b612b21565b610460610803366004614dbd565b612bfe565b61054e610816366004614de5565b612cb2565b6106ba610829366004614970565b606a6020525f908152604090205463ffffffff1681565b6102e261084e366004614e0f565b61305c565b61034a6108613660046149ca565b6130a8565b61034a6130e2565b5f6001600160e01b031982166380ac58cd60e01b148061089e57506001600160e01b03198216635b5e139f60e01b145b806108b957506301ffc9a760e01b6001600160e01b03198316145b92915050565b5f5160206152db5f395f51905f5280546060919081906108de90614e37565b80601f016020809104026020016040519081016040528092919081815260200182805461090a90614e37565b80156109555780601f1061092c57610100808354040283529160200191610955565b820191905f5260205f20905b81548152906001019060200180831161093857829003601f168201915b505050505091505090565b5f61096a826130f2565b506108b982613129565b61097f828233613162565b5050565b6001600160a01b0381165f9081526067602052604090205460609060ff168067ffffffffffffffff8111156109ba576109ba614abb565b6040519080825280602002602001820160405280156109e3578160200160208202803683370190505b5091508060ff165f036109f65750919050565b5f805b606554600160a01b900463ffffffff16811015610a7057846001600160a01b0316610a238261316f565b6001600160a01b031603610a685780848381518110610a4457610a44614e6f565b602090810291909101015281610a5981614e97565b9250508260ff16821015610a70575b6001016109f9565b505050919050565b610a806131a8565b610a886131ff565b8180421115610aaa57604051631ab7da6b60e01b815260040160405180910390fd5b33610ab486611608565b6001600160a01b031614610adb576040516359dc379f60e01b815260040160405180910390fd5b5f858152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b900490911660608201529103610b5657604051632254ea3d60e11b815260040160405180910390fd5b5f858260400151610b679190614eaf565b90505f610b744283614ecb565b905062ed4e0063ffffffff82161115610ba057604051637616640160e01b815260040160405180910390fd5b5f610bad845f0151613245565b90505f610bba8284613288565b9050866001600160801b0316816001600160801b03161015610bef57604051638199f5f360e01b815260040160405180910390fd5b8451610bfb908261334b565b610c4a8a6040518060400160405280885f0151600f0b8152602001886040015163ffffffff168152506040518060400160405280895f0151600f0b81526020018863ffffffff168152506133bd565b6040518060800160405280865f01516001600160801b03168152602001836001600160801b031681526020018563ffffffff1681526020014263ffffffff1681525060665f8c81526020019081526020015f205f820151815f015f6101000a8154816001600160801b0302191690836001600160801b031602179055506020820151815f0160106101000a8154816001600160801b0302191690836001600160801b031602179055506040820151816001015f6101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160046101000a81548163ffffffff021916908363ffffffff16021790555090505089336001600160a01b03167f3032be442129e161b4ae1cdee94871a69de2c16ee2007f31fc209a715673455c8684604051610d9992919063ffffffff9290921682526001600160801b0316602082015260400190565b60405180910390a3505050505050610db060015f55565b50505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff165f81158015610dfb5750825b90505f8267ffffffffffffffff166001148015610e175750303b155b905081158015610e25575080155b15610e435760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610e6d57845460ff60401b1916600160401b1785555b6001600160a01b0389161580610e8a57506001600160a01b038816155b15610ea85760405163d92e233d60e01b815260040160405180910390fd5b610eb287876133dc565b610eba6133ee565b610ec26133fe565b610ecb3361340e565b610ed361341f565b606480546001600160a01b03808c166001600160a01b031992831617909255606f8054928b16929091169190911790555f805260686020527fad6f8124f6081c2622ab3a16acd47af73d52fe87b755c3f897263c58ba3fdbd880544263ffffffff90811663ffffffff194392909216600160201b029190911667ffffffffffffffff19909216919091171790558315610fa657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b610fbb8382613474565b610fc6838383613507565b505050565b5f8163ffffffff165f03610ff257604051637616640160e01b815260040160405180910390fd5b5f838152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b90049091166060820152910361106d57604051632254ea3d60e11b815260040160405180910390fd5b5f83826040015161107e9190614eaf565b90505f61108b4283614ecb565b905062ed4e0063ffffffff821611156110b757604051637616640160e01b815260040160405180910390fd5b5f6110c4845f0151613245565b90506110d08183613288565b979650505050505050565b6110e36131a8565b5f6110ed8261316f565b90506001600160a01b03811661111557604051626f708760e21b815260040160405180910390fd5b6001600160a01b038116331461113e576040516359dc379f60e01b815260040160405180910390fd5b5f828152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b9004909116606082015291036111b957604051632254ea3d60e11b815260040160405180910390fd5b806040015163ffffffff164263ffffffff1610156111ea5760405163342ad40160e11b815260040160405180910390fd5b8051604080518082018252600f83900b81528184015163ffffffff166020808301919091525f8781526066909152918220828155600101805467ffffffffffffffff191690559061123a86611c46565b90505f670de0b6b3a764000061125c6001600160801b03808516908716614ee7565b6112669190614f12565b9050816001600160801b0316846001600160801b0316826112879190614f12565b146112a557604051630fc12e3560e11b815260040160405180910390fd5b5f6112b8670de0b6b3a764000083614f12565b90506001600160801b038111156112e25760405163162908e360e11b815260040160405180910390fd5b606e80548291905f906112ff9084906001600160801b0316614f25565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555061134b888560405180604001604052805f600f0b81526020015f63ffffffff168152506133bd565b5f888152606a60205260409020805463ffffffff1916905561136c8861358a565b335f818152606760205260409020805460ff19811660ff9182165f19019091161790556064546113b1916001600160a01b03909116906001600160801b0388166135c2565b6040516001600160801b0386168152889033907f8903a5b5d08a841e7f68438387f1da20c84dea756379ed37e633ff3854b99b849060200160405180910390a35050505050505061140160015f55565b50565b61140c613625565b6001600160a01b0381166114335760405163d92e233d60e01b815260040160405180910390fd5b606d80546001600160a01b0319166001600160a01b0392909216919091179055565b610fc683838360405180602001604052805f815250611e97565b6114776131a8565b606f54600160a01b900460ff166114cd5760405162461bcd60e51b81526020600482015260156024820152744e6f7420696e20656d657267656e6379206d6f646560581b60448201526064015b60405180910390fd5b336114d782611608565b6001600160a01b0316146114fe576040516359dc379f60e01b815260040160405180910390fd5b5f818152606660208181526040808420815160808101835281546001600160801b03808216808452600160801b909204168286015260018301805463ffffffff80821696850196909652600160201b810490951660608401528888529590945294905567ffffffffffffffff19169091556115788361358a565b335f818152606760205260409020805460ff19811660ff9182165f19019091161790556064546115bd916001600160a01b03909116906001600160801b0384166135c2565b6040516001600160801b0382168152839033907f4f27eb511b2a4633cfb633ac1c4a99b4c298ca6488b29ec26f3504a5927f67289060200160405180910390a3505061140160015f55565b5f6108b9826130f2565b5f5f5160206152db5f395f51905f526001600160a01b03831661164a576040516322718ad960e21b81525f60048201526024016114c4565b6001600160a01b039092165f908152600390920160205250604090205490565b611672613625565b61167b5f613680565b565b611685613625565b6001600160a01b0381166116ac5760405163d92e233d60e01b815260040160405180910390fd5b6065546001600160a01b0316156117055760405162461bcd60e51b815260206004820152601760248201527f4469737472696275746f7220616c72656164792073657400000000000000000060448201526064016114c4565b606580546001600160a01b0319166001600160a01b0392909216919091179055565b6065545f90600160a01b900463ffffffff1682111561175357606554600160a01b900463ffffffff1691505b5f835b83811015611868575f6117688261316f565b6001600160a01b031614611860575f81815260666020908152604091829020825160808101845281546001600160801b03808216808452600160801b909204169382019390935260019091015463ffffffff80821694830194909452600160201b9004909216606083015215806117ef5750806040015163ffffffff164263ffffffff1610155b156117fa5750611860565b80516001600160801b03165f61181362ed4e0083614f12565b90506001600160801b0381111561182c57505050611860565b5f819050806001600160801b031684602001516001600160801b03161461185b578561185781614e97565b9650505b505050505b600101611756565b509392505050565b611878613625565b606554600160a01b900463ffffffff168111156118a15750606554600160a01b900463ffffffff165b5f6118ac8383614f44565b905060648111156118bb575f5ffd5b825b82811015610db0575f6118cf8261316f565b6001600160a01b031614611c3e575f81815260666020908152604091829020825160808101845281546001600160801b03808216808452600160801b909204169382019390935260019091015463ffffffff80821694830194909452600160201b9004909216606083015215806119565750806040015163ffffffff164263ffffffff1610155b156119615750611c3e565b80516001600160801b03165f61197a62ed4e0083614f12565b90506001600160801b0381111561199357505050611c3e565b602083015181906001600160801b038083169116036119b55750505050611c3e565b5f4285604001516119c69190614ecb565b90505f6119e263ffffffff83166001600160801b038516614ee7565b90505f6119fb62ed4e006001600160801b038616614ee7565b611a15670de0b6b3a7640000673782dace9d900000614f25565b611a28906001600160801b031684614ee7565b611a329190614f12565b611a4490670de0b6b3a7640000614f57565b9050673782dace9d900000811115611a615750673782dace9d9000005b670de0b6b3a7640000811015611a7c5750670de0b6b3a76400005b611acf8860405180604001604052808a5f0151600f0b81526020018a6040015163ffffffff1681525060405180604001604052808b5f0151600f0b81526020018b6040015163ffffffff168152506133bd565b6040518060800160405280885f01516001600160801b03168152602001856001600160801b03168152602001886040015163ffffffff1681526020014263ffffffff1681525060665f8a81526020019081526020015f205f820151815f015f6101000a8154816001600160801b0302191690836001600160801b031602179055506020820151815f0160106101000a8154816001600160801b0302191690836001600160801b031602179055506040820151816001015f6101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160046101000a81548163ffffffff021916908363ffffffff16021790555090505087611bd68961316f565b6001600160a01b03167f3032be442129e161b4ae1cdee94871a69de2c16ee2007f31fc209a715673455c896040015184604051611c2e92919063ffffffff9290921682526001600160801b0316602082015260400190565b60405180910390a3505050505050505b6001016118bd565b5f818152606660209081526040808320815160808101835281546001600160801b038082168352600160801b90910416938101939093526001015463ffffffff808216928401839052600160201b90910481166060840152421610611cb55750670de0b6b3a764000092915050565b5f611ccb670de0b6b3a764000062ed4e00614f6a565b6001600160801b0316611cee670de0b6b3a7640000673782dace9d900000614f25565b8351611d06916001600160801b039081169116614ee7565b611d109190614f12565b90506001600160801b03811115611d3a5760405163162908e360e11b815260040160405180910390fd5b604082015181905f90611d4e904290614ecb565b90505f611d6a63ffffffff83166001600160801b038516614ee7565b611d7c90670de0b6b3a7640000614f57565b9050673782dace9d9000006001600160801b0382161115611dab5750673782dace9d9000009695505050505050565b670de0b6b3a76400006001600160801b0382161015611dd85750670de0b6b3a76400009695505050505050565b9695505050505050565b7f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930180546060915f5160206152db5f395f51905f52916108de90614e37565b60695463ffffffff9081165f90815260686020908152604080832081516080810183528154600f81810b8352600160801b909104900b938101939093526001015480851691830191909152600160201b9004909216606083015290611e8581846136f0565b9392505050565b61097f338383613805565b611ea18483613474565b610db0848484846138b4565b611eb56131a8565b611ebd6131ff565b8080421115611edf57604051631ab7da6b60e01b815260040160405180910390fd5b6002831015611f015760405163162908e360e11b815260040160405180910390fd5b5f80805b8581101561200a5733611f2f888884818110611f2357611f23614e6f565b90506020020135611608565b6001600160a01b031614611f56576040516359dc379f60e01b815260040160405180910390fd5b5f60665f898985818110611f6c57611f6c614e6f565b602090810292909201358352508181019290925260409081015f20815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b900490911660608201529150611fdf9085614f93565b93508263ffffffff16816040015163ffffffff16111561200157806040015192505b50600101611f05565b505f6120164283614ecb565b905062ed4e0063ffffffff8216111561204257604051637616640160e01b815260040160405180910390fd5b5f62ed4e00612061670de0b6b3a7640000673782dace9d900000614f25565b6001600160801b0316856001600160801b031661207e9190614ee7565b6120889190614f12565b90506001600160801b038111156120b25760405163162908e360e11b815260040160405180910390fd5b6065805482915f916014906120d390600160a01b900463ffffffff16614fb2565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff16905061210233826138cc565b5f5b898110156121ed575f8b8b8381811061211f5761211f614e6f565b602090810292909201355f818152606684526040808220815160808101835281546001600160801b038082168352600160801b909104168188015260019091015463ffffffff808216838501908152600160201b90920481166060840152835180850185528351600f0b8152915116818801528251808401909352838352958201929092529194509291506121b790849083906133bd565b5f838152606660205260408120908155600101805467ffffffffffffffff191690556121e28361358a565b505050600101612104565b50604080518082018252600f88900b815263ffffffff871660208083019190915282518084019093525f808452908301529061222b908390836133bd565b6040518060800160405280886001600160801b03168152602001846001600160801b031681526020018763ffffffff1681526020014263ffffffff1681525060665f8481526020019081526020015f205f820151815f015f6101000a8154816001600160801b0302191690836001600160801b031602179055506020820151815f0160106101000a8154816001600160801b0302191690836001600160801b031602179055506040820151816001015f6101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055509050508a8a905060675f336001600160a01b03166001600160a01b031681526020019081526020015f205f9054906101000a900460ff160360010160675f336001600160a01b03166001600160a01b031681526020019081526020015f205f6101000a81548160ff021916908360ff16021790555081336001600160a01b03167fdbd81f1b10e6f1395ede56cabac59119f8be0cb5ca3ef0ca44f859782893495489896040516123e99291906001600160801b0392909216825263ffffffff16602082015260400190565b60405180910390a35050505050505050610fc660015f55565b61240a6131a8565b6124126131ff565b818042111561243457604051631ab7da6b60e01b815260040160405180910390fd5b3361243e86611608565b6001600160a01b031614612465576040516359dc379f60e01b815260040160405180910390fd5b836001600160801b03165f0361248e5760405163162908e360e11b815260040160405180910390fd5b5f858152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b90049091166060820152910361250957604051632254ea3d60e11b815260040160405180910390fd5b806040015163ffffffff164263ffffffff1610612539576040516307b7d7dd60e51b815260040160405180910390fd5b80515f90612548908790614f93565b90505f61255482613245565b90505f4284604001516125679190614ecb565b90505f61258363ffffffff83166001600160801b038516614ee7565b61259590670de0b6b3a7640000614f57565b9050673782dace9d9000006001600160801b03821611156125c957604051638f651fb760e01b815260040160405180910390fd5b866001600160801b0316816001600160801b031610156125fc57604051638199f5f360e01b815260040160405180910390fd5b6064546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015612642573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126669190614fd6565b60645490915061268a906001600160a01b031633306001600160801b038e166138e5565b61269d6001600160801b038b1682614f57565b6064546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156126e3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127079190614fd6565b14612725576040516312171d8360e31b815260040160405180910390fd5b8551612731908361334b565b6127818b6040518060400160405280895f0151600f0b8152602001896040015163ffffffff16815250604051806040016040528089600f0b81526020018a6040015163ffffffff168152506133bd565b6040518060800160405280866001600160801b03168152602001856001600160801b03168152602001876040015163ffffffff1681526020014263ffffffff1681525060665f8d81526020019081526020015f205f820151815f015f6101000a8154816001600160801b0302191690836001600160801b031602179055506020820151815f0160106101000a8154816001600160801b0302191690836001600160801b031602179055506040820151816001015f6101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055509050508a336001600160a01b03167f1381e2f7d0d4b71a58d34dc3db2051dd52769766e65eabf380c9b4ea93f0890b8c88866040516128d7939291906001600160801b0393841681529183166020830152909116604082015260600190565b60405180910390a350505050505050610db060015f55565b6128f7613625565b606f805460ff60a01b1916600160a01b17905561291261341f565b606f546040516001600160a01b0390911681527fc0a1c7e9f05b4d536e1ff8606bae9b847cdb43ef4a9b2d7a503a88cee08dccdb906020015b60405180910390a1565b60605f6129618361316f565b6001600160a01b03160361298757604051626f708760e21b815260040160405180910390fd5b606d546001600160a01b03166129b0576040516338a69c8d60e21b815260040160405180910390fd5b606d54604051602481018490525f9182916001600160a01b039091169060440160408051601f198184030181529181526020820180516001600160e01b031663c87b56dd60e01b17905251612a059190614fed565b5f60405180830381855afa9150503d805f8114612a3d576040519150601f19603f3d011682016040523d82523d5f602084013e612a42565b606091505b509150915081612a8c5760405162461bcd60e51b8152602060048201526015602482015274105c9d081c1c9bde1e4818d85b1b0819985a5b1959605a1b60448201526064016114c4565b80806020019051810190612aa09190615003565b949350505050565b5f63ffffffff82161580612ac4575062ed4e0063ffffffff8316115b15612ae257604051637616640160e01b815260040160405180910390fd5b826001600160801b03165f03612b0b5760405163162908e360e11b815260040160405180910390fd5b5f612b1584613245565b9050612aa08184613288565b5f828152606a602052604081205463ffffffff16808203612b45575f9150506108b9565b5f848152606b6020908152604080832063ffffffff80861685529083529281902081516080810183528154600f81810b8352600160801b909104900b9381019390935260010154808416918301829052600160201b9004909216606082015290612baf9085614ecb565b63ffffffff168160200151612bc49190615078565b81518290612bd3908390615097565b600f90810b90915282515f910b12159050612bec575f81525b516001600160801b0316949350505050565b606d545f90819063ffffffff600160a01b909104811690841611612c225782612c3c565b606d54612c3c90600160a01b900463ffffffff1684614ecb565b90505f62ed4e00612c5d670de0b6b3a7640000673782dace9d900000614f25565b6001600160801b0316866001600160801b0316612c7a9190614ee7565b612c849190614f12565b905080612ca063ffffffff84166001600160801b038316614ee7565b611dd890670de0b6b3a7640000614f57565b5f612cbb6131a8565b612cc36131ff565b8280421115612ce557604051631ab7da6b60e01b815260040160405180910390fd5b856001600160801b03165f03612d0e5760405163162908e360e11b815260040160405180910390fd5b63ffffffff85161580612d29575062ed4e0063ffffffff8616115b15612d4757604051637616640160e01b815260040160405180910390fd5b335f90815260676020526040902054606460ff90911610612d7b5760405163133cbc4f60e01b815260040160405180910390fd5b5f612d868642614eaf565b90505f5f612d9589898861391d565b915091505f60405180604001604052808b600f0b81526020018563ffffffff168152509050612de25f60405180604001604052805f600f0b81526020015f63ffffffff16815250836133bd565b6064546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015612e28573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e4c9190614fd6565b606454909150612e70906001600160a01b031633306001600160801b038f166138e5565b612e836001600160801b038c1682614f57565b6064546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015612ec9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612eed9190614fd6565b14612f0b576040516312171d8360e31b815260040160405180910390fd5b60658054600163ffffffff600160a01b80840482168381019092160263ffffffff60a01b1990931692909217909255335f818152606760205260409020805460ff80821690950190941660ff19909416939093179092559750612f6e90886138cc565b604080516080810182526001600160801b03808e168252868116602080840191825263ffffffff808b16858701908152428216606087019081525f8f8152606690945296909220945192518416600160801b0292909316919091178355516001909201805493518216600160201b0267ffffffffffffffff1990941692909116919091179190911790556130028b8461334b565b604080516001600160801b038d16815263ffffffff87166020820152889133917fdbd81f1b10e6f1395ede56cabac59119f8be0cb5ca3ef0ca44f8597828934954910160405180910390a3505050505050612aa060015f55565b6001600160a01b039182165f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab00793056020908152604080832093909416825291909152205460ff1690565b6130b0613625565b6001600160a01b0381166130d957604051631e4fbdf760e01b81525f60048201526024016114c4565b61140181613680565b6130ea613625565b61167b613a77565b5f5f6130fd8361316f565b90506001600160a01b0381166108b957604051637e27328960e01b8152600481018490526024016114c4565b5f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930460205260409020546001600160a01b031690565b610fc68383836001613ab0565b5f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930260205260409020546001600160a01b031690565b60025f54036131f95760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016114c4565b60025f55565b60325460ff161561167b5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016114c4565b5f6001600160801b0382168161325e62ed4e0083614f12565b90506001600160801b03811115611e855760405163162908e360e11b815260040160405180910390fd5b5f806132a363ffffffff84166001600160801b038616614ee7565b90505f6132bc62ed4e006001600160801b038716614ee7565b6132d6670de0b6b3a7640000673782dace9d900000614f25565b6132e9906001600160801b031684614ee7565b6132f39190614f12565b61330590670de0b6b3a7640000614f57565b9050673782dace9d90000081111561332957673782dace9d900000925050506108b9565b670de0b6b3a7640000811015612aa057670de0b6b3a7640000925050506108b9565b5f670de0b6b3a764000061336b6001600160801b03848116908616614ee7565b6133759190614f12565b606e805491925082915f906133949084906001600160801b0316614f93565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550505050565b6133c5613bc3565b8215610fc657610fc6838383613d35565b60015f55565b6133e4613f2b565b61097f8282613f74565b6133f6613f2b565b61167b613fa4565b613406613f2b565b61167b613fac565b613416613f2b565b61140181613fc0565b6134276131ff565b6032805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861345c3390565b6040516001600160a01b03909116815260200161294b565b6001600160a01b0382161580159061349657506065546001600160a01b031615155b1561097f5760655460405163379607f560e01b8152600481018390526001600160a01b039091169063379607f5906024016020604051808303815f875af11580156134e3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fc69190614fd6565b6001600160a01b03821661353057604051633250574960e11b81525f60048201526024016114c4565b5f61353c838333613fc8565b9050836001600160a01b0316816001600160a01b031614610db0576040516364283d7b60e01b81526001600160a01b03808616600483015260248201849052821660448201526064016114c4565b5f6135965f835f613fc8565b90506001600160a01b03811661097f57604051637e27328960e01b8152600481018390526024016114c4565b6040516001600160a01b038316602482015260448101829052610fc690849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526140ca565b336136577f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b03161461167b5760405163118cdaa760e01b81523360048201526024016114c4565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f5f8390505f62093a8080836040015161370a91906150c4565b61371491906150eb565b90505f5b60ff8110156137e05761372e62093a8083614eaf565b91505f63ffffffff808716908416111561374a57859250613764565b5063ffffffff82165f908152606c6020526040902054600f0b5b60408401516137739084614ecb565b63ffffffff1684602001516137889190615078565b84518590613797908390615097565b600f0b90525063ffffffff808716908416036137b357506137e0565b80846020018181516137c5919061510a565b600f0b9052505063ffffffff82166040840152600101613718565b505f825f0151600f0b12156137f3575f82525b50516001600160801b03169392505050565b5f5160206152db5f395f51905f526001600160a01b03831661384557604051630b61174360e31b81526001600160a01b03841660048201526024016114c4565b6001600160a01b038481165f818152600584016020908152604080832094881680845294825291829020805460ff191687151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a350505050565b6138bf848484610fb1565b610db0338585858561419d565b61097f828260405180602001604052805f8152506142c5565b6040516001600160a01b0380851660248301528316604482015260648101829052610db09085906323b872dd60e01b906084016135ee565b5f808061393b670de0b6b3a76400006001600160801b038816614f12565b90505f613958670de0b6b3a7640000673782dace9d900000614f25565b6001600160801b031690505f613979670de0b6b3a764000062ed4e00614f6a565b6001600160801b031661398c8385614ee7565b6139969190614f12565b90506001600160801b038111156139c05760405163162908e360e11b815260040160405180910390fd5b9350835f670de0b6b3a76400006139e663ffffffff8a166001600160801b038516614ee7565b6139f09190614f12565b9050613a0481670de0b6b3a7640000614f57565b9450673782dace9d9000006001600160801b0386161115613a3857604051638f651fb760e01b815260040160405180910390fd5b866001600160801b0316856001600160801b03161015613a6b57604051638199f5f360e01b815260040160405180910390fd5b50505050935093915050565b613a7f6142dc565b6032805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa3361345c565b5f5160206152db5f395f51905f528180613ad257506001600160a01b03831615155b15613b93575f613ae1856130f2565b90506001600160a01b03841615801590613b0d5750836001600160a01b0316816001600160a01b031614155b8015613b205750613b1e818561305c565b155b15613b495760405163a9fbf51f60e01b81526001600160a01b03851660048201526024016114c4565b8215613b915784866001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5f93845260040160205250506040902080546001600160a01b0319166001600160a01b0392909216919091179055565b60695463ffffffff16613bf5604080516080810182525f80825260208201819052918101829052606081019190915290565b63ffffffff821615613c6e5760685f613c0f600185614ecb565b63ffffffff908116825260208083019390935260409182015f2082516080810184528154600f81810b8352600160801b909104900b948101949094526001015480821692840192909252600160201b9091041660608201529050613c9b565b50604080516080810182525f808252602082015263ffffffff428116928201929092524390911660608201525b60408101515f63ffffffff808316429091161115613cfc576040830151613cc89063ffffffff1642614f44565b6060840151613cdd9063ffffffff1643614f44565b613cef90670de0b6b3a7640000614ee7565b613cf99190614f12565b90505b613d0883838387614325565b9250613d15846001614eaf565b6069805463ffffffff191663ffffffff9290921691909117905550505050565b604080516080810182525f808252602082018190529181018290526060810191909152604080516080810182525f8082526020820181905291810182905260608101919091524263ffffffff16846020015163ffffffff16118015613d9f57505f845f0151600f0b135b15613de9578351613db49062ed4e0090615137565b600f0b602080840191909152840151613dce904290614ecb565b63ffffffff168260200151613de39190615078565b600f0b82525b4263ffffffff16836020015163ffffffff16118015613e0d57505f835f0151600f0b135b15613e57578251613e229062ed4e0090615137565b600f0b602080830191909152830151613e3c904290614ecb565b63ffffffff168160200151613e519190615078565b600f0b81525b613e6b84848460200151846020015161452a565b5f858152606a6020526040812054613e8a9063ffffffff166001614eaf565b5f878152606a60209081526040808320805463ffffffff95861663ffffffff199091168117909155428516878301908152438616606089019081529b8552606b84528285209185529083529220855195909101516001600160801b03908116600160801b02951694909417845551600193909301805497518216600160201b0267ffffffffffffffff19909816939091169290921795909517905550505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661167b57604051631afcd79f60e31b815260040160405180910390fd5b613f7c613f2b565b5f5160206152db5f395f51905f5280613f9584826151b7565b5060018101610db083826151b7565b6133d6613f2b565b613fb4613f2b565b6032805460ff19169055565b6130b0613f2b565b5f5f5160206152db5f395f51905f5281613fe18561316f565b90506001600160a01b03841615613ffd57613ffd818587614665565b6001600160a01b03811615614039576140185f865f5f613ab0565b6001600160a01b0381165f908152600383016020526040902080545f190190555b6001600160a01b03861615614069576001600160a01b0386165f9081526003830160205260409020805460010190555b5f85815260028301602052604080822080546001600160a01b0319166001600160a01b038a811691821790925591518893918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a495945050505050565b5f61411e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166146c99092919063ffffffff16565b905080515f148061413e57508080602001905181019061413e9190615272565b610fc65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016114c4565b6001600160a01b0383163b156142be57604051630a85bd0160e11b81526001600160a01b0384169063150b7a02906141df90889088908790879060040161528d565b6020604051808303815f875af1925050508015614219575060408051601f3d908101601f19168201909252614216918101906152bf565b60015b614280573d808015614246576040519150601f19603f3d011682016040523d82523d5f602084013e61424b565b606091505b5080515f0361427857604051633250574960e11b81526001600160a01b03851660048201526024016114c4565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b146142bc57604051633250574960e11b81526001600160a01b03851660048201526024016114c4565b505b5050505050565b6142cf83836146d7565b610fc6335f85858561419d565b60325460ff1661167b5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016114c4565b604080516080810182525f808252602082018190529181018290526060810191909152845f62093a8061435881886150c4565b61436291906150eb565b90505f5b60ff81101561451e5761437c62093a8083614eaf565b91505f63ffffffff4281169084161115614398574292506143b2565b5063ffffffff82165f908152606c6020526040902054600f0b5b6143bc8884614ecb565b63ffffffff1689602001516143d19190615078565b89518a906143e0908390615097565b600f0b9052506020890180518291906143fa90839061510a565b600f0b90525063ffffffff83166040808b0191909152840151670de0b6b3a7640000906144279085614ecb565b6144409063ffffffff166001600160801b038a16614ee7565b61444a9190614f12565b846060015163ffffffff1661445f9190614f57565b63ffffffff90811660608b015242811690841603614489575063ffffffff4316606089015261451e565b8860685f846144998a6001614eaf565b6144a39190614eaf565b63ffffffff908116825260208083019390935260409182015f208451938501516001600160801b03908116600160801b02941693909317835590830151600190920180546060909401518216600160201b0267ffffffffffffffff199094169290911691909117919091179055509095508590600101614366565b50959695505050505050565b4263ffffffff16846020015163ffffffff1611156145cb5760208085015163ffffffff165f908152606c9091526040902054600f0b614569838261510a565b9050846020015163ffffffff16846020015163ffffffff1603614593576145908282615097565b90505b60208581015163ffffffff165f908152606c9091526040902080546001600160801b0319166001600160801b03929092169190911790555b4263ffffffff16836020015163ffffffff161115610db057836020015163ffffffff16836020015163ffffffff161115610db05760208084015163ffffffff165f908152606c9091526040902054600f0b6146268282615097565b60208086015163ffffffff165f908152606c9091526040902080546001600160801b039092166001600160801b03199092169190911790555050505050565b614670838383614738565b610fc6576001600160a01b03831661469e57604051637e27328960e01b8152600481018290526024016114c4565b60405163177e802f60e01b81526001600160a01b0383166004820152602481018290526044016114c4565b6060612aa084845f8561479c565b6001600160a01b03821661470057604051633250574960e11b81525f60048201526024016114c4565b5f61470c83835f613fc8565b90506001600160a01b03811615610fc6576040516339e3563760e11b81525f60048201526024016114c4565b5f6001600160a01b03831615801590612aa05750826001600160a01b0316846001600160a01b031614806147715750614771848461305c565b80612aa05750826001600160a01b031661478a83613129565b6001600160a01b031614949350505050565b6060824710156147fd5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016114c4565b5f5f866001600160a01b031685876040516148189190614fed565b5f6040518083038185875af1925050503d805f8114614852576040519150601f19603f3d011682016040523d82523d5f602084013e614857565b606091505b50915091506110d087838387606083156148d15782515f036148ca576001600160a01b0385163b6148ca5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016114c4565b5081612aa0565b612aa083838151156148e65781518083602001fd5b8060405162461bcd60e51b81526004016114c4919061495e565b6001600160e01b031981168114611401575f5ffd5b5f60208284031215614925575f5ffd5b8135611e8581614900565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611e856020830184614930565b5f60208284031215614980575f5ffd5b5035919050565b80356001600160a01b038116811461499d575f5ffd5b919050565b5f5f604083850312156149b3575f5ffd5b6149bc83614987565b946020939093013593505050565b5f602082840312156149da575f5ffd5b611e8582614987565b602080825282518282018190525f918401906040840190835b81811015614a1a5783518352602093840193909201916001016149fc565b509095945050505050565b803563ffffffff8116811461499d575f5ffd5b5f5f60408385031215614a49575f5ffd5b82359150614a5960208401614a25565b90509250929050565b80356001600160801b038116811461499d575f5ffd5b5f5f5f5f60808587031215614a8b575f5ffd5b84359350614a9b60208601614a25565b925060408501359150614ab060608601614a62565b905092959194509250565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614af857614af8614abb565b604052919050565b5f67ffffffffffffffff821115614b1957614b19614abb565b50601f01601f191660200190565b5f614b39614b3484614b00565b614acf565b9050828152838383011115614b4c575f5ffd5b828260208301375f602084830101529392505050565b5f82601f830112614b71575f5ffd5b611e8583833560208501614b27565b5f5f5f5f60808587031215614b93575f5ffd5b614b9c85614987565b9350614baa60208601614987565b9250604085013567ffffffffffffffff811115614bc5575f5ffd5b614bd187828801614b62565b925050606085013567ffffffffffffffff811115614bed575f5ffd5b614bf987828801614b62565b91505092959194509250565b5f5f5f60608486031215614c17575f5ffd5b614c2084614987565b9250614c2e60208501614987565b929592945050506040919091013590565b5f60208284031215614c4f575f5ffd5b611e8582614a25565b5f5f60408385031215614c69575f5ffd5b50508035926020909101359150565b8015158114611401575f5ffd5b5f5f60408385031215614c96575f5ffd5b614c9f83614987565b91506020830135614caf81614c78565b809150509250929050565b5f5f5f5f60808587031215614ccd575f5ffd5b614cd685614987565b9350614ce460208601614987565b925060408501359150606085013567ffffffffffffffff811115614d06575f5ffd5b8501601f81018713614d16575f5ffd5b614bf987823560208401614b27565b5f5f5f60408486031215614d37575f5ffd5b833567ffffffffffffffff811115614d4d575f5ffd5b8401601f81018613614d5d575f5ffd5b803567ffffffffffffffff811115614d73575f5ffd5b8660208260051b8401011115614d87575f5ffd5b6020918201979096509401359392505050565b5f5f5f5f60808587031215614dad575f5ffd5b84359350614a9b60208601614a62565b5f5f60408385031215614dce575f5ffd5b614dd783614a62565b9150614a5960208401614a25565b5f5f5f5f60808587031215614df8575f5ffd5b614e0185614a62565b9350614a9b60208601614a25565b5f5f60408385031215614e20575f5ffd5b614e2983614987565b9150614a5960208401614987565b600181811c90821680614e4b57607f821691505b602082108103614e6957634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f60018201614ea857614ea8614e83565b5060010190565b63ffffffff81811683821601908111156108b9576108b9614e83565b63ffffffff82811682821603908111156108b9576108b9614e83565b80820281158282048414176108b9576108b9614e83565b634e487b7160e01b5f52601260045260245ffd5b5f82614f2057614f20614efe565b500490565b6001600160801b0382811682821603908111156108b9576108b9614e83565b818103818111156108b9576108b9614e83565b808201808211156108b9576108b9614e83565b6001600160801b038181168382160290811690818114614f8c57614f8c614e83565b5092915050565b6001600160801b0381811683821601908111156108b9576108b9614e83565b5f63ffffffff821663ffffffff8103614fcd57614fcd614e83565b60010192915050565b5f60208284031215614fe6575f5ffd5b5051919050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615013575f5ffd5b815167ffffffffffffffff811115615029575f5ffd5b8201601f81018413615039575f5ffd5b8051615047614b3482614b00565b81815285602083850101111561505b575f5ffd5b8160208401602083015e5f91810160200191909152949350505050565b5f82600f0b82600f0b0280600f0b9150808214614f8c57614f8c614e83565b600f82810b9082900b0360016001607f1b0319811260016001607f1b03821317156108b9576108b9614e83565b5f63ffffffff8316806150d9576150d9614efe565b8063ffffffff84160491505092915050565b63ffffffff8181168382160290811690818114614f8c57614f8c614e83565b600f81810b9083900b0160016001607f1b03811360016001607f1b0319821217156108b9576108b9614e83565b5f81600f0b83600f0b8061514d5761514d614efe565b60016001607f1b031982145f198214161561516a5761516a614e83565b90059392505050565b601f821115610fc657805f5260205f20601f840160051c810160208510156151985750805b601f840160051c820191505b818110156142be575f81556001016151a4565b815167ffffffffffffffff8111156151d1576151d1614abb565b6151e5816151df8454614e37565b84615173565b6020601f821160018114615217575f83156152005750848201515b5f19600385901b1c1916600184901b1784556142be565b5f84815260208120601f198516915b828110156152465787850151825560209485019460019092019101615226565b508482101561526357868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f60208284031215615282575f5ffd5b8151611e8581614c78565b6001600160a01b03858116825284166020820152604081018390526080606082018190525f90611dd890830184614930565b5f602082840312156152cf575f5ffd5b8151611e858161490056fe80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079300a2646970667358221220ef9a63d329c5cb68fcb78c323435d0abb474f0582e53487911b1c7ec2e40021864736f6c634300081b0033
Deployed Bytecode
0x608060405234801561000f575f5ffd5b50600436106102cb575f3560e01c80638981be0e1161017b578063bbe33ea5116100e4578063ddacc94a1161009e578063e58f594711610079578063e58f59471461081b578063e985e9c514610840578063f2fde38b14610853578063f7b188a514610866575f5ffd5b8063ddacc94a146107e2578063df0c78ef146107f5578063df21515714610808575f5ffd5b8063bbe33ea51461076c578063bcc002251461077f578063beb83109146107a1578063c5b1c7d0146107b4578063c87b56dd146107bc578063d89dd269146107cf575f5ffd5b806395d89b411161013557806395d89b41146106cf57806397612d4b146106d757806398a3f422146106ea5780639b7d02ad14610709578063a22cb46514610746578063b88d4fde14610759575f5ffd5b80638981be0e1461058a57806389f839c61461059d5780638b25e8c1146106205780638da5cb5b146106335780638ff4249014610663578063900cf0cf146106aa575f5ffd5b8063268dc19911610237578063586c2600116101f157806370a08231116101cc57806370a082311461053b578063715018a61461055c57806375619ab5146105645780638125bae514610577575f5ffd5b8063586c2600146104e85780635c975abb1461051d5780636352211e14610528575f5ffd5b8063268dc199146104785780632e1a7d4d146104895780632e720f7d1461049c57806342842e0e146104af5780635312ea8e146104c25780635594a045146104d5575f5ffd5b80631d237a49116102885780631d237a491461037d5780631f5ab022146104025780632016a0d21461041557806320a194b81461042857806323b872dd1461043a57806324c44c5b1461044d575f5ffd5b806301ffc9a7146102cf57806306fdde03146102f7578063081812fc1461030c578063095ea7b3146103375780630f45cc811461034c57806313de148b1461035d575b5f5ffd5b6102e26102dd366004614915565b61086e565b60405190151581526020015b60405180910390f35b6102ff6108bf565b6040516102ee919061495e565b61031f61031a366004614970565b610960565b6040516001600160a01b0390911681526020016102ee565b61034a6103453660046149a2565b610974565b005b6064546001600160a01b031661031f565b61037061036b3660046149ca565b610983565b6040516102ee91906149e3565b6103cf61038b366004614a38565b606b60209081525f928352604080842090915290825290208054600190910154600f82810b92600160801b9004900b9063ffffffff80821691600160201b90041684565b60408051600f95860b81529390940b602084015263ffffffff9182169383019390935290911660608201526080016102ee565b61034a610410366004614a78565b610a78565b61034a610423366004614b80565b610db6565b606f54600160a01b900460ff166102e2565b61034a610448366004614c05565b610fb1565b61046061045b366004614a38565b610fcb565b6040516001600160801b0390911681526020016102ee565b606e546001600160801b0316610460565b61034a610497366004614970565b6110db565b61034a6104aa3660046149ca565b611404565b61034a6104bd366004614c05565b611455565b61034a6104d0366004614970565b61146f565b606d5461031f906001600160a01b031681565b61050a6104f6366004614c3f565b606c6020525f9081526040902054600f0b81565b604051600f9190910b81526020016102ee565b60325460ff166102e2565b61031f610536366004614970565b611608565b61054e6105493660046149ca565b611612565b6040519081526020016102ee565b61034a61166a565b61034a6105723660046149ca565b61167d565b61054e610585366004614c58565b611727565b61034a610598366004614c58565b611870565b6105e96105ab366004614970565b60666020525f9081526040902080546001909101546001600160801b0380831692600160801b9004169063ffffffff80821691600160201b90041684565b604080516001600160801b03958616815294909316602085015263ffffffff918216928401929092521660608201526080016102ee565b61046061062e366004614970565b611c46565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031661031f565b6103cf610671366004614c3f565b60686020525f908152604090208054600190910154600f82810b92600160801b9004900b9063ffffffff80821691600160201b90041684565b6069546106ba9063ffffffff1681565b60405163ffffffff90911681526020016102ee565b6102ff611de2565b6104606106e5366004614c3f565b611e20565b61054e6106f8366004614970565b60706020525f908152604090205481565b6107346107173660046149ca565b6001600160a01b03165f9081526067602052604090205460ff1690565b60405160ff90911681526020016102ee565b61034a610754366004614c85565b611e8c565b61034a610767366004614cba565b611e97565b61034a61077a366004614d25565b611ead565b61073461078d3660046149ca565b60676020525f908152604090205460ff1681565b61034a6107af366004614d9a565b612402565b61034a6128ef565b6102ff6107ca366004614970565b612955565b6104606107dd366004614dbd565b612aa8565b6104606107f0366004614a38565b612b21565b610460610803366004614dbd565b612bfe565b61054e610816366004614de5565b612cb2565b6106ba610829366004614970565b606a6020525f908152604090205463ffffffff1681565b6102e261084e366004614e0f565b61305c565b61034a6108613660046149ca565b6130a8565b61034a6130e2565b5f6001600160e01b031982166380ac58cd60e01b148061089e57506001600160e01b03198216635b5e139f60e01b145b806108b957506301ffc9a760e01b6001600160e01b03198316145b92915050565b5f5160206152db5f395f51905f5280546060919081906108de90614e37565b80601f016020809104026020016040519081016040528092919081815260200182805461090a90614e37565b80156109555780601f1061092c57610100808354040283529160200191610955565b820191905f5260205f20905b81548152906001019060200180831161093857829003601f168201915b505050505091505090565b5f61096a826130f2565b506108b982613129565b61097f828233613162565b5050565b6001600160a01b0381165f9081526067602052604090205460609060ff168067ffffffffffffffff8111156109ba576109ba614abb565b6040519080825280602002602001820160405280156109e3578160200160208202803683370190505b5091508060ff165f036109f65750919050565b5f805b606554600160a01b900463ffffffff16811015610a7057846001600160a01b0316610a238261316f565b6001600160a01b031603610a685780848381518110610a4457610a44614e6f565b602090810291909101015281610a5981614e97565b9250508260ff16821015610a70575b6001016109f9565b505050919050565b610a806131a8565b610a886131ff565b8180421115610aaa57604051631ab7da6b60e01b815260040160405180910390fd5b33610ab486611608565b6001600160a01b031614610adb576040516359dc379f60e01b815260040160405180910390fd5b5f858152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b900490911660608201529103610b5657604051632254ea3d60e11b815260040160405180910390fd5b5f858260400151610b679190614eaf565b90505f610b744283614ecb565b905062ed4e0063ffffffff82161115610ba057604051637616640160e01b815260040160405180910390fd5b5f610bad845f0151613245565b90505f610bba8284613288565b9050866001600160801b0316816001600160801b03161015610bef57604051638199f5f360e01b815260040160405180910390fd5b8451610bfb908261334b565b610c4a8a6040518060400160405280885f0151600f0b8152602001886040015163ffffffff168152506040518060400160405280895f0151600f0b81526020018863ffffffff168152506133bd565b6040518060800160405280865f01516001600160801b03168152602001836001600160801b031681526020018563ffffffff1681526020014263ffffffff1681525060665f8c81526020019081526020015f205f820151815f015f6101000a8154816001600160801b0302191690836001600160801b031602179055506020820151815f0160106101000a8154816001600160801b0302191690836001600160801b031602179055506040820151816001015f6101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160046101000a81548163ffffffff021916908363ffffffff16021790555090505089336001600160a01b03167f3032be442129e161b4ae1cdee94871a69de2c16ee2007f31fc209a715673455c8684604051610d9992919063ffffffff9290921682526001600160801b0316602082015260400190565b60405180910390a3505050505050610db060015f55565b50505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff165f81158015610dfb5750825b90505f8267ffffffffffffffff166001148015610e175750303b155b905081158015610e25575080155b15610e435760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610e6d57845460ff60401b1916600160401b1785555b6001600160a01b0389161580610e8a57506001600160a01b038816155b15610ea85760405163d92e233d60e01b815260040160405180910390fd5b610eb287876133dc565b610eba6133ee565b610ec26133fe565b610ecb3361340e565b610ed361341f565b606480546001600160a01b03808c166001600160a01b031992831617909255606f8054928b16929091169190911790555f805260686020527fad6f8124f6081c2622ab3a16acd47af73d52fe87b755c3f897263c58ba3fdbd880544263ffffffff90811663ffffffff194392909216600160201b029190911667ffffffffffffffff19909216919091171790558315610fa657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b610fbb8382613474565b610fc6838383613507565b505050565b5f8163ffffffff165f03610ff257604051637616640160e01b815260040160405180910390fd5b5f838152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b90049091166060820152910361106d57604051632254ea3d60e11b815260040160405180910390fd5b5f83826040015161107e9190614eaf565b90505f61108b4283614ecb565b905062ed4e0063ffffffff821611156110b757604051637616640160e01b815260040160405180910390fd5b5f6110c4845f0151613245565b90506110d08183613288565b979650505050505050565b6110e36131a8565b5f6110ed8261316f565b90506001600160a01b03811661111557604051626f708760e21b815260040160405180910390fd5b6001600160a01b038116331461113e576040516359dc379f60e01b815260040160405180910390fd5b5f828152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b9004909116606082015291036111b957604051632254ea3d60e11b815260040160405180910390fd5b806040015163ffffffff164263ffffffff1610156111ea5760405163342ad40160e11b815260040160405180910390fd5b8051604080518082018252600f83900b81528184015163ffffffff166020808301919091525f8781526066909152918220828155600101805467ffffffffffffffff191690559061123a86611c46565b90505f670de0b6b3a764000061125c6001600160801b03808516908716614ee7565b6112669190614f12565b9050816001600160801b0316846001600160801b0316826112879190614f12565b146112a557604051630fc12e3560e11b815260040160405180910390fd5b5f6112b8670de0b6b3a764000083614f12565b90506001600160801b038111156112e25760405163162908e360e11b815260040160405180910390fd5b606e80548291905f906112ff9084906001600160801b0316614f25565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555061134b888560405180604001604052805f600f0b81526020015f63ffffffff168152506133bd565b5f888152606a60205260409020805463ffffffff1916905561136c8861358a565b335f818152606760205260409020805460ff19811660ff9182165f19019091161790556064546113b1916001600160a01b03909116906001600160801b0388166135c2565b6040516001600160801b0386168152889033907f8903a5b5d08a841e7f68438387f1da20c84dea756379ed37e633ff3854b99b849060200160405180910390a35050505050505061140160015f55565b50565b61140c613625565b6001600160a01b0381166114335760405163d92e233d60e01b815260040160405180910390fd5b606d80546001600160a01b0319166001600160a01b0392909216919091179055565b610fc683838360405180602001604052805f815250611e97565b6114776131a8565b606f54600160a01b900460ff166114cd5760405162461bcd60e51b81526020600482015260156024820152744e6f7420696e20656d657267656e6379206d6f646560581b60448201526064015b60405180910390fd5b336114d782611608565b6001600160a01b0316146114fe576040516359dc379f60e01b815260040160405180910390fd5b5f818152606660208181526040808420815160808101835281546001600160801b03808216808452600160801b909204168286015260018301805463ffffffff80821696850196909652600160201b810490951660608401528888529590945294905567ffffffffffffffff19169091556115788361358a565b335f818152606760205260409020805460ff19811660ff9182165f19019091161790556064546115bd916001600160a01b03909116906001600160801b0384166135c2565b6040516001600160801b0382168152839033907f4f27eb511b2a4633cfb633ac1c4a99b4c298ca6488b29ec26f3504a5927f67289060200160405180910390a3505061140160015f55565b5f6108b9826130f2565b5f5f5160206152db5f395f51905f526001600160a01b03831661164a576040516322718ad960e21b81525f60048201526024016114c4565b6001600160a01b039092165f908152600390920160205250604090205490565b611672613625565b61167b5f613680565b565b611685613625565b6001600160a01b0381166116ac5760405163d92e233d60e01b815260040160405180910390fd5b6065546001600160a01b0316156117055760405162461bcd60e51b815260206004820152601760248201527f4469737472696275746f7220616c72656164792073657400000000000000000060448201526064016114c4565b606580546001600160a01b0319166001600160a01b0392909216919091179055565b6065545f90600160a01b900463ffffffff1682111561175357606554600160a01b900463ffffffff1691505b5f835b83811015611868575f6117688261316f565b6001600160a01b031614611860575f81815260666020908152604091829020825160808101845281546001600160801b03808216808452600160801b909204169382019390935260019091015463ffffffff80821694830194909452600160201b9004909216606083015215806117ef5750806040015163ffffffff164263ffffffff1610155b156117fa5750611860565b80516001600160801b03165f61181362ed4e0083614f12565b90506001600160801b0381111561182c57505050611860565b5f819050806001600160801b031684602001516001600160801b03161461185b578561185781614e97565b9650505b505050505b600101611756565b509392505050565b611878613625565b606554600160a01b900463ffffffff168111156118a15750606554600160a01b900463ffffffff165b5f6118ac8383614f44565b905060648111156118bb575f5ffd5b825b82811015610db0575f6118cf8261316f565b6001600160a01b031614611c3e575f81815260666020908152604091829020825160808101845281546001600160801b03808216808452600160801b909204169382019390935260019091015463ffffffff80821694830194909452600160201b9004909216606083015215806119565750806040015163ffffffff164263ffffffff1610155b156119615750611c3e565b80516001600160801b03165f61197a62ed4e0083614f12565b90506001600160801b0381111561199357505050611c3e565b602083015181906001600160801b038083169116036119b55750505050611c3e565b5f4285604001516119c69190614ecb565b90505f6119e263ffffffff83166001600160801b038516614ee7565b90505f6119fb62ed4e006001600160801b038616614ee7565b611a15670de0b6b3a7640000673782dace9d900000614f25565b611a28906001600160801b031684614ee7565b611a329190614f12565b611a4490670de0b6b3a7640000614f57565b9050673782dace9d900000811115611a615750673782dace9d9000005b670de0b6b3a7640000811015611a7c5750670de0b6b3a76400005b611acf8860405180604001604052808a5f0151600f0b81526020018a6040015163ffffffff1681525060405180604001604052808b5f0151600f0b81526020018b6040015163ffffffff168152506133bd565b6040518060800160405280885f01516001600160801b03168152602001856001600160801b03168152602001886040015163ffffffff1681526020014263ffffffff1681525060665f8a81526020019081526020015f205f820151815f015f6101000a8154816001600160801b0302191690836001600160801b031602179055506020820151815f0160106101000a8154816001600160801b0302191690836001600160801b031602179055506040820151816001015f6101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160046101000a81548163ffffffff021916908363ffffffff16021790555090505087611bd68961316f565b6001600160a01b03167f3032be442129e161b4ae1cdee94871a69de2c16ee2007f31fc209a715673455c896040015184604051611c2e92919063ffffffff9290921682526001600160801b0316602082015260400190565b60405180910390a3505050505050505b6001016118bd565b5f818152606660209081526040808320815160808101835281546001600160801b038082168352600160801b90910416938101939093526001015463ffffffff808216928401839052600160201b90910481166060840152421610611cb55750670de0b6b3a764000092915050565b5f611ccb670de0b6b3a764000062ed4e00614f6a565b6001600160801b0316611cee670de0b6b3a7640000673782dace9d900000614f25565b8351611d06916001600160801b039081169116614ee7565b611d109190614f12565b90506001600160801b03811115611d3a5760405163162908e360e11b815260040160405180910390fd5b604082015181905f90611d4e904290614ecb565b90505f611d6a63ffffffff83166001600160801b038516614ee7565b611d7c90670de0b6b3a7640000614f57565b9050673782dace9d9000006001600160801b0382161115611dab5750673782dace9d9000009695505050505050565b670de0b6b3a76400006001600160801b0382161015611dd85750670de0b6b3a76400009695505050505050565b9695505050505050565b7f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930180546060915f5160206152db5f395f51905f52916108de90614e37565b60695463ffffffff9081165f90815260686020908152604080832081516080810183528154600f81810b8352600160801b909104900b938101939093526001015480851691830191909152600160201b9004909216606083015290611e8581846136f0565b9392505050565b61097f338383613805565b611ea18483613474565b610db0848484846138b4565b611eb56131a8565b611ebd6131ff565b8080421115611edf57604051631ab7da6b60e01b815260040160405180910390fd5b6002831015611f015760405163162908e360e11b815260040160405180910390fd5b5f80805b8581101561200a5733611f2f888884818110611f2357611f23614e6f565b90506020020135611608565b6001600160a01b031614611f56576040516359dc379f60e01b815260040160405180910390fd5b5f60665f898985818110611f6c57611f6c614e6f565b602090810292909201358352508181019290925260409081015f20815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b900490911660608201529150611fdf9085614f93565b93508263ffffffff16816040015163ffffffff16111561200157806040015192505b50600101611f05565b505f6120164283614ecb565b905062ed4e0063ffffffff8216111561204257604051637616640160e01b815260040160405180910390fd5b5f62ed4e00612061670de0b6b3a7640000673782dace9d900000614f25565b6001600160801b0316856001600160801b031661207e9190614ee7565b6120889190614f12565b90506001600160801b038111156120b25760405163162908e360e11b815260040160405180910390fd5b6065805482915f916014906120d390600160a01b900463ffffffff16614fb2565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff16905061210233826138cc565b5f5b898110156121ed575f8b8b8381811061211f5761211f614e6f565b602090810292909201355f818152606684526040808220815160808101835281546001600160801b038082168352600160801b909104168188015260019091015463ffffffff808216838501908152600160201b90920481166060840152835180850185528351600f0b8152915116818801528251808401909352838352958201929092529194509291506121b790849083906133bd565b5f838152606660205260408120908155600101805467ffffffffffffffff191690556121e28361358a565b505050600101612104565b50604080518082018252600f88900b815263ffffffff871660208083019190915282518084019093525f808452908301529061222b908390836133bd565b6040518060800160405280886001600160801b03168152602001846001600160801b031681526020018763ffffffff1681526020014263ffffffff1681525060665f8481526020019081526020015f205f820151815f015f6101000a8154816001600160801b0302191690836001600160801b031602179055506020820151815f0160106101000a8154816001600160801b0302191690836001600160801b031602179055506040820151816001015f6101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055509050508a8a905060675f336001600160a01b03166001600160a01b031681526020019081526020015f205f9054906101000a900460ff160360010160675f336001600160a01b03166001600160a01b031681526020019081526020015f205f6101000a81548160ff021916908360ff16021790555081336001600160a01b03167fdbd81f1b10e6f1395ede56cabac59119f8be0cb5ca3ef0ca44f859782893495489896040516123e99291906001600160801b0392909216825263ffffffff16602082015260400190565b60405180910390a35050505050505050610fc660015f55565b61240a6131a8565b6124126131ff565b818042111561243457604051631ab7da6b60e01b815260040160405180910390fd5b3361243e86611608565b6001600160a01b031614612465576040516359dc379f60e01b815260040160405180910390fd5b836001600160801b03165f0361248e5760405163162908e360e11b815260040160405180910390fd5b5f858152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b90049091166060820152910361250957604051632254ea3d60e11b815260040160405180910390fd5b806040015163ffffffff164263ffffffff1610612539576040516307b7d7dd60e51b815260040160405180910390fd5b80515f90612548908790614f93565b90505f61255482613245565b90505f4284604001516125679190614ecb565b90505f61258363ffffffff83166001600160801b038516614ee7565b61259590670de0b6b3a7640000614f57565b9050673782dace9d9000006001600160801b03821611156125c957604051638f651fb760e01b815260040160405180910390fd5b866001600160801b0316816001600160801b031610156125fc57604051638199f5f360e01b815260040160405180910390fd5b6064546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015612642573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126669190614fd6565b60645490915061268a906001600160a01b031633306001600160801b038e166138e5565b61269d6001600160801b038b1682614f57565b6064546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156126e3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127079190614fd6565b14612725576040516312171d8360e31b815260040160405180910390fd5b8551612731908361334b565b6127818b6040518060400160405280895f0151600f0b8152602001896040015163ffffffff16815250604051806040016040528089600f0b81526020018a6040015163ffffffff168152506133bd565b6040518060800160405280866001600160801b03168152602001856001600160801b03168152602001876040015163ffffffff1681526020014263ffffffff1681525060665f8d81526020019081526020015f205f820151815f015f6101000a8154816001600160801b0302191690836001600160801b031602179055506020820151815f0160106101000a8154816001600160801b0302191690836001600160801b031602179055506040820151816001015f6101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055509050508a336001600160a01b03167f1381e2f7d0d4b71a58d34dc3db2051dd52769766e65eabf380c9b4ea93f0890b8c88866040516128d7939291906001600160801b0393841681529183166020830152909116604082015260600190565b60405180910390a350505050505050610db060015f55565b6128f7613625565b606f805460ff60a01b1916600160a01b17905561291261341f565b606f546040516001600160a01b0390911681527fc0a1c7e9f05b4d536e1ff8606bae9b847cdb43ef4a9b2d7a503a88cee08dccdb906020015b60405180910390a1565b60605f6129618361316f565b6001600160a01b03160361298757604051626f708760e21b815260040160405180910390fd5b606d546001600160a01b03166129b0576040516338a69c8d60e21b815260040160405180910390fd5b606d54604051602481018490525f9182916001600160a01b039091169060440160408051601f198184030181529181526020820180516001600160e01b031663c87b56dd60e01b17905251612a059190614fed565b5f60405180830381855afa9150503d805f8114612a3d576040519150601f19603f3d011682016040523d82523d5f602084013e612a42565b606091505b509150915081612a8c5760405162461bcd60e51b8152602060048201526015602482015274105c9d081c1c9bde1e4818d85b1b0819985a5b1959605a1b60448201526064016114c4565b80806020019051810190612aa09190615003565b949350505050565b5f63ffffffff82161580612ac4575062ed4e0063ffffffff8316115b15612ae257604051637616640160e01b815260040160405180910390fd5b826001600160801b03165f03612b0b5760405163162908e360e11b815260040160405180910390fd5b5f612b1584613245565b9050612aa08184613288565b5f828152606a602052604081205463ffffffff16808203612b45575f9150506108b9565b5f848152606b6020908152604080832063ffffffff80861685529083529281902081516080810183528154600f81810b8352600160801b909104900b9381019390935260010154808416918301829052600160201b9004909216606082015290612baf9085614ecb565b63ffffffff168160200151612bc49190615078565b81518290612bd3908390615097565b600f90810b90915282515f910b12159050612bec575f81525b516001600160801b0316949350505050565b606d545f90819063ffffffff600160a01b909104811690841611612c225782612c3c565b606d54612c3c90600160a01b900463ffffffff1684614ecb565b90505f62ed4e00612c5d670de0b6b3a7640000673782dace9d900000614f25565b6001600160801b0316866001600160801b0316612c7a9190614ee7565b612c849190614f12565b905080612ca063ffffffff84166001600160801b038316614ee7565b611dd890670de0b6b3a7640000614f57565b5f612cbb6131a8565b612cc36131ff565b8280421115612ce557604051631ab7da6b60e01b815260040160405180910390fd5b856001600160801b03165f03612d0e5760405163162908e360e11b815260040160405180910390fd5b63ffffffff85161580612d29575062ed4e0063ffffffff8616115b15612d4757604051637616640160e01b815260040160405180910390fd5b335f90815260676020526040902054606460ff90911610612d7b5760405163133cbc4f60e01b815260040160405180910390fd5b5f612d868642614eaf565b90505f5f612d9589898861391d565b915091505f60405180604001604052808b600f0b81526020018563ffffffff168152509050612de25f60405180604001604052805f600f0b81526020015f63ffffffff16815250836133bd565b6064546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015612e28573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e4c9190614fd6565b606454909150612e70906001600160a01b031633306001600160801b038f166138e5565b612e836001600160801b038c1682614f57565b6064546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015612ec9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612eed9190614fd6565b14612f0b576040516312171d8360e31b815260040160405180910390fd5b60658054600163ffffffff600160a01b80840482168381019092160263ffffffff60a01b1990931692909217909255335f818152606760205260409020805460ff80821690950190941660ff19909416939093179092559750612f6e90886138cc565b604080516080810182526001600160801b03808e168252868116602080840191825263ffffffff808b16858701908152428216606087019081525f8f8152606690945296909220945192518416600160801b0292909316919091178355516001909201805493518216600160201b0267ffffffffffffffff1990941692909116919091179190911790556130028b8461334b565b604080516001600160801b038d16815263ffffffff87166020820152889133917fdbd81f1b10e6f1395ede56cabac59119f8be0cb5ca3ef0ca44f8597828934954910160405180910390a3505050505050612aa060015f55565b6001600160a01b039182165f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab00793056020908152604080832093909416825291909152205460ff1690565b6130b0613625565b6001600160a01b0381166130d957604051631e4fbdf760e01b81525f60048201526024016114c4565b61140181613680565b6130ea613625565b61167b613a77565b5f5f6130fd8361316f565b90506001600160a01b0381166108b957604051637e27328960e01b8152600481018490526024016114c4565b5f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930460205260409020546001600160a01b031690565b610fc68383836001613ab0565b5f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930260205260409020546001600160a01b031690565b60025f54036131f95760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016114c4565b60025f55565b60325460ff161561167b5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016114c4565b5f6001600160801b0382168161325e62ed4e0083614f12565b90506001600160801b03811115611e855760405163162908e360e11b815260040160405180910390fd5b5f806132a363ffffffff84166001600160801b038616614ee7565b90505f6132bc62ed4e006001600160801b038716614ee7565b6132d6670de0b6b3a7640000673782dace9d900000614f25565b6132e9906001600160801b031684614ee7565b6132f39190614f12565b61330590670de0b6b3a7640000614f57565b9050673782dace9d90000081111561332957673782dace9d900000925050506108b9565b670de0b6b3a7640000811015612aa057670de0b6b3a7640000925050506108b9565b5f670de0b6b3a764000061336b6001600160801b03848116908616614ee7565b6133759190614f12565b606e805491925082915f906133949084906001600160801b0316614f93565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550505050565b6133c5613bc3565b8215610fc657610fc6838383613d35565b60015f55565b6133e4613f2b565b61097f8282613f74565b6133f6613f2b565b61167b613fa4565b613406613f2b565b61167b613fac565b613416613f2b565b61140181613fc0565b6134276131ff565b6032805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861345c3390565b6040516001600160a01b03909116815260200161294b565b6001600160a01b0382161580159061349657506065546001600160a01b031615155b1561097f5760655460405163379607f560e01b8152600481018390526001600160a01b039091169063379607f5906024016020604051808303815f875af11580156134e3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fc69190614fd6565b6001600160a01b03821661353057604051633250574960e11b81525f60048201526024016114c4565b5f61353c838333613fc8565b9050836001600160a01b0316816001600160a01b031614610db0576040516364283d7b60e01b81526001600160a01b03808616600483015260248201849052821660448201526064016114c4565b5f6135965f835f613fc8565b90506001600160a01b03811661097f57604051637e27328960e01b8152600481018390526024016114c4565b6040516001600160a01b038316602482015260448101829052610fc690849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526140ca565b336136577f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b03161461167b5760405163118cdaa760e01b81523360048201526024016114c4565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f5f8390505f62093a8080836040015161370a91906150c4565b61371491906150eb565b90505f5b60ff8110156137e05761372e62093a8083614eaf565b91505f63ffffffff808716908416111561374a57859250613764565b5063ffffffff82165f908152606c6020526040902054600f0b5b60408401516137739084614ecb565b63ffffffff1684602001516137889190615078565b84518590613797908390615097565b600f0b90525063ffffffff808716908416036137b357506137e0565b80846020018181516137c5919061510a565b600f0b9052505063ffffffff82166040840152600101613718565b505f825f0151600f0b12156137f3575f82525b50516001600160801b03169392505050565b5f5160206152db5f395f51905f526001600160a01b03831661384557604051630b61174360e31b81526001600160a01b03841660048201526024016114c4565b6001600160a01b038481165f818152600584016020908152604080832094881680845294825291829020805460ff191687151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a350505050565b6138bf848484610fb1565b610db0338585858561419d565b61097f828260405180602001604052805f8152506142c5565b6040516001600160a01b0380851660248301528316604482015260648101829052610db09085906323b872dd60e01b906084016135ee565b5f808061393b670de0b6b3a76400006001600160801b038816614f12565b90505f613958670de0b6b3a7640000673782dace9d900000614f25565b6001600160801b031690505f613979670de0b6b3a764000062ed4e00614f6a565b6001600160801b031661398c8385614ee7565b6139969190614f12565b90506001600160801b038111156139c05760405163162908e360e11b815260040160405180910390fd5b9350835f670de0b6b3a76400006139e663ffffffff8a166001600160801b038516614ee7565b6139f09190614f12565b9050613a0481670de0b6b3a7640000614f57565b9450673782dace9d9000006001600160801b0386161115613a3857604051638f651fb760e01b815260040160405180910390fd5b866001600160801b0316856001600160801b03161015613a6b57604051638199f5f360e01b815260040160405180910390fd5b50505050935093915050565b613a7f6142dc565b6032805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa3361345c565b5f5160206152db5f395f51905f528180613ad257506001600160a01b03831615155b15613b93575f613ae1856130f2565b90506001600160a01b03841615801590613b0d5750836001600160a01b0316816001600160a01b031614155b8015613b205750613b1e818561305c565b155b15613b495760405163a9fbf51f60e01b81526001600160a01b03851660048201526024016114c4565b8215613b915784866001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5f93845260040160205250506040902080546001600160a01b0319166001600160a01b0392909216919091179055565b60695463ffffffff16613bf5604080516080810182525f80825260208201819052918101829052606081019190915290565b63ffffffff821615613c6e5760685f613c0f600185614ecb565b63ffffffff908116825260208083019390935260409182015f2082516080810184528154600f81810b8352600160801b909104900b948101949094526001015480821692840192909252600160201b9091041660608201529050613c9b565b50604080516080810182525f808252602082015263ffffffff428116928201929092524390911660608201525b60408101515f63ffffffff808316429091161115613cfc576040830151613cc89063ffffffff1642614f44565b6060840151613cdd9063ffffffff1643614f44565b613cef90670de0b6b3a7640000614ee7565b613cf99190614f12565b90505b613d0883838387614325565b9250613d15846001614eaf565b6069805463ffffffff191663ffffffff9290921691909117905550505050565b604080516080810182525f808252602082018190529181018290526060810191909152604080516080810182525f8082526020820181905291810182905260608101919091524263ffffffff16846020015163ffffffff16118015613d9f57505f845f0151600f0b135b15613de9578351613db49062ed4e0090615137565b600f0b602080840191909152840151613dce904290614ecb565b63ffffffff168260200151613de39190615078565b600f0b82525b4263ffffffff16836020015163ffffffff16118015613e0d57505f835f0151600f0b135b15613e57578251613e229062ed4e0090615137565b600f0b602080830191909152830151613e3c904290614ecb565b63ffffffff168160200151613e519190615078565b600f0b81525b613e6b84848460200151846020015161452a565b5f858152606a6020526040812054613e8a9063ffffffff166001614eaf565b5f878152606a60209081526040808320805463ffffffff95861663ffffffff199091168117909155428516878301908152438616606089019081529b8552606b84528285209185529083529220855195909101516001600160801b03908116600160801b02951694909417845551600193909301805497518216600160201b0267ffffffffffffffff19909816939091169290921795909517905550505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661167b57604051631afcd79f60e31b815260040160405180910390fd5b613f7c613f2b565b5f5160206152db5f395f51905f5280613f9584826151b7565b5060018101610db083826151b7565b6133d6613f2b565b613fb4613f2b565b6032805460ff19169055565b6130b0613f2b565b5f5f5160206152db5f395f51905f5281613fe18561316f565b90506001600160a01b03841615613ffd57613ffd818587614665565b6001600160a01b03811615614039576140185f865f5f613ab0565b6001600160a01b0381165f908152600383016020526040902080545f190190555b6001600160a01b03861615614069576001600160a01b0386165f9081526003830160205260409020805460010190555b5f85815260028301602052604080822080546001600160a01b0319166001600160a01b038a811691821790925591518893918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a495945050505050565b5f61411e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166146c99092919063ffffffff16565b905080515f148061413e57508080602001905181019061413e9190615272565b610fc65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016114c4565b6001600160a01b0383163b156142be57604051630a85bd0160e11b81526001600160a01b0384169063150b7a02906141df90889088908790879060040161528d565b6020604051808303815f875af1925050508015614219575060408051601f3d908101601f19168201909252614216918101906152bf565b60015b614280573d808015614246576040519150601f19603f3d011682016040523d82523d5f602084013e61424b565b606091505b5080515f0361427857604051633250574960e11b81526001600160a01b03851660048201526024016114c4565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b146142bc57604051633250574960e11b81526001600160a01b03851660048201526024016114c4565b505b5050505050565b6142cf83836146d7565b610fc6335f85858561419d565b60325460ff1661167b5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016114c4565b604080516080810182525f808252602082018190529181018290526060810191909152845f62093a8061435881886150c4565b61436291906150eb565b90505f5b60ff81101561451e5761437c62093a8083614eaf565b91505f63ffffffff4281169084161115614398574292506143b2565b5063ffffffff82165f908152606c6020526040902054600f0b5b6143bc8884614ecb565b63ffffffff1689602001516143d19190615078565b89518a906143e0908390615097565b600f0b9052506020890180518291906143fa90839061510a565b600f0b90525063ffffffff83166040808b0191909152840151670de0b6b3a7640000906144279085614ecb565b6144409063ffffffff166001600160801b038a16614ee7565b61444a9190614f12565b846060015163ffffffff1661445f9190614f57565b63ffffffff90811660608b015242811690841603614489575063ffffffff4316606089015261451e565b8860685f846144998a6001614eaf565b6144a39190614eaf565b63ffffffff908116825260208083019390935260409182015f208451938501516001600160801b03908116600160801b02941693909317835590830151600190920180546060909401518216600160201b0267ffffffffffffffff199094169290911691909117919091179055509095508590600101614366565b50959695505050505050565b4263ffffffff16846020015163ffffffff1611156145cb5760208085015163ffffffff165f908152606c9091526040902054600f0b614569838261510a565b9050846020015163ffffffff16846020015163ffffffff1603614593576145908282615097565b90505b60208581015163ffffffff165f908152606c9091526040902080546001600160801b0319166001600160801b03929092169190911790555b4263ffffffff16836020015163ffffffff161115610db057836020015163ffffffff16836020015163ffffffff161115610db05760208084015163ffffffff165f908152606c9091526040902054600f0b6146268282615097565b60208086015163ffffffff165f908152606c9091526040902080546001600160801b039092166001600160801b03199092169190911790555050505050565b614670838383614738565b610fc6576001600160a01b03831661469e57604051637e27328960e01b8152600481018290526024016114c4565b60405163177e802f60e01b81526001600160a01b0383166004820152602481018290526044016114c4565b6060612aa084845f8561479c565b6001600160a01b03821661470057604051633250574960e11b81525f60048201526024016114c4565b5f61470c83835f613fc8565b90506001600160a01b03811615610fc6576040516339e3563760e11b81525f60048201526024016114c4565b5f6001600160a01b03831615801590612aa05750826001600160a01b0316846001600160a01b031614806147715750614771848461305c565b80612aa05750826001600160a01b031661478a83613129565b6001600160a01b031614949350505050565b6060824710156147fd5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016114c4565b5f5f866001600160a01b031685876040516148189190614fed565b5f6040518083038185875af1925050503d805f8114614852576040519150601f19603f3d011682016040523d82523d5f602084013e614857565b606091505b50915091506110d087838387606083156148d15782515f036148ca576001600160a01b0385163b6148ca5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016114c4565b5081612aa0565b612aa083838151156148e65781518083602001fd5b8060405162461bcd60e51b81526004016114c4919061495e565b6001600160e01b031981168114611401575f5ffd5b5f60208284031215614925575f5ffd5b8135611e8581614900565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611e856020830184614930565b5f60208284031215614980575f5ffd5b5035919050565b80356001600160a01b038116811461499d575f5ffd5b919050565b5f5f604083850312156149b3575f5ffd5b6149bc83614987565b946020939093013593505050565b5f602082840312156149da575f5ffd5b611e8582614987565b602080825282518282018190525f918401906040840190835b81811015614a1a5783518352602093840193909201916001016149fc565b509095945050505050565b803563ffffffff8116811461499d575f5ffd5b5f5f60408385031215614a49575f5ffd5b82359150614a5960208401614a25565b90509250929050565b80356001600160801b038116811461499d575f5ffd5b5f5f5f5f60808587031215614a8b575f5ffd5b84359350614a9b60208601614a25565b925060408501359150614ab060608601614a62565b905092959194509250565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614af857614af8614abb565b604052919050565b5f67ffffffffffffffff821115614b1957614b19614abb565b50601f01601f191660200190565b5f614b39614b3484614b00565b614acf565b9050828152838383011115614b4c575f5ffd5b828260208301375f602084830101529392505050565b5f82601f830112614b71575f5ffd5b611e8583833560208501614b27565b5f5f5f5f60808587031215614b93575f5ffd5b614b9c85614987565b9350614baa60208601614987565b9250604085013567ffffffffffffffff811115614bc5575f5ffd5b614bd187828801614b62565b925050606085013567ffffffffffffffff811115614bed575f5ffd5b614bf987828801614b62565b91505092959194509250565b5f5f5f60608486031215614c17575f5ffd5b614c2084614987565b9250614c2e60208501614987565b929592945050506040919091013590565b5f60208284031215614c4f575f5ffd5b611e8582614a25565b5f5f60408385031215614c69575f5ffd5b50508035926020909101359150565b8015158114611401575f5ffd5b5f5f60408385031215614c96575f5ffd5b614c9f83614987565b91506020830135614caf81614c78565b809150509250929050565b5f5f5f5f60808587031215614ccd575f5ffd5b614cd685614987565b9350614ce460208601614987565b925060408501359150606085013567ffffffffffffffff811115614d06575f5ffd5b8501601f81018713614d16575f5ffd5b614bf987823560208401614b27565b5f5f5f60408486031215614d37575f5ffd5b833567ffffffffffffffff811115614d4d575f5ffd5b8401601f81018613614d5d575f5ffd5b803567ffffffffffffffff811115614d73575f5ffd5b8660208260051b8401011115614d87575f5ffd5b6020918201979096509401359392505050565b5f5f5f5f60808587031215614dad575f5ffd5b84359350614a9b60208601614a62565b5f5f60408385031215614dce575f5ffd5b614dd783614a62565b9150614a5960208401614a25565b5f5f5f5f60808587031215614df8575f5ffd5b614e0185614a62565b9350614a9b60208601614a25565b5f5f60408385031215614e20575f5ffd5b614e2983614987565b9150614a5960208401614987565b600181811c90821680614e4b57607f821691505b602082108103614e6957634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f60018201614ea857614ea8614e83565b5060010190565b63ffffffff81811683821601908111156108b9576108b9614e83565b63ffffffff82811682821603908111156108b9576108b9614e83565b80820281158282048414176108b9576108b9614e83565b634e487b7160e01b5f52601260045260245ffd5b5f82614f2057614f20614efe565b500490565b6001600160801b0382811682821603908111156108b9576108b9614e83565b818103818111156108b9576108b9614e83565b808201808211156108b9576108b9614e83565b6001600160801b038181168382160290811690818114614f8c57614f8c614e83565b5092915050565b6001600160801b0381811683821601908111156108b9576108b9614e83565b5f63ffffffff821663ffffffff8103614fcd57614fcd614e83565b60010192915050565b5f60208284031215614fe6575f5ffd5b5051919050565b5f82518060208501845e5f920191825250919050565b5f60208284031215615013575f5ffd5b815167ffffffffffffffff811115615029575f5ffd5b8201601f81018413615039575f5ffd5b8051615047614b3482614b00565b81815285602083850101111561505b575f5ffd5b8160208401602083015e5f91810160200191909152949350505050565b5f82600f0b82600f0b0280600f0b9150808214614f8c57614f8c614e83565b600f82810b9082900b0360016001607f1b0319811260016001607f1b03821317156108b9576108b9614e83565b5f63ffffffff8316806150d9576150d9614efe565b8063ffffffff84160491505092915050565b63ffffffff8181168382160290811690818114614f8c57614f8c614e83565b600f81810b9083900b0160016001607f1b03811360016001607f1b0319821217156108b9576108b9614e83565b5f81600f0b83600f0b8061514d5761514d614efe565b60016001607f1b031982145f198214161561516a5761516a614e83565b90059392505050565b601f821115610fc657805f5260205f20601f840160051c810160208510156151985750805b601f840160051c820191505b818110156142be575f81556001016151a4565b815167ffffffffffffffff8111156151d1576151d1614abb565b6151e5816151df8454614e37565b84615173565b6020601f821160018114615217575f83156152005750848201515b5f19600385901b1c1916600184901b1784556142be565b5f84815260208120601f198516915b828110156152465787850151825560209485019460019092019101615226565b508482101561526357868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f60208284031215615282575f5ffd5b8151611e8581614c78565b6001600160a01b03858116825284166020820152604081018390526080606082018190525f90611dd890830184614930565b5f602082840312156152cf575f5ffd5b8151611e858161490056fe80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079300a2646970667358221220ef9a63d329c5cb68fcb78c323435d0abb474f0582e53487911b1c7ec2e40021864736f6c634300081b0033
Deployed Bytecode Sourcemap
151541:31361:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101706:316;;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;101706:316:0;;;;;;;;102606:149;;;:::i;:::-;;;;;;;:::i;103894:158::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1506:32:1;;;1488:51;;1476:2;1461:18;103894:158:0;1342:203:1;103713:115:0;;;;;;:::i;:::-;;:::i;:::-;;177501:104;177585:12;;-1:-1:-1;;;;;177585:12:0;177501:104;;177988:562;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;153704:68::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;153704:68:0;;;;;;;;;;-1:-1:-1;;;153704:68:0;;;;;;;;;3797:2:1;3786:22;;;3768:41;;3845:22;;;;3840:2;3825:18;;3818:50;3916:10;3904:23;;;3884:18;;;3877:51;;;;3964:23;;;3959:2;3944:18;;3937:51;3755:3;3740:19;153704:68:0;3545:449:1;167521:1650:0;;;;;;:::i;:::-;;:::i;155275:736::-;;;;;;:::i;:::-;;:::i;177613:96::-;177687:14;;-1:-1:-1;;;177687:14:0;;;;177613:96;;162367:191;;;;;;:::i;:::-;;:::i;179379:603::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;7099:47:1;;;7081:66;;7069:2;7054:18;179379:603:0;6935:218:1;177717:109:0;177798:20;;-1:-1:-1;;;;;177798:20:0;177717:109;;162804:1494;;;;;;:::i;:::-;;:::i;177834:146::-;;;;;;:::i;:::-;;:::i;105280:134::-;;;;;;:::i;:::-;;:::i;176685:585::-;;;;;;:::i;:::-;;:::i;153831:23::-;;;;;-1:-1:-1;;;;;153831:23:0;;;153779:45;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;7520:2:1;7509:22;;;;7491:41;;7479:2;7464:18;153779:45:0;7347:191:1;145969:86:0;146040:7;;;;145969:86;;102419:120;;;;;;:::i;:::-;;:::i;102086:271::-;;;;;;:::i;:::-;;:::i;:::-;;;7689:25:1;;;7677:2;7662:18;102086:271:0;7543:177:1;150264:103:0;;;:::i;156019:280::-;;;;;;:::i;:::-;;:::i;182133:766::-;;;;;;:::i;:::-;;:::i;179986:2094::-;;;;;;:::i;:::-;;:::i;153430:46::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;153430:46:0;;;;-1:-1:-1;;;153430:46:0;;;;;;;;;-1:-1:-1;;;153430:46:0;;;;;;;;;-1:-1:-1;;;;;8321:47:1;;;8303:66;;8405:47;;;;8400:2;8385:18;;8378:75;8501:10;8489:23;;;8469:18;;;8462:51;;;;8549:23;8544:2;8529:18;;8522:51;8290:3;8275:19;153430:46:0;8076:503:1;156630:858:0;;;;;;:::i;:::-;;:::i;149529:147::-;148360:22;149660:8;-1:-1:-1;;;;;149660:8:0;149529:147;;153572:44;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;153572:44:0;;;;;;;;;;-1:-1:-1;;;153572:44:0;;;;;153623:19;;;;;;;;;;;;8758:10:1;8746:23;;;8728:42;;8716:2;8701:18;153623:19:0;8584:192:1;102824:153:0;;;:::i;171030:199::-;;;;;;:::i;:::-;;:::i;155000:45::-;;;;;;:::i;:::-;;;;;;;;;;;;;;177377:116;;;;;;:::i;:::-;-1:-1:-1;;;;;177465:20:0;177440:5;177465:20;;;:14;:20;;;;;;;;;177377:116;;;;8953:4:1;8941:17;;;8923:36;;8911:2;8896:18;177377:116:0;8781:184:1;104124:146:0;;;;;;:::i;:::-;;:::i;162566:226::-;;;;;;:::i;:::-;;:::i;172913:2544::-;;;;;;:::i;:::-;;:::i;153484:47::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;169183:1837;;;;;;:::i;:::-;;:::i;176505:172::-;;;:::i;178554:495::-;;;;;;:::i;:::-;;:::i;179053:322::-;;;;;;:::i;:::-;;:::i;175465:490::-;;;;;;:::i;:::-;;:::i;175963:506::-;;;;;;:::i;:::-;;:::i;165722:1791::-;;;;;;:::i;:::-;;:::i;153649:48::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;104341:213;;;;;;:::i;:::-;;:::i;150522:220::-;;;;;;:::i;:::-;;:::i;177278:68::-;;;:::i;101706:316::-;101819:4;-1:-1:-1;;;;;;101856:40:0;;-1:-1:-1;;;101856:40:0;;:105;;-1:-1:-1;;;;;;;101913:48:0;;-1:-1:-1;;;101913:48:0;101856:105;:158;;;-1:-1:-1;;;;;;;;;;99729:40:0;;;101978:36;101836:178;101706:316;-1:-1:-1;;101706:316:0:o;102606:149::-;-1:-1:-1;;;;;;;;;;;102733:14:0;;102651:13;;101089:21;;;102733:14;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102606:149;:::o;103894:158::-;103961:7;103981:22;103995:7;103981:13;:22::i;:::-;;104023:21;104036:7;104023:12;:21::i;103713:115::-;103785:35;103794:2;103798:7;25439:10;103785:8;:35::i;:::-;103713:115;;:::o;177988:562::-;-1:-1:-1;;;;;178101:21:0;;178087:11;178101:21;;;:14;:21;;;;;;178049:25;;178101:21;;;178144:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;178144:20:0;;178133:31;;178179:5;:10;;178188:1;178179:10;178175:31;;178191:15;177988:562;;;:::o;178175:31::-;178227:20;;178262:245;178288:12;;-1:-1:-1;;;178288:12:0;;;;178283:17;;178262:245;;;178343:5;-1:-1:-1;;;;;178327:21:0;:12;178336:2;178327:8;:12::i;:::-;-1:-1:-1;;;;;178327:21:0;;178323:173;;178394:2;178369:8;178378:12;178369:22;;;;;;;;:::i;:::-;;;;;;;;;;:27;178415:14;;;;:::i;:::-;;;;178468:5;178452:21;;:12;:21;178448:32;178475:5;178448:32;;178302:4;;178262:245;;;;178527:15;;177988:562;;;:::o;167521:1650::-;143039:21;:19;:21::i;:::-;145574:19:::1;:17;:19::i;:::-;167719:8:::2;156399;156381:15;:26;156377:56;;;156416:17;;-1:-1:-1::0;;;156416:17:0::2;;;;;;;;;;;156377:56;167764:10:::3;167744:16;167752:7:::0;167744::::3;:16::i;:::-;-1:-1:-1::0;;;;;167744:30:0::3;;167740:58;;167783:15;;-1:-1:-1::0;;;167783:15:0::3;;;;;;;;;;;167740:58;167819:24;167846:15:::0;;;:6:::3;:15;::::0;;;;;;;167819:42;;::::3;::::0;::::3;::::0;;;;-1:-1:-1;;;;;167819:42:0;;::::3;::::0;;;-1:-1:-1;;;167819:42:0;;::::3;;::::0;;::::3;::::0;;;;;;;::::3;::::0;::::3;::::0;;::::3;::::0;;;;;;;-1:-1:-1;;;167819:42:0;::::3;::::0;;::::3;::::0;;;;;167876:16;167872:44:::3;;167901:15;;-1:-1:-1::0;;;167901:15:0::3;;;;;;;;;;;167872:44;167972:17;168007:18;167992:4;:12;;;:33;;;;:::i;:::-;167972:53:::0;-1:-1:-1;168036:29:0::3;168068:36;168088:15;167972:53:::0;168068:36:::3;:::i;:::-;168036:68:::0;-1:-1:-1;152872:8:0::3;168119:32;::::0;::::3;;168115:62;;;168160:17;;-1:-1:-1::0;;;168160:17:0::3;;;;;;;;;;;168115:62;168265:16;168284:31;168303:4;:11;;;168284:18;:31::i;:::-;168265:50;;168326:18;168347:54;168368:8;168378:22;168347:20;:54::i;:::-;168326:75;;168429:13;-1:-1:-1::0;;;;;168416:26:0::3;:10;-1:-1:-1::0;;;;;168416:26:0::3;;168412:57;;;168451:18;;-1:-1:-1::0;;;168451:18:0::3;;;;;;;;;;;168412:57;168561:11:::0;;168525:83:::3;::::0;168587:10;168525:21:::3;:83::i;:::-;168652:186;168678:7;168700:57;;;;;;;;168729:4;:11;;;168700:57;;;;;;168744:4;:12;;;168700:57;;;;::::0;168772:55:::3;;;;;;;;168801:4;:11;;;168772:55;;;;;;168816:10;168772:55;;;;::::0;168652:11:::3;:186::i;:::-;168907:173;;;;;;;;168943:4;:11;;;-1:-1:-1::0;;;;;168907:173:0::3;;;;;169060:8;-1:-1:-1::0;;;;;168907:173:0::3;;;;;168978:10;168907:173;;;;;;169022:15;168907:173;;;;::::0;168889:6:::3;:15;168896:7;168889:15;;;;;;;;;;;:191;;;;;;;;;;;;;-1:-1:-1::0;;;;;168889:191:0::3;;;;;-1:-1:-1::0;;;;;168889:191:0::3;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;168889:191:0::3;;;;;-1:-1:-1::0;;;;;168889:191:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;169131:7;169119:10;-1:-1:-1::0;;;;;169106:57:0::3;;169140:10;169152;169106:57;;;;;;13684:10:1::0;13672:23;;;;13654:42;;-1:-1:-1;;;;;13732:47:1;13727:2;13712:18;;13705:75;13642:2;13627:18;;13482:304;169106:57:0::3;;;;;;;;167729:1442;;;;;145604:1:::2;143083:20:::0;142300:1;143603:7;:22;143420:213;143083:20;167521:1650;;;;:::o;155275:736::-;24567:21;19883:15;;-1:-1:-1;;;19883:15:0;;;;19882:16;;19930:14;;19736:30;20315:16;;:34;;;;;20335:14;20315:34;20295:54;;20360:17;20380:11;:16;;20395:1;20380:16;:50;;;;-1:-1:-1;20408:4:0;20400:25;:30;20380:50;20360:70;;20448:12;20447:13;:30;;;;;20465:12;20464:13;20447:30;20443:93;;;20501:23;;-1:-1:-1;;;20501:23:0;;;;;;;;;;;20443:93;20546:18;;-1:-1:-1;;20546:18:0;20563:1;20546:18;;;20575:69;;;;20610:22;;-1:-1:-1;;;;20610:22:0;-1:-1:-1;;;20610:22:0;;;20575:69;-1:-1:-1;;;;;155471:26:0;::::1;::::0;;:77:::1;;-1:-1:-1::0;;;;;;155517:31:0;::::1;::::0;155471:77:::1;155467:103;;;155557:13;;-1:-1:-1::0;;;155557:13:0::1;;;;;;;;;;;155467:103;155595:27;155609:4;155615:6;155595:13;:27::i;:::-;155633:24;:22;:24::i;:::-;155668:17;:15;:17::i;:::-;155696:26;155711:10;155696:14;:26::i;:::-;155735:8;:6;:8::i;:::-;155754:12;:46:::0;;-1:-1:-1;;;;;155754:46:0;;::::1;-1:-1:-1::0;;;;;;155754:46:0;;::::1;;::::0;;;155811:25:::1;:45:::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;155754:12:::1;155906:15:::0;;:12:::1;:15;::::0;:19;:42;;155987:15:::1;155906;155959:44:::0;;::::1;-1:-1:-1::0;;155935:12:0::1;155906:42:::0;;;::::1;-1:-1:-1::0;;;155906:42:0::1;155959:44:::0;;;;-1:-1:-1;;155959:44:0;;;;;;;::::1;::::0;;20666:104;;;;20701:23;;-1:-1:-1;;;;20701:23:0;;;20744:14;;-1:-1:-1;13944:50:1;;20744:14:0;;13932:2:1;13917:18;20744:14:0;;;;;;;20666:104;19668:1109;;;;;155275:736;;;;:::o;162367:191::-;162467:35;162488:4;162494:7;162467:20;:35::i;:::-;162513:36;162532:4;162537:2;162541:7;162513:18;:36::i;:::-;162367:191;;;:::o;179379:603::-;179483:7;179503:18;:23;;179525:1;179503:23;179499:53;;179535:17;;-1:-1:-1;;;179535:17:0;;;;;;;;;;;179499:53;179565:24;179592:15;;;:6;:15;;;;;;;;179565:42;;;;;;;;;-1:-1:-1;;;;;179565:42:0;;;;;;-1:-1:-1;;;179565:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;179565:42:0;;;;;;;;;;179618:16;179614:44;;179643:15;;-1:-1:-1;;;179643:15:0;;;;;;;;;;;179614:44;179671:17;179706:18;179691:4;:12;;;:33;;;;:::i;:::-;179671:53;-1:-1:-1;179731:24:0;179758:36;179778:15;179671:53;179758:36;:::i;:::-;179731:63;-1:-1:-1;152872:8:0;179805:27;;;;179801:57;;;179841:17;;-1:-1:-1;;;179841:17:0;;;;;;;;;;;179801:57;179871:13;179887:31;179906:4;:11;;;179887:18;:31::i;:::-;179871:47;;179932:46;179953:5;179960:17;179932:20;:46::i;:::-;179925:53;179379:603;-1:-1:-1;;;;;;;179379:603:0:o;162804:1494::-;143039:21;:19;:21::i;:::-;162872:13:::1;162888:17;162897:7;162888:8;:17::i;:::-;162872:33:::0;-1:-1:-1;;;;;;162920:19:0;::::1;162916:48;;162948:16;;-1:-1:-1::0;;;162948:16:0::1;;;;;;;;;;;162916:48;-1:-1:-1::0;;;;;162979:19:0;::::1;162988:10;162979:19;162975:47;;163007:15;;-1:-1:-1::0;;;163007:15:0::1;;;;;;;;;;;162975:47;163043:24;163070:15:::0;;;:6:::1;:15;::::0;;;;;;;163043:42;;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;;;163043:42:0;;::::1;::::0;;;-1:-1:-1;;;163043:42:0;;::::1;;::::0;;::::1;::::0;;;;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;163043:42:0;::::1;::::0;;::::1;::::0;;;;;163100:16;163096:44:::1;;163125:15;;-1:-1:-1::0;;;163125:15:0::1;;;;;;;;;;;163096:44;163181:4;:12;;;163155:38;;163162:15;163155:38;;;163151:67;;;163202:16;;-1:-1:-1::0;;;163202:16:0::1;;;;;;;;;;;163151:67;163256:11:::0;;163319:104:::1;::::0;;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;163399:12;;::::1;::::0;163319:104:::1;;;::::0;;::::1;::::0;;;;163239:14:::1;163443:15:::0;;;:6:::1;:15:::0;;;;;;163436:22;;;;::::1;::::0;;-1:-1:-1;;163436:22:0;;;163319:104;163500:29:::1;163450:7:::0;163500:20:::1;:29::i;:::-;163479:50:::0;-1:-1:-1;163540:22:0::1;153078:4;163566:37;-1:-1:-1::0;;;;;163584:19:0;;::::1;::::0;163566:15;::::1;:37;:::i;:::-;163565:51;;;;:::i;:::-;163540:76;;163675:10;-1:-1:-1::0;;;;;163667:19:0::1;163656:6;-1:-1:-1::0;;;;;163648:15:0::1;163631:14;:32;;;;:::i;:::-;:55;163627:85;;163695:17;;-1:-1:-1::0;;;163695:17:0::1;;;;;;;;;;;163627:85;163723:30;163756:26;153078:4;163756:14:::0;:26:::1;:::i;:::-;163723:59:::0;-1:-1:-1;;;;;;163797:42:0;::::1;163793:70;;;163848:15;;-1:-1:-1::0;;;163848:15:0::1;;;;;;;;;;;163793:70;163874:20;:55:::0;;163906:22;;163874:20;::::1;::::0;:55:::1;::::0;163906:22;;-1:-1:-1;;;;;163874:55:0::1;;:::i;:::-;;;;;;;;-1:-1:-1::0;;;;;163874:55:0::1;;;;;-1:-1:-1::0;;;;;163874:55:0::1;;;;;;163950:50;163962:7;163971;163980:19;;;;;;;;163994:1;163980:19;;;;;;163997:1;163980:19;;;;::::0;163950:11:::1;:50::i;:::-;164028:23;::::0;;;:14:::1;:23;::::0;;;;164021:30;;-1:-1:-1;;164021:30:0::1;::::0;;164072:14:::1;164043:7:::0;164072:5:::1;:14::i;:::-;164137:10;164122:26;::::0;;;:14:::1;:26;::::0;;;;:28;;-1:-1:-1;;164122:28:0;::::1;;::::0;;::::1;-1:-1:-1::0;;164122:28:0;;;::::1;;::::0;;164182:12:::1;::::0;:45:::1;::::0;-1:-1:-1;;;;;164182:12:0;;::::1;::::0;-1:-1:-1;;;;;164182:45:0;::::1;:25;:45::i;:::-;164253:37;::::0;-1:-1:-1;;;;;7099:47:1;;7081:66;;164274:7:0;;164262:10:::1;::::0;164253:37:::1;::::0;7069:2:1;7054:18;164253:37:0::1;;;;;;;162861:1437;;;;;;;143083:20:::0;142300:1;143603:7;:22;143420:213;143083:20;162804:1494;:::o;177834:146::-;149415:13;:11;:13::i;:::-;-1:-1:-1;;;;;177904:23:0;::::1;177900:49;;177936:13;;-1:-1:-1::0;;;177936:13:0::1;;;;;;;;;;;177900:49;177956:8;:20:::0;;-1:-1:-1;;;;;;177956:20:0::1;-1:-1:-1::0;;;;;177956:20:0;;;::::1;::::0;;;::::1;::::0;;177834:146::o;105280:134::-;105367:39;105384:4;105390:2;105394:7;105367:39;;;;;;;;;;;;:16;:39::i;176685:585::-;143039:21;:19;:21::i;:::-;176770:14:::1;::::0;-1:-1:-1;;;176770:14:0;::::1;;;176762:48;;;::::0;-1:-1:-1;;;176762:48:0;;14885:2:1;176762:48:0::1;::::0;::::1;14867:21:1::0;14924:2;14904:18;;;14897:30;-1:-1:-1;;;14943:18:1;;;14936:51;15004:18;;176762:48:0::1;;;;;;;;;176845:10;176825:16;176833:7:::0;176825::::1;:16::i;:::-;-1:-1:-1::0;;;;;176825:30:0::1;;176821:58;;176864:15;;-1:-1:-1::0;;;176864:15:0::1;;;;;;;;;;;176821:58;176900:24;176927:15:::0;;;:6:::1;:15;::::0;;;;;;;176900:42;;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;;;176900:42:0;;::::1;::::0;;;-1:-1:-1;;;176900:42:0;;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;176900:42:0;::::1;::::0;;::::1;::::0;;;;177009:15;;;;;;;177002:22;;;-1:-1:-1;;177002:22:0;;;;177035:14:::1;176934:7:::0;177035:5:::1;:14::i;:::-;177100:10;177085:26;::::0;;;:14:::1;:26;::::0;;;;:28;;-1:-1:-1;;177085:28:0;::::1;;::::0;;::::1;-1:-1:-1::0;;177085:28:0;;;::::1;;::::0;;177145:12:::1;::::0;:45:::1;::::0;-1:-1:-1;;;;;177145:12:0;;::::1;::::0;-1:-1:-1;;;;;177145:45:0;::::1;:25;:45::i;:::-;177216:46;::::0;-1:-1:-1;;;;;7099:47:1;;7081:66;;177246:7:0;;177234:10:::1;::::0;177216:46:::1;::::0;7069:2:1;7054:18;177216:46:0::1;;;;;;;176751:519;;143083:20:::0;142300:1;143603:7;:22;143420:213;102419:120;102482:7;102509:22;102523:7;102509:13;:22::i;102086:271::-;102149:7;-1:-1:-1;;;;;;;;;;;;;;;;102229:19:0;;102225:89;;102272:30;;-1:-1:-1;;;102272:30:0;;102299:1;102272:30;;;1488:51:1;1461:18;;102272:30:0;1342:203:1;102225:89:0;-1:-1:-1;;;;;102331:18:0;;;;;;;:11;;;;:18;;-1:-1:-1;102331:18:0;;;;;102086:271::o;150264:103::-;149415:13;:11;:13::i;:::-;150329:30:::1;150356:1;150329:18;:30::i;:::-;150264:103::o:0;156019:280::-;149415:13;:11;:13::i;:::-;-1:-1:-1;;;;;156099:26:0;::::1;156095:52;;156134:13;;-1:-1:-1::0;;;156134:13:0::1;;;;;;;;;;;156095:52;156170:12;::::0;-1:-1:-1;;;;;156170:12:0::1;156162:35:::0;156158:74:::1;;156199:33;::::0;-1:-1:-1;;;156199:33:0;;15235:2:1;156199:33:0::1;::::0;::::1;15217:21:1::0;15274:2;15254:18;;;15247:30;15313:25;15293:18;;;15286:53;15356:18;;156199:33:0::1;15033:347:1::0;156158:74:0::1;156243:12;:48:::0;;-1:-1:-1;;;;;;156243:48:0::1;-1:-1:-1::0;;;;;156243:48:0;;;::::1;::::0;;;::::1;::::0;;156019:280::o;182133:766::-;182256:12;;182228:7;;-1:-1:-1;;;182256:12:0;;;;182248:20;;182244:65;;;182289:12;;-1:-1:-1;;;182289:12:0;;;;;-1:-1:-1;182244:65:0;182321:13;182368:7;182345:532;182387:5;182377:7;:15;182345:532;;;182449:1;182420:17;182429:7;182420:8;:17::i;:::-;-1:-1:-1;;;;;182420:31:0;182416:45;182453:8;182416:45;182482:24;182509:15;;;:6;:15;;;;;;;;;182482:42;;;;;;;;;-1:-1:-1;;;;;182482:42:0;;;;;;-1:-1:-1;;;182482:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;182482:42:0;;;;;;;;;182539:16;;:59;;;182586:4;:12;;;182559:39;;182566:15;182559:39;;;;182539:59;182535:73;;;182600:8;;;182535:73;182653:11;;-1:-1:-1;;;;;182645:20:0;182629:13;182696:15;152872:8;182645:20;182696:15;:::i;:::-;182676:35;-1:-1:-1;;;;;;182726:29:0;;182722:43;;;182757:8;;;;;182722:43;182776:16;182803:9;182776:37;;182852:8;-1:-1:-1;;;;;182838:22:0;:4;:10;;;-1:-1:-1;;;;;182838:22:0;;182834:35;;182862:7;;;;:::i;:::-;;;;182834:35;182405:472;;;;182345:532;182394:9;;182345:532;;;-1:-1:-1;182890:5:0;182133:766;-1:-1:-1;;;182133:766:0:o;179986:2094::-;149415:13;:11;:13::i;:::-;180090:12:::1;::::0;-1:-1:-1;;;180090:12:0;::::1;;;180082:20:::0;::::1;180078:65;;;-1:-1:-1::0;180123:12:0::1;::::0;-1:-1:-1;;;180123:12:0;::::1;;;180078:65;180155:17;180175:15;180183:7:::0;180175:5;:15:::1;:::i;:::-;180155:35;;180213:3;180201:9;:15;180197:29;;;180218:8;;;180197:29;180284:7:::0;180261:1816:::1;180303:5;180293:7;:15;180261:1816;;;180419:1;180390:17;180399:7:::0;180390:8:::1;:17::i;:::-;-1:-1:-1::0;;;;;180390:31:0::1;180386:45:::0;180423:8:::1;180386:45;180452:24;180479:15:::0;;;:6:::1;:15;::::0;;;;;;;;180452:42;;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;;;180452:42:0;;::::1;::::0;;;-1:-1:-1;;;180452:42:0;;::::1;;::::0;;::::1;::::0;;;;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;180452:42:0;::::1;::::0;;::::1;::::0;;;;180509:16;;:59:::1;;;180556:4;:12;;;180529:39;;180536:15;180529:39;;;;180509:59;180505:73;;;180570:8;;;180505:73;180674:11:::0;;-1:-1:-1;;;;;180666:20:0::1;180650:13;180717:15;152872:8;180666:20:::0;180717:15:::1;:::i;:::-;180697:35:::0;-1:-1:-1;;;;;;180747:29:0;::::1;180743:43;;;180778:8;;;;;180743:43;180928:10;::::0;::::1;::::0;180848:9;;-1:-1:-1;;;;;180928:22:0;;::::1;::::0;::::1;::::0;180924:36:::1;;180952:8;;;;;;180924:36;181018:24;181067:15;181045:4;:12;;;:38;;;;:::i;:::-;181018:65:::0;-1:-1:-1;181094:12:0::1;181109:37;;::::0;::::1;-1:-1:-1::0;;;;;181109:17:0;::::1;:37;:::i;:::-;181094:52:::0;-1:-1:-1;181157:18:0::1;181258:27;152872:8;-1:-1:-1::0;;;;;181258:17:0;::::1;:27;:::i;:::-;181220:32;153030:4;152976;181220:32;:::i;:::-;181212:41;::::0;-1:-1:-1;;;;;181212:41:0::1;:4:::0;:41:::1;:::i;:::-;181211:75;;;;:::i;:::-;181178:109;::::0;153030:4:::1;181178:109;:::i;:::-;181157:130:::0;-1:-1:-1;152976:4:0::1;181316:27:::0;::::1;181312:60;;;-1:-1:-1::0;152976:4:0::1;181312:60;153030:4;181387:28:::0;::::1;181383:62;;;-1:-1:-1::0;153030:4:0::1;181383:62;181500:188;181526:7;181548:57;;;;;;;;181577:4;:11;;;181548:57;;;;;;181592:4;:12;;;181548:57;;;;::::0;181620::::1;;;;;;;;181649:4;:11;;;181620:57;;;;;;181664:4;:12;;;181620:57;;;;::::0;181500:11:::1;:188::i;:::-;181727:175;;;;;;;;181763:4;:11;;;-1:-1:-1::0;;;;;181727:175:0::1;;;;;181882:8;-1:-1:-1::0;;;;;181727:175:0::1;;;;;181798:4;:12;;;181727:175;;;;;;181844:15;181727:175;;;;::::0;181709:6:::1;:15;181716:7;181709:15;;;;;;;;;;;:193;;;;;;;;;;;;;-1:-1:-1::0;;;;;181709:193:0::1;;;;;-1:-1:-1::0;;;;;181709:193:0::1;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;181709:193:0::1;;;;;-1:-1:-1::0;;;;;181709:193:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;181988:7;181955:17;181964:7;181955:8;:17::i;:::-;-1:-1:-1::0;;;;;181928:141:0::1;;182011:4;:12;;;182047:10;181928:141;;;;;;13684:10:1::0;13672:23;;;;13654:42;;-1:-1:-1;;;;;13732:47:1;13727:2;13712:18;;13705:75;13642:2;13627:18;;13482:304;181928:141:0::1;;;;;;;;180321:1756;;;;;;;180261:1816;180310:9;;180261:1816;;156630:858:::0;156698:7;156745:15;;;:6;:15;;;;;;;;156718:42;;;;;;;;;-1:-1:-1;;;;;156718:42:0;;;;;-1:-1:-1;;;156718:42:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;156718:42:0;;;;;;;;;156782:15;156775:39;;156771:67;;-1:-1:-1;153030:4:0;;156630:858;-1:-1:-1;;156630:858:0:o;156771:67::-;156921:17;157004:19;153078:4;152872:8;157004:19;:::i;:::-;-1:-1:-1;;;;;156941:83:0;156966:32;153030:4;152976;156966:32;:::i;:::-;156950:11;;156942:57;;-1:-1:-1;;;;;156942:57:0;;;;:20;:57;:::i;:::-;156941:83;;;;:::i;:::-;156921:103;-1:-1:-1;;;;;;157039:29:0;;157035:57;;;157077:15;;-1:-1:-1;;;157077:15:0;;;;;;;;;;;157035:57;157176:12;;;;157127:9;;157103:13;;157176:38;;157198:15;;157176:38;:::i;:::-;157158:56;-1:-1:-1;157225:18:0;157273:25;;;;-1:-1:-1;;;;;157273:14:0;;:25;:::i;:::-;157254:45;;153030:4;157254:45;:::i;:::-;157225:75;-1:-1:-1;152976:4:0;-1:-1:-1;;;;;157325:27:0;;;157321:54;;;-1:-1:-1;152976:4:0;;156630:858;-1:-1:-1;;;;;;156630:858:0:o;157321:54::-;153030:4;-1:-1:-1;;;;;157390:28:0;;;157386:56;;;-1:-1:-1;153030:4:0;;156630:858;-1:-1:-1;;;;;;156630:858:0:o;157386:56::-;157470:10;156630:858;-1:-1:-1;;;;;;156630:858:0:o;102824:153::-;102960:9;102953:16;;102871:13;;-1:-1:-1;;;;;;;;;;;101089:21:0;102953:16;;;:::i;171030:199::-;171157:5;;;;;;171099:7;171144:19;;;:12;:19;;;;;;;;171119:44;;;;;;;;;;;;;;;-1:-1:-1;;;171119:44:0;;;;;;;;;;;;171157:5;171119:44;;;;;;;;;;;;-1:-1:-1;;;171119:44:0;;;;;;;;;171099:7;171189:31;171119:44;171210:9;171189;:31::i;:::-;171174:47;171030:199;-1:-1:-1;;;171030:199:0:o;104124:146::-;104210:52;25439:10;104243:8;104253;104210:18;:52::i;162566:226::-;162690:35;162711:4;162717:7;162690:20;:35::i;:::-;162737:47;162760:4;162766:2;162770:7;162779:4;162737:22;:47::i;172913:2544::-;143039:21;:19;:21::i;:::-;145574:19:::1;:17;:19::i;:::-;173050:8:::2;156399;156381:15;:26;156377:56;;;156416:17;;-1:-1:-1::0;;;156416:17:0::2;;;;;;;;;;;156377:56;173093:1:::3;173075:19:::0;::::3;173071:47;;;173103:15;;-1:-1:-1::0;;;173103:15:0::3;;;;;;;;;;;173071:47;173139:19;::::0;;173274:376:::3;173294:19:::0;;::::3;173274:376;;;173363:10;173339:20;173347:8:::0;;173356:1;173347:11;;::::3;;;;;:::i;:::-;;;;;;;173339:7;:20::i;:::-;-1:-1:-1::0;;;;;173339:34:0::3;;173335:62;;173382:15;;-1:-1:-1::0;;;173382:15:0::3;;;;;;;;;;;173335:62;173426:24;173453:6;:19;173460:8;;173469:1;173460:11;;;;;;;:::i;:::-;;::::0;;::::3;::::0;;;::::3;;173453:19:::0;;-1:-1:-1;173453:19:0;;::::3;::::0;;;;;;;;-1:-1:-1;173453:19:0;173426:46;;::::3;::::0;::::3;::::0;;;;-1:-1:-1;;;;;173426:46:0;;::::3;::::0;;;-1:-1:-1;;;173426:46:0;;::::3;;::::0;;::::3;::::0;;;;;;;::::3;::::0;::::3;::::0;;::::3;::::0;;;;;;;-1:-1:-1;;;173426:46:0;::::3;::::0;;::::3;::::0;;;;;-1:-1:-1;173501:26:0::3;::::0;;::::3;:::i;:::-;;;173561:13;173546:28;;:4;:12;;;:28;;;173542:97;;;173611:4;:12;;;173595:28;;173542:97;-1:-1:-1::0;173315:3:0::3;;173274:376;;;-1:-1:-1::0;173709:24:0::3;173736:39;173759:15;173736:13:::0;:39:::3;:::i;:::-;173709:66:::0;-1:-1:-1;152872:8:0::3;173790:27;::::0;::::3;;173786:57;;;173826:17;;-1:-1:-1::0;;;173826:17:0::3;;;;;;;;;;;173786:57;173864:17;152872:8;173909:32;153030:4;152976;173909:32;:::i;:::-;-1:-1:-1::0;;;;;173885:57:0::3;173893:11;-1:-1:-1::0;;;;;173885:20:0::3;:57;;;;:::i;:::-;173884:69;;;;:::i;:::-;173864:89:::0;-1:-1:-1;;;;;;173968:29:0;::::3;173964:57;;;174006:15;;-1:-1:-1::0;;;174006:15:0::3;;;;;;;;;;;173964:57;174113:12;174111:14:::0;;174059:9;;174032:16:::3;::::0;174113:12:::3;::::0;174111:14:::3;::::0;-1:-1:-1;;;174111:14:0;::::3;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;174090:35;;;;174136:33;174146:10;174158;174136:9;:33::i;:::-;174244:9;174239:512;174259:19:::0;;::::3;174239:512;;;174300:15;174318:8;;174327:1;174318:11;;;;;;;:::i;:::-;;::::0;;::::3;::::0;;;::::3;;174344:27;174374:15:::0;;;:6:::3;:15:::0;;;;;;174344:45;;::::3;::::0;::::3;::::0;;;;-1:-1:-1;;;;;174344:45:0;;::::3;::::0;;-1:-1:-1;;;174344:45:0;;::::3;;::::0;;::::3;::::0;;;;::::3;::::0;::::3;::::0;;::::3;::::0;;;;;;-1:-1:-1;;;174344:45:0;;::::3;::::0;::::3;::::0;;;;174458:127;;;;::::3;::::0;;174514:14;;174458:127:::3;;::::0;;174554:15;;174458:127:::3;::::0;;::::3;::::0;174653:19;;;;::::3;::::0;;;;;;;;::::3;::::0;;;;174318:11;;-1:-1:-1;174344:45:0;174458:127;-1:-1:-1;174614:59:0::3;::::0;174318:11;;174458:127;;174614:11:::3;:59::i;:::-;174695:15;::::0;;;:6:::3;:15;::::0;;;;174688:22;;;;::::3;::::0;;-1:-1:-1;;174688:22:0;;;174725:14:::3;174702:7:::0;174725:5:::3;:14::i;:::-;-1:-1:-1::0;;;174280:3:0::3;;174239:512;;;-1:-1:-1::0;174822:110:0::3;::::0;;;;::::3;::::0;;::::3;::::0;;::::3;::::0;;::::3;::::0;::::3;;::::0;;::::3;::::0;;;;174977:19;;;;::::3;::::0;;;174791:28:::3;174977:19:::0;;;;;::::3;::::0;174822:110;174953:53:::3;::::0;174965:10;;174822:110;174953:11:::3;:53::i;:::-;175048:176;;;;;;;;175084:11;-1:-1:-1::0;;;;;175048:176:0::3;;;;;175204:8;-1:-1:-1::0;;;;;175048:176:0::3;;;;;175119:13;175048:176;;;;;;175166:15;175048:176;;;;::::0;175027:6:::3;:18;175034:10;175027:18;;;;;;;;;;;:197;;;;;;;;;;;;;-1:-1:-1::0;;;;;175027:197:0::3;;;;;-1:-1:-1::0;;;;;175027:197:0::3;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;175027:197:0::3;;;;;-1:-1:-1::0;;;;;175027:197:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;175332:8;;:15;;175297:14;:26;175312:10;-1:-1:-1::0;;;;;175297:26:0::3;-1:-1:-1::0;;;;;175297:26:0::3;;;;;;;;;;;;;;;;;;;;;;:51;175351:1;175297:55;175262:14;:26;175277:10;-1:-1:-1::0;;;;;175262:26:0::3;-1:-1:-1::0;;;;;175262:26:0::3;;;;;;;;;;;;;:91;;;;;;;;;;;;;;;;;;175410:10;175398;-1:-1:-1::0;;;;;175390:59:0::3;;175422:11;175435:13;175390:59;;;;;;-1:-1:-1::0;;;;;16598:47:1;;;;16580:66;;16694:10;16682:23;16677:2;16662:18;;16655:51;16568:2;16553:18;;16408:304;175390:59:0::3;;;;;;;;173060:2397;;;;;;;145604:1:::2;143083:20:::0;142300:1;143603:7;:22;143420:213;169183:1837;143039:21;:19;:21::i;:::-;145574:19:::1;:17;:19::i;:::-;169368:8:::2;156399;156381:15;:26;156377:56;;;156416:17;;-1:-1:-1::0;;;156416:17:0::2;;;;;;;;;;;156377:56;169409:10:::3;169389:16;169397:7:::0;169389::::3;:16::i;:::-;-1:-1:-1::0;;;;;169389:30:0::3;;169385:58;;169428:15;;-1:-1:-1::0;;;169428:15:0::3;;;;;;;;;;;169385:58;169454:16;-1:-1:-1::0;;;;;169454:21:0::3;169474:1;169454:21:::0;169450:49:::3;;169484:15;;-1:-1:-1::0;;;169484:15:0::3;;;;;;;;;;;169450:49;169512:24;169539:15:::0;;;:6:::3;:15;::::0;;;;;;;169512:42;;::::3;::::0;::::3;::::0;;;;-1:-1:-1;;;;;169512:42:0;;::::3;::::0;;;-1:-1:-1;;;169512:42:0;;::::3;;::::0;;::::3;::::0;;;;;;;::::3;::::0;::::3;::::0;;::::3;::::0;;;;;;;-1:-1:-1;;;169512:42:0;::::3;::::0;;::::3;::::0;;;;;169565:16;169561:44:::3;;169590:15;;-1:-1:-1::0;;;169590:15:0::3;;;;;;;;;;;169561:44;169643:4;:12;;;169616:39;;169623:15;169616:39;;;169612:65;;169664:13;;-1:-1:-1::0;;;169664:13:0::3;;;;;;;;;;;169612:65;169710:11:::0;;169690:17:::3;::::0;169710:30:::3;::::0;169724:16;;169710:30:::3;:::i;:::-;169690:50;;169747:16;169766:29;169785:9;169766:18;:29::i;:::-;169747:48;;169808:24;169857:15;169835:4;:12;;;:38;;;;:::i;:::-;169808:65:::0;-1:-1:-1;169880:18:0::3;169928:37;;::::0;::::3;-1:-1:-1::0;;;;;169928:17:0;::::3;:37;:::i;:::-;169909:57;::::0;153030:4:::3;169909:57;:::i;:::-;169880:87:::0;-1:-1:-1;152976:4:0::3;-1:-1:-1::0;;;;;169978:27:0;::::3;;169974:59;;;170014:19;;-1:-1:-1::0;;;170014:19:0::3;;;;;;;;;;;169974:59;170057:13;-1:-1:-1::0;;;;;170044:26:0::3;:10;-1:-1:-1::0;;;;;170044:26:0::3;;170040:57;;;170079:18;;-1:-1:-1::0;;;170079:18:0::3;;;;;;;;;;;170040:57;170158:12;::::0;:37:::3;::::0;-1:-1:-1;;;170158:37:0;;170189:4:::3;170158:37;::::0;::::3;1488:51:1::0;170134:21:0::3;::::0;-1:-1:-1;;;;;170158:12:0::3;::::0;:22:::3;::::0;1461:18:1;;170158:37:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;170202:12;::::0;170134:61;;-1:-1:-1;170202:74:0::3;::::0;-1:-1:-1;;;;;170202:12:0::3;170232:10;170252:4;-1:-1:-1::0;;;;;170202:74:0;::::3;:29;:74::i;:::-;170328:32;-1:-1:-1::0;;;;;170328:32:0;::::3;:13:::0;:32:::3;:::i;:::-;170287:12;::::0;:37:::3;::::0;-1:-1:-1;;;170287:37:0;;170318:4:::3;170287:37;::::0;::::3;1488:51:1::0;-1:-1:-1;;;;;170287:12:0;;::::3;::::0;:22:::3;::::0;1461:18:1;;170287:37:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:73;170283:111;;170378:16;;-1:-1:-1::0;;;170378:16:0::3;;;;;;;;;;;170283:111;170470:11:::0;;170438:71:::3;::::0;170492:10;170438:21:::3;:71::i;:::-;170541:170;170563:7;170581:57;;;;;;;;170610:4;:11;;;170581:57;;;;;;170625:4;:12;;;170581:57;;;;::::0;170649:55:::3;;;;;;;;170678:9;170649:55;;;;;;170691:4;:12;;;170649:55;;;;::::0;170541:11:::3;:170::i;:::-;170768:153;;;;;;;;170800:9;-1:-1:-1::0;;;;;170768:153:0::3;;;;;170905:8;-1:-1:-1::0;;;;;170768:153:0::3;;;;;170829:4;:12;;;170768:153;;;;;;170871:15;170768:153;;;;::::0;170750:6:::3;:15;170757:7;170750:15;;;;;;;;;;;:171;;;;;;;;;;;;;-1:-1:-1::0;;;;;170750:171:0::3;;;;;-1:-1:-1::0;;;;;170750:171:0::3;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;170750:171:0::3;;;;;-1:-1:-1::0;;;;;170750:171:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;170967:7;170955:10;-1:-1:-1::0;;;;;170939:77:0::3;;170976:16;170994:9;171005:10;170939:77;;;;;;;-1:-1:-1::0;;;;;17126:47:1;;;17108:66;;17210:47;;;17205:2;17190:18;;17183:75;17294:47;;;17289:2;17274:18;;17267:75;17096:2;17081:18;;16906:442;170939:77:0::3;;;;;;;;169378:1642;;;;;;145604:1:::2;143083:20:::0;142300:1;143603:7;:22;143420:213;176505:172;149415:13;:11;:13::i;:::-;176566:14:::1;:21:::0;;-1:-1:-1;;;;176566:21:0::1;-1:-1:-1::0;;;176566:21:0::1;::::0;;176598:8:::1;:6;:8::i;:::-;176643:25;::::0;176622:47:::1;::::0;-1:-1:-1;;;;;176643:25:0;;::::1;1488:51:1::0;;176622:47:0::1;::::0;1476:2:1;1461:18;176622:47:0::1;;;;;;;;176505:172::o:0;178554:495::-;178627:13;178682:1;178653:17;178662:7;178653:8;:17::i;:::-;-1:-1:-1;;;;;178653:31:0;;178649:60;;178693:16;;-1:-1:-1;;;178693:16:0;;;;;;;;;;;178649:60;178720:8;;-1:-1:-1;;;;;178720:8:0;178716:52;;178751:17;;-1:-1:-1;;;178751:17:0;;;;;;;;;;;178716:52;178861:8;;178891:53;;;;;7689:25:1;;;178826:12:0;;;;-1:-1:-1;;;;;178861:8:0;;;;7662:18:1;;178891:53:0;;;-1:-1:-1;;178891:53:0;;;;;;;;;;;;;;-1:-1:-1;;;;;178891:53:0;-1:-1:-1;;;178891:53:0;;;178861:90;;;178891:53;178861:90;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;178825:126;;;;178966:7;178958:41;;;;-1:-1:-1;;;178958:41:0;;17861:2:1;178958:41:0;;;17843:21:1;17900:2;17880:18;;;17873:30;-1:-1:-1;;;17919:18:1;;;17912:51;17980:18;;178958:41:0;17659:345:1;178958:41:0;179030:4;179019:26;;;;;;;;;;;;:::i;:::-;179012:33;178554:495;-1:-1:-1;;;;178554:495:0:o;179053:322::-;179138:7;179158:13;;;;;:35;;-1:-1:-1;152872:8:0;179175:18;;;;179158:35;179154:65;;;179202:17;;-1:-1:-1;;;179202:17:0;;;;;;;;;;;179154:65;179230:6;-1:-1:-1;;;;;179230:11:0;179240:1;179230:11;179226:39;;179250:15;;-1:-1:-1;;;179250:15:0;;;;;;;;;;;179226:39;179278:13;179294:26;179313:6;179294:18;:26::i;:::-;179278:42;;179334:37;179355:5;179362:8;179334:20;:37::i;175465:490::-;175546:7;175585:23;;;:14;:23;;;;;;;;175623:14;;;175619:28;;175646:1;175639:8;;;;;175619:28;175660:22;175685:25;;;:16;:25;;;;;;;;:36;;;;;;;;;;;;;175660:61;;;;;;;;;;;;;;;-1:-1:-1;;;175660:61:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;175660:61:0;;;;;;;;;;175783:24;;:9;:24;:::i;:::-;175775:33;;175750:9;:15;;;:59;;;;:::i;:::-;175732:77;;:9;;:77;;;;;:::i;:::-;;;;;;;;175824:14;;175841:1;175824:18;;;175820:69;;-1:-1:-1;175820:69:0;;175876:1;175859:18;;175820:69;175930:14;-1:-1:-1;;;;;175914:32:0;;175465:490;-1:-1:-1;;;;175465:490:0:o;175963:506::-;176142:15;;176047:7;;;;176142:15;-1:-1:-1;;;176142:15:0;;;;;176127:30;;;;:78;;176193:12;176127:78;;;176175:15;;176160:30;;-1:-1:-1;;;176175:15:0;;;;176160:12;:30;:::i;:::-;176106:99;-1:-1:-1;176269:17:0;152872:8;176309:32;153030:4;152976;176309:32;:::i;:::-;-1:-1:-1;;;;;176290:52:0;176298:6;-1:-1:-1;;;;;176290:15:0;:52;;;;:::i;:::-;176289:64;;;;:::i;:::-;176269:84;-1:-1:-1;176269:84:0;176435:28;;;;-1:-1:-1;;;;;176435:14:0;;:28;:::i;:::-;176416:48;;153030:4;176416:48;:::i;165722:1791::-;165932:15;143039:21;:19;:21::i;:::-;145574:19:::1;:17;:19::i;:::-;165913:8:::2;156399;156381:15;:26;156377:56;;;156416:17;;-1:-1:-1::0;;;156416:17:0::2;;;;;;;;;;;156377:56;165964:6:::3;-1:-1:-1::0;;;;;165964:11:0::3;165974:1;165964:11:::0;165960:39:::3;;165984:15;;-1:-1:-1::0;;;165984:15:0::3;;;;;;;;;;;165960:39;166014:17;::::0;::::3;::::0;;:43:::3;;-1:-1:-1::0;152872:8:0::3;166035:22;::::0;::::3;;166014:43;166010:73;;;166066:17;;-1:-1:-1::0;;;166066:17:0::3;;;;;;;;;;;166010:73;166113:10;166098:26;::::0;;;:14:::3;:26;::::0;;;;;153133:3:::3;166098:48;:26:::0;;::::3;:48;166094:78;;166155:17;;-1:-1:-1::0;;;166155:17:0::3;;;;;;;;;;;166094:78;166193:17;166213:38;166239:12:::0;166220:15:::3;166213:38;:::i;:::-;166193:58;;166273:13;166288:18;166310:61;166335:6;166343:12;166357:13;166310:24;:61::i;:::-;166272:99;;;;166428:28;166459:102;;;;;;;;166511:6;166459:102;;;;;;166539:10;166459:102;;;;::::0;166428:133:::3;;166628:44;166640:1;166643:19;;;;;;;;166657:1;166643:19;;;;;;166660:1;166643:19;;;;::::0;166664:7:::3;166628:11;:44::i;:::-;166761:12;::::0;:37:::3;::::0;-1:-1:-1;;;166761:37:0;;166792:4:::3;166761:37;::::0;::::3;1488:51:1::0;166737:21:0::3;::::0;-1:-1:-1;;;;;166761:12:0::3;::::0;:22:::3;::::0;1461:18:1;;166761:37:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;166809:12;::::0;166737:61;;-1:-1:-1;166809:64:0::3;::::0;-1:-1:-1;;;;;166809:12:0::3;166839:10;166859:4;-1:-1:-1::0;;;;;166809:64:0;::::3;:29;:64::i;:::-;166929:22;-1:-1:-1::0;;;;;166929:22:0;::::3;:13:::0;:22:::3;:::i;:::-;166888:12;::::0;:37:::3;::::0;-1:-1:-1;;;166888:37:0;;166919:4:::3;166888:37;::::0;::::3;1488:51:1::0;-1:-1:-1;;;;;166888:12:0;;::::3;::::0;:22:::3;::::0;1461:18:1;;166888:37:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:63;166884:106;;166974:16;;-1:-1:-1::0;;;166974:16:0::3;;;;;;;;;;;166884:106;167046:12;:14:::0;;::::3;;-1:-1:-1::0;;;167046:14:0;;::::3;::::0;::::3;::::0;;::::3;::::0;;::::3;;-1:-1:-1::0;;;;167046:14:0;;::::3;::::0;;;::::3;::::0;;;167090:10:::3;-1:-1:-1::0;167075:26:0;;;:14:::3;:26;::::0;;;;:28;;::::3;::::0;;::::3;::::0;;::::3;::::0;;::::3;-1:-1:-1::0;;167075:28:0;;::::3;::::0;;;::::3;::::0;;;167046:14;-1:-1:-1;167135:30:0::3;::::0;167046:14;167135:9:::3;:30::i;:::-;167204:165;::::0;;::::3;::::0;::::3;::::0;;-1:-1:-1;;;;;167204:165:0;;::::3;::::0;;;;::::3;;::::0;;::::3;::::0;;;::::3;::::0;;::::3;::::0;;;;;;167314:15:::3;167204:165:::0;::::3;::::0;;;;;;-1:-1:-1;167186:15:0;;;:6:::3;:15:::0;;;;;;;:183;;;;;::::3;-1:-1:-1::0;;;167186:183:0::3;::::0;;;::::3;::::0;;;::::3;::::0;;;;;;::::3;::::0;;;;;::::3;-1:-1:-1::0;;;167186:183:0::3;-1:-1:-1::0;;167186:183:0;;;;;;::::3;::::0;;;;;;;::::3;::::0;;167390:41:::3;167240:6:::0;167420:10;167390:21:::3;:41::i;:::-;167457:48;::::0;;-1:-1:-1;;;;;16598:47:1;;16580:66;;16694:10;16682:23;;16677:2;16662:18;;16655:51;167477:7:0;;167465:10:::3;::::0;167457:48:::3;::::0;16553:18:1;167457:48:0::3;;;;;;;165949:1564;;;;;145604:1:::2;143083:20:::0;142300:1;143603:7;:22;143420:213;104341;-1:-1:-1;;;;;104509:27:0;;;104429:4;104509:27;;;:20;:27;;;;;;;;:37;;;;;;;;;;;;;;;104341:213::o;150522:220::-;149415:13;:11;:13::i;:::-;-1:-1:-1;;;;;150607:22:0;::::1;150603:93;;150653:31;::::0;-1:-1:-1;;;150653:31:0;;150681:1:::1;150653:31;::::0;::::1;1488:51:1::0;1461:18;;150653:31:0::1;1342:203:1::0;150603:93:0::1;150706:28;150725:8;150706:18;:28::i;177278:68::-:0;149415:13;:11;:13::i;:::-;177328:10:::1;:8;:10::i;117355:247::-:0;117418:7;117438:13;117454:17;117463:7;117454:8;:17::i;:::-;117438:33;-1:-1:-1;;;;;;117486:19:0;;117482:90;;117529:31;;-1:-1:-1;;;117529:31:0;;;;;7689:25:1;;;7662:18;;117529:31:0;7543:177:1;106542:187:0;106612:7;106695:26;;;:17;:26;;;;;;-1:-1:-1;;;;;106695:26:0;;106542:187::o;115471:122::-;115552:33;115561:2;115565:7;115574:4;115580;115552:8;:33::i;106246:175::-;106312:7;106395:18;;;:9;:18;;;;;;-1:-1:-1;;;;;106395:18:0;;106246:175::o;143119:293::-;142344:1;143253:7;;:19;143245:63;;;;-1:-1:-1;;;143245:63:0;;19403:2:1;143245:63:0;;;19385:21:1;19442:2;19422:18;;;19415:30;19481:33;19461:18;;;19454:61;19532:18;;143245:63:0;19201:355:1;143245:63:0;142344:1;143386:7;:18;143119:293::o;146128:108::-;146040:7;;;;146198:9;146190:38;;;;-1:-1:-1;;;146190:38:0;;19763:2:1;146190:38:0;;;19745:21:1;19802:2;19782:18;;;19775:30;-1:-1:-1;;;19821:18:1;;;19814:46;19877:18;;146190:38:0;19561:340:1;172046:275:0;172112:7;-1:-1:-1;;;;;172148:15:0;;172112:7;172194:15;152872:8;172148:15;172194;:::i;:::-;172174:35;-1:-1:-1;;;;;;172224:29:0;;172220:57;;;172262:15;;-1:-1:-1;;;172262:15:0;;;;;;;;;;;172329:576;172414:7;;172487:25;;;;-1:-1:-1;;;;;172487:14:0;;:25;:::i;:::-;172472:40;-1:-1:-1;172581:18:0;172682:24;152872:8;-1:-1:-1;;;;;172682:14:0;;:24;:::i;:::-;172644:32;153030:4;152976;172644:32;:::i;:::-;172636:41;;-1:-1:-1;;;;;172636:41:0;:4;:41;:::i;:::-;172635:72;;;;:::i;:::-;172602:106;;153030:4;172602:106;:::i;:::-;172581:127;-1:-1:-1;152976:4:0;172733:27;;172729:54;;;152976:4;172762:21;;;;;;172729:54;153030:4;172798:28;;172794:56;;;153030:4;172828:22;;;;;;165487:227;165574:22;153078:4;165599:37;-1:-1:-1;;;;;165617:19:0;;;;165599:15;;:37;:::i;:::-;:49;;;;:::i;:::-;165659:20;:47;;165574:74;;-1:-1:-1;165574:74:0;;165659:20;;:47;;165574:74;;-1:-1:-1;;;;;165659:47:0;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;165659:47:0;;;;;-1:-1:-1;;;;;165659:47:0;;;;;;165563:151;165487:227;;:::o;157496:363::-;157652:19;:17;:19::i;:::-;157696:12;;157692:160;;157725:115;157760:7;157787:9;157816;157725:16;:115::i;143420:213::-;142300:1;143603:7;:22;143420:213::o;101252:151::-;22574:20;:18;:20::i;:::-;101356:39:::1;101380:5;101387:7;101356:23;:39::i;142386:113::-:0;22574:20;:18;:20::i;:::-;142457:34:::1;:32;:34::i;145139:99::-:0;22574:20;:18;:20::i;:::-;145203:27:::1;:25;:27::i;148913:129::-:0;22574:20;:18;:20::i;:::-;148996:38:::1;149021:12;148996:24;:38::i;146565:118::-:0;145574:19;:17;:19::i;:::-;146625:7:::1;:14:::0;;-1:-1:-1;;146625:14:0::1;146635:4;146625:14;::::0;;146655:20:::1;146662:12;25439:10:::0;;25359:98;146662:12:::1;146655:20;::::0;-1:-1:-1;;;;;1506:32:1;;;1488:51;;1476:2;1461:18;146655:20:0::1;1342:203:1::0;162099:259:0;-1:-1:-1;;;;;162209:18:0;;;;;;:57;;-1:-1:-1;162239:12:0;;-1:-1:-1;;;;;162239:12:0;162231:35;;162209:57;162205:136;;;162302:12;;:27;;-1:-1:-1;;;162302:27:0;;;;;7689:25:1;;;-1:-1:-1;;;;;162302:12:0;;;;:18;;7662::1;;162302:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;104621:588::-;-1:-1:-1;;;;;104716:16:0;;104712:89;;104756:33;;-1:-1:-1;;;104756:33:0;;104786:1;104756:33;;;1488:51:1;1461:18;;104756:33:0;1342:203:1;104712:89:0;105022:21;105046:34;105054:2;105058:7;25439:10;105046:7;:34::i;:::-;105022:58;;105112:4;-1:-1:-1;;;;;105095:21:0;:13;-1:-1:-1;;;;;105095:21:0;;105091:111;;105140:50;;-1:-1:-1;;;105140:50:0;;-1:-1:-1;;;;;20126:32:1;;;105140:50:0;;;20108:51:1;20175:18;;;20168:34;;;20238:32;;20218:18;;;20211:60;20081:18;;105140:50:0;19906:371:1;112417:232:0;112469:21;112493:40;112509:1;112513:7;112530:1;112493:7;:40::i;:::-;112469:64;-1:-1:-1;;;;;;112548:27:0;;112544:98;;112599:31;;-1:-1:-1;;;112599:31:0;;;;;7689:25:1;;;7662:18;;112599:31:0;7543:177:1;134407:188:0;134528:58;;-1:-1:-1;;;;;20474:32:1;;134528:58:0;;;20456:51:1;20523:18;;;20516:34;;;134501:86:0;;134521:5;;-1:-1:-1;;;134551:23:0;20429:18:1;;134528:58:0;;;;-1:-1:-1;;134528:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;134528:58:0;-1:-1:-1;;;;;;134528:58:0;;;;;;;;;;134501:19;:86::i;149754:166::-;25439:10;149814:7;148360:22;149660:8;-1:-1:-1;;;;;149660:8:0;;149529:147;149814:7;-1:-1:-1;;;;;149814:23:0;;149810:103;;149861:40;;-1:-1:-1;;;149861:40:0;;25439:10;149861:40;;;1488:51:1;1461:18;;149861:40:0;1342:203:1;150902:253:0;148360:22;151053:8;;-1:-1:-1;;;;;;151072:19:0;;-1:-1:-1;;;;;151072:19:0;;;;;;;;151107:40;;151053:8;;;;;151107:40;;150976:24;;151107:40;150965:190;;150902:253;:::o;171237:801::-;171309:7;171329:22;171354:5;171329:30;;171370:9;152918;;171383;:12;;;:19;;;;:::i;:::-;171382:28;;;;:::i;:::-;171370:40;-1:-1:-1;171436:9:0;171431:460;171455:3;171451:1;:7;171431:460;;;171480:10;152918:9;171480:10;;:::i;:::-;;-1:-1:-1;171505:13:0;171541:6;;;;;;;;171537:119;;;171573:1;171568:6;;171537:119;;;-1:-1:-1;171624:16:0;;;;;;;:12;:16;;;;;;;;171537:119;171726:12;;;;171721:17;;:2;:17;:::i;:::-;171713:26;;171688:9;:15;;;:52;;;;:::i;:::-;171670:70;;:9;;:70;;;;;:::i;:::-;;;;;-1:-1:-1;171759:7:0;;;;;;;;171755:53;;171787:5;;;171755:53;171841:6;171822:9;:15;;:25;;;;;;;:::i;:::-;;;;;-1:-1:-1;;171862:17:0;;;:12;;;:17;171460:3;;171431:460;;;;171924:1;171907:9;:14;;;:18;;;171903:69;;;171959:1;171942:18;;171903:69;-1:-1:-1;172013:14:0;-1:-1:-1;;;;;171997:32:0;;171237:801;-1:-1:-1;;;171237:801:0:o;116736:376::-;-1:-1:-1;;;;;;;;;;;;;;;;116900:22:0;;116896:93;;116946:31;;-1:-1:-1;;;116946:31:0;;-1:-1:-1;;;;;1506:32:1;;116946:31:0;;;1488:51:1;1461:18;;116946:31:0;1342:203:1;116896:93:0;-1:-1:-1;;;;;116999:27:0;;;;;;;:20;;;:27;;;;;;;;:37;;;;;;;;;;;;;:48;;-1:-1:-1;;116999:48:0;;;;;;;;;;117063:41;;540::1;;;117063::0;;513:18:1;117063:41:0;;;;;;;116829:283;116736:376;;;:::o;105485:236::-;105599:31;105612:4;105618:2;105622:7;105599:12;:31::i;:::-;105641:72;25439:10;105689:4;105695:2;105699:7;105708:4;105641:33;:72::i;111539:102::-;111607:26;111617:2;111621:7;111607:26;;;;;;;;;;;;:9;:26::i;134840:216::-;134979:68;;-1:-1:-1;;;;;21463:32:1;;;134979:68:0;;;21445:51:1;21532:32;;21512:18;;;21505:60;21581:18;;;21574:34;;;134952:96:0;;134972:5;;-1:-1:-1;;;135002:27:0;21418:18:1;;134979:68:0;21243:371:1;164306:1173:0;164457:13;;;164575:27;153078:4;-1:-1:-1;;;;;164575:15:0;;:27;:::i;:::-;164552:50;-1:-1:-1;164845:22:0;164870:32;153030:4;152976;164870:32;:::i;:::-;-1:-1:-1;;;;;164845:57:0;;-1:-1:-1;164924:17:0;164979:19;153078:4;152872:8;164979:19;:::i;:::-;-1:-1:-1;;;;;164944:55:0;164945:29;164960:14;164945:12;:29;:::i;:::-;164944:55;;;;:::i;:::-;164924:75;-1:-1:-1;;;;;;165014:29:0;;165010:57;;;165052:15;;-1:-1:-1;;;165052:15:0;;;;;;;;;;;165010:57;165094:9;-1:-1:-1;165094:9:0;165182:26;153078:4;165212:29;;;;-1:-1:-1;;;;;165212:14:0;;:29;:::i;:::-;165211:43;;;;:::i;:::-;165182:72;-1:-1:-1;165286:36:0;165182:72;153030:4;165286:36;:::i;:::-;165265:58;-1:-1:-1;152976:4:0;-1:-1:-1;;;;;165348:27:0;;;165344:59;;;165384:19;;-1:-1:-1;;;165384:19:0;;;;;;;;;;;165344:59;165431:13;-1:-1:-1;;;;;165418:26:0;:10;-1:-1:-1;;;;;165418:26:0;;165414:57;;;165453:18;;-1:-1:-1;;;165453:18:0;;;;;;;;;;;165414:57;164492:987;;;;164306:1173;;;;;;:::o;146824:120::-;145833:16;:14;:16::i;:::-;146883:7:::1;:15:::0;;-1:-1:-1;;146883:15:0::1;::::0;;146914:22:::1;25439:10:::0;146923:12:::1;25359:98:::0;115781:736;-1:-1:-1;;;;;;;;;;;115999:9:0;;:31;;-1:-1:-1;;;;;;116012:18:0;;;;115999:31;115995:471;;;116047:13;116063:22;116077:7;116063:13;:22::i;:::-;116047:38;-1:-1:-1;;;;;;116216:18:0;;;;;;:35;;;116247:4;-1:-1:-1;;;;;116238:13:0;:5;-1:-1:-1;;;;;116238:13:0;;;116216:35;:69;;;;;116256:29;116273:5;116280:4;116256:16;:29::i;:::-;116255:30;116216:69;116212:144;;;116313:27;;-1:-1:-1;;;116313:27:0;;-1:-1:-1;;;;;1506:32:1;;116313:27:0;;;1488:51:1;1461:18;;116313:27:0;1342:203:1;116212:144:0;116376:9;116372:83;;;116431:7;116427:2;-1:-1:-1;;;;;116411:28:0;116420:5;-1:-1:-1;;;;;116411:28:0;;;;;;;;;;;116372:83;116032:434;115995:471;116478:26;;;;:17;;:26;;-1:-1:-1;;116478:26:0;;;:31;;-1:-1:-1;;;;;;116478:31:0;-1:-1:-1;;;;;116478:31:0;;;;;;;;;;115781:736::o;157867:950::-;157932:5;;;;157948:22;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;157948:22:0;157995:10;;;;157991:289;;158034:12;:24;158047:10;158056:1;158047:6;:10;:::i;:::-;158034:24;;;;;;;;;;;;;;;;;;-1:-1:-1;158034:24:0;158022:36;;;;;;;;;;;;;;;-1:-1:-1;;;158022:36:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;158022:36:0;;;;;;;;;-1:-1:-1;157991:289:0;;;-1:-1:-1;158103:165:0;;;;;;;;-1:-1:-1;158103:165:0;;;;;;;;158192:15;158103:165;;;;;;;;;158239:12;158103:165;;;;;;;157991:289;158316:12;;;;158292:21;158386:40;;;;158393:15;158386:40;;;;158382:198;;;158554:12;;;;158536:30;;;;:15;:30;:::i;:::-;158493:13;;;;158478:28;;;;:12;:28;:::i;:::-;158465:42;;153078:4;158465:42;:::i;:::-;158464:103;;;;:::i;:::-;158443:125;;158382:198;158643:135;158683:9;158707:14;158736:10;158761:6;158643:25;:135::i;:::-;158631:147;-1:-1:-1;158799:10:0;:6;158808:1;158799:10;:::i;:::-;158791:5;:18;;-1:-1:-1;;158791:18:0;;;;;;;;;;;;-1:-1:-1;;;;157867:950:0:o;160109:1160::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;160363:15:0;160340:39;;:9;:13;;;:39;;;:63;;;;;160402:1;160383:9;:16;;;:20;;;160340:63;160336:257;;;160433:16;;:27;;152872:8;;160433:27;:::i;:::-;160420:40;;:10;;;;:40;;;;160540:13;;;:39;;160563:15;;160540:39;:::i;:::-;160532:48;;160487:4;:10;;;:94;;;;:::i;:::-;160475:106;;;;160336:257;160640:15;160617:39;;:9;:13;;;:39;;;:63;;;;;160679:1;160660:9;:16;;;:20;;;160617:63;160613:257;;;160710:16;;:27;;152872:8;;160710:27;:::i;:::-;160697:40;;:10;;;;:40;;;;160817:13;;;:39;;160840:15;;160817:39;:::i;:::-;160809:48;;160764:4;:10;;;:94;;;;:::i;:::-;160752:106;;;;160613:257;160882:134;160922:9;160946;160970:4;:10;;;160995:4;:10;;;160882:25;:134::i;:::-;161029:16;161048:23;;;:14;:23;;;;;;:27;;:23;;;:27;:::i;:::-;161086:23;;;;:14;:23;;;;;;;;:35;;;;;;-1:-1:-1;;161086:35:0;;;;;;;;161149:15;161132:33;;:7;;;:33;;;161194:12;161176:31;;:8;;;:31;;;161218:25;;;:16;:25;;;;;:36;;;;;;;;:43;;;;;;;-1:-1:-1;;;;;161218:43:0;;;-1:-1:-1;;;161218:43:0;;;;;;;;;;161086:35;161218:43;;;;;;;;;;-1:-1:-1;;;161218:43:0;-1:-1:-1;;161218:43:0;;;;;;;;;;;;;;;;;-1:-1:-1;;;;160109:1160:0:o;22734:145::-;24567:21;24248:40;-1:-1:-1;;;24248:40:0;;;;22797:75;;22843:17;;-1:-1:-1;;;22843:17:0;;;;;;;;;;;101411:223;22574:20;:18;:20::i;:::-;-1:-1:-1;;;;;;;;;;;101089:21:0;101581:15:::1;101591:5:::0;101089:21;101581:15:::1;:::i;:::-;-1:-1:-1::0;101607:9:0::1;::::0;::::1;:19;101619:7:::0;101607:9;:19:::1;:::i;142507:111::-:0;22574:20;:18;:20::i;145246:97::-;22574:20;:18;:20::i;:::-;145320:7:::1;:15:::0;;-1:-1:-1;;145320:15:0::1;::::0;;145246:97::o;149050:240::-;22574:20;:18;:20::i;109619:886::-;109705:7;-1:-1:-1;;;;;;;;;;;109705:7:0;109796:17;109805:7;109796:8;:17::i;:::-;109781:32;-1:-1:-1;;;;;;109876:18:0;;;109872:88;;109911:37;109928:4;109934;109940:7;109911:16;:37::i;:::-;-1:-1:-1;;;;;110007:18:0;;;110003:265;;110125:48;110142:1;110146:7;110163:1;110167:5;110125:8;:48::i;:::-;-1:-1:-1;;;;;110219:17:0;;;;;;:11;;;:17;;;;;:22;;-1:-1:-1;;110219:22:0;;;110003:265;-1:-1:-1;;;;;110284:16:0;;;110280:113;;-1:-1:-1;;;;;110346:15:0;;;;;;:11;;;:15;;;;;:20;;110365:1;110346:20;;;110280:113;110405:18;;;;:9;;;:18;;;;;;:23;;-1:-1:-1;;;;;;110405:23:0;-1:-1:-1;;;;;110405:23:0;;;;;;;;;110446:27;;110405:18;;110446:27;;;;;;;110493:4;109619:886;-1:-1:-1;;;;;109619:886:0:o;138830:660::-;139265:23;139291:69;139319:4;139291:69;;;;;;;;;;;;;;;;;139299:5;-1:-1:-1;;;;;139291:27:0;;;:69;;;;;:::i;:::-;139265:95;;139379:10;:17;139400:1;139379:22;:56;;;;139416:10;139405:30;;;;;;;;;;;;:::i;:::-;139371:111;;;;-1:-1:-1;;;139371:111:0;;24505:2:1;139371:111:0;;;24487:21:1;24544:2;24524:18;;;24517:30;24583:34;24563:18;;;24556:62;-1:-1:-1;;;24634:18:1;;;24627:40;24684:19;;139371:111:0;24303:406:1;14630:948:0;-1:-1:-1;;;;;14817:14:0;;;:18;14813:758;;14856:67;;-1:-1:-1;;;14856:67:0;;-1:-1:-1;;;;;14856:36:0;;;;;:67;;14893:8;;14903:4;;14909:7;;14918:4;;14856:67;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14856:67:0;;;;;;;;-1:-1:-1;;14856:67:0;;;;;;;;;;;;:::i;:::-;;;14852:708;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15219:6;:13;15236:1;15219:18;15215:330;;15325:39;;-1:-1:-1;;;15325:39:0;;-1:-1:-1;;;;;1506:32:1;;15325:39:0;;;1488:51:1;1461:18;;15325:39:0;1342:203:1;15215:330:0;15495:6;15489:13;15480:6;15476:2;15472:15;15465:38;14852:708;-1:-1:-1;;;;;;14971:51:0;;-1:-1:-1;;;14971:51:0;14967:185;;15093:39;;-1:-1:-1;;;15093:39:0;;-1:-1:-1;;;;;1506:32:1;;15093:39:0;;;1488:51:1;1461:18;;15093:39:0;1342:203:1;14967:185:0;14924:243;14852:708;14630:948;;;;;:::o;111868:210::-;111963:18;111969:2;111973:7;111963:5;:18::i;:::-;111992:78;25439:10;112048:1;112052:2;112056:7;112065:4;111992:33;:78::i;146313:108::-;146040:7;;;;146372:41;;;;-1:-1:-1;;;146372:41:0;;25660:2:1;146372:41:0;;;25642:21:1;25699:2;25679:18;;;25672:30;-1:-1:-1;;;25718:18:1;;;25711:50;25778:18;;146372:41:0;25458:344:1;158825:1276:0;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;159060:9:0;159028:29;152918:9;159093:21;152918:9;159093:14;:21;:::i;:::-;159092:30;;;;:::i;:::-;159080:42;-1:-1:-1;159148:9:0;159143:914;159167:3;159163:1;:7;159143:914;;;159192:10;152918:9;159192:10;;:::i;:::-;;-1:-1:-1;159217:13:0;159267:28;159279:15;159267:28;;;;;;159263:163;;;159328:15;159316:28;;159263:163;;;-1:-1:-1;159394:16:0;;;;;;;:12;:16;;;;;;;;159263:163;159505:19;159510:14;159505:2;:19;:::i;:::-;159497:28;;159472:9;:15;;;:54;;;;:::i;:::-;159454:72;;:9;;:72;;;;;:::i;:::-;;;;;-1:-1:-1;159541:15:0;;;:25;;159560:6;;159541:15;:25;;159560:6;;159541:25;:::i;:::-;;;;;-1:-1:-1;159581:17:0;;;:12;;;;:17;;;;159716:19;;;153078:4;;159711:24;;159596:2;159711:24;:::i;:::-;159688:48;;;;-1:-1:-1;;;;;159688:19:0;;:48;:::i;:::-;159687:62;;;;:::i;:::-;159636:16;:20;;;:113;;;;;;:::i;:::-;159613:137;;;;:13;;;:137;159796:15;159783:29;;;;;;159779:219;;-1:-1:-1;159833:36:0;159856:12;159833:36;:13;;;:36;159888:5;;159779:219;159973:9;159934:12;:36;159967:1;159947:10;:6;159956:1;159947:10;:::i;:::-;:22;;;;:::i;:::-;159934:36;;;;;;;;;;;;;;;;;;-1:-1:-1;159934:36:0;:48;;;;;;-1:-1:-1;;;;;159934:48:0;;;-1:-1:-1;;;159934:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;159934:48:0;-1:-1:-1;;159934:48:0;;;;;;;;;;;;;;;;;-1:-1:-1;160043:2:0;;-1:-1:-1;160043:2:0;;159172:3;;159143:914;;;-1:-1:-1;160084:9:0;;158825:1276;-1:-1:-1;;;;;;158825:1276:0:o;161277:814::-;161500:15;161477:39;;:9;:13;;;:39;;;161473:314;;;161565:13;;;;;161552:27;;161533:16;161552:27;;;:12;:27;;;;;;;;;161594:21;161607:8;161552:27;161594:21;:::i;:::-;;;161651:9;:13;;;161634:30;;:9;:13;;;:30;;;161630:92;;161685:21;161698:8;161685:21;;:::i;:::-;;;161630:92;161749:13;;;;;161736:27;;;;;;:12;:27;;;;;;:39;;-1:-1:-1;;;;;;161736:39:0;-1:-1:-1;;;;;161736:39:0;;;;;;;;;;161473:314;161826:15;161803:39;;:9;:13;;;:39;;;161799:285;;;161879:9;:13;;;161863:29;;:9;:13;;;:29;;;161859:214;;;161945:13;;;;;161932:27;;161913:16;161932:27;;;:12;:27;;;;;;;;;161978:21;161991:8;161932:27;161978:21;:::i;:::-;162031:13;;;;;162018:27;;;;;;:12;:27;;;;;;:39;;-1:-1:-1;;;;;162018:39:0;;;-1:-1:-1;;;;;;162018:39:0;;;;;;;;;-1:-1:-1;161277:814:0;;;;:::o;107768:376::-;107881:38;107895:5;107902:7;107911;107881:13;:38::i;:::-;107876:261;;-1:-1:-1;;;;;107940:19:0;;107936:190;;107987:31;;-1:-1:-1;;;107987:31:0;;;;;7689:25:1;;;7662:18;;107987:31:0;7543:177:1;107936:190:0;108066:44;;-1:-1:-1;;;108066:44:0;;-1:-1:-1;;;;;20474:32:1;;108066:44:0;;;20456:51:1;20523:18;;;20516:34;;;20429:18;;108066:44:0;20282:274:1;128230:229:0;128367:12;128399:52;128421:6;128429:4;128435:1;128438:12;128399:21;:52::i;110841:335::-;-1:-1:-1;;;;;110909:16:0;;110905:89;;110949:33;;-1:-1:-1;;;110949:33:0;;110979:1;110949:33;;;1488:51:1;1461:18;;110949:33:0;1342:203:1;110905:89:0;111004:21;111028:32;111036:2;111040:7;111057:1;111028:7;:32::i;:::-;111004:56;-1:-1:-1;;;;;;111075:27:0;;;111071:98;;111126:31;;-1:-1:-1;;;111126:31:0;;111154:1;111126:31;;;1488:51:1;1461:18;;111126:31:0;1342:203:1;107049:276:0;107152:4;-1:-1:-1;;;;;107189:21:0;;;;;;:128;;;107237:7;-1:-1:-1;;;;;107228:16:0;:5;-1:-1:-1;;;;;107228:16:0;;:52;;;;107248:32;107265:5;107272:7;107248:16;:32::i;:::-;107228:88;;;;107309:7;-1:-1:-1;;;;;107284:32:0;:21;107297:7;107284:12;:21::i;:::-;-1:-1:-1;;;;;107284:32:0;;;107049:276;-1:-1:-1;;;;107049:276:0:o;129316:455::-;129486:12;129544:5;129519:21;:30;;129511:81;;;;-1:-1:-1;;;129511:81:0;;26009:2:1;129511:81:0;;;25991:21:1;26048:2;26028:18;;;26021:30;26087:34;26067:18;;;26060:62;-1:-1:-1;;;26138:18:1;;;26131:36;26184:19;;129511:81:0;25807:402:1;129511:81:0;129604:12;129618:23;129645:6;-1:-1:-1;;;;;129645:11:0;129664:5;129671:4;129645:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;129603:73;;;;129694:69;129721:6;129729:7;129738:10;129750:12;132074;132103:7;132099:427;;;132131:10;:17;132152:1;132131:22;132127:290;;-1:-1:-1;;;;;125770:19:0;;;132341:60;;;;-1:-1:-1;;;132341:60:0;;26416:2:1;132341:60:0;;;26398:21:1;26455:2;26435:18;;;26428:30;26494:31;26474:18;;;26467:59;26543:18;;132341:60:0;26214:353:1;132341:60:0;-1:-1:-1;132438:10:0;132431:17;;132099:427;132481:33;132489:10;132501:12;133236:17;;:21;133232:388;;133468:10;133462:17;133525:15;133512:10;133508:2;133504:19;133497:44;133232:388;133595:12;133588:20;;-1:-1:-1;;;133588:20:0;;;;;;;;:::i;14:131:1:-;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:289::-;634:3;672:5;666:12;699:6;694:3;687:19;755:6;748:4;741:5;737:16;730:4;725:3;721:14;715:47;807:1;800:4;791:6;786:3;782:16;778:27;771:38;870:4;863:2;859:7;854:2;846:6;842:15;838:29;833:3;829:39;825:50;818:57;;;592:289;;;;:::o;886:220::-;1035:2;1024:9;1017:21;998:4;1055:45;1096:2;1085:9;1081:18;1073:6;1055:45;:::i;1111:226::-;1170:6;1223:2;1211:9;1202:7;1198:23;1194:32;1191:52;;;1239:1;1236;1229:12;1191:52;-1:-1:-1;1284:23:1;;1111:226;-1:-1:-1;1111:226:1:o;1550:173::-;1618:20;;-1:-1:-1;;;;;1667:31:1;;1657:42;;1647:70;;1713:1;1710;1703:12;1647:70;1550:173;;;:::o;1728:300::-;1796:6;1804;1857:2;1845:9;1836:7;1832:23;1828:32;1825:52;;;1873:1;1870;1863:12;1825:52;1896:29;1915:9;1896:29;:::i;:::-;1886:39;1994:2;1979:18;;;;1966:32;;-1:-1:-1;;;1728:300:1:o;2267:186::-;2326:6;2379:2;2367:9;2358:7;2354:23;2350:32;2347:52;;;2395:1;2392;2385:12;2347:52;2418:29;2437:9;2418:29;:::i;2458:611::-;2648:2;2660:21;;;2730:13;;2633:18;;;2752:22;;;2600:4;;2831:15;;;2805:2;2790:18;;;2600:4;2874:169;2888:6;2885:1;2882:13;2874:169;;;2949:13;;2937:26;;2992:2;3018:15;;;;2983:12;;;;2910:1;2903:9;2874:169;;;-1:-1:-1;3060:3:1;;2458:611;-1:-1:-1;;;;;2458:611:1:o;3074:163::-;3141:20;;3201:10;3190:22;;3180:33;;3170:61;;3227:1;3224;3217:12;3242:298;3309:6;3317;3370:2;3358:9;3349:7;3345:23;3341:32;3338:52;;;3386:1;3383;3376:12;3338:52;3431:23;;;-1:-1:-1;3497:37:1;3530:2;3515:18;;3497:37;:::i;:::-;3487:47;;3242:298;;;;;:::o;3999:188::-;4067:20;;-1:-1:-1;;;;;4116:46:1;;4106:57;;4096:85;;4177:1;4174;4167:12;4192:493;4277:6;4285;4293;4301;4354:3;4342:9;4333:7;4329:23;4325:33;4322:53;;;4371:1;4368;4361:12;4322:53;4416:23;;;-1:-1:-1;4482:37:1;4515:2;4500:18;;4482:37;:::i;:::-;4472:47;-1:-1:-1;4592:2:1;4577:18;;4564:32;;-1:-1:-1;4641:38:1;4675:2;4660:18;;4641:38;:::i;:::-;4631:48;;4192:493;;;;;;;:::o;4690:127::-;4751:10;4746:3;4742:20;4739:1;4732:31;4782:4;4779:1;4772:15;4806:4;4803:1;4796:15;4822:275;4893:2;4887:9;4958:2;4939:13;;-1:-1:-1;;4935:27:1;4923:40;;4993:18;4978:34;;5014:22;;;4975:62;4972:88;;;5040:18;;:::i;:::-;5076:2;5069:22;4822:275;;-1:-1:-1;4822:275:1:o;5102:187::-;5151:4;5184:18;5176:6;5173:30;5170:56;;;5206:18;;:::i;:::-;-1:-1:-1;5272:2:1;5251:15;-1:-1:-1;;5247:29:1;5278:4;5243:40;;5102:187::o;5294:338::-;5359:5;5388:53;5404:36;5433:6;5404:36;:::i;:::-;5388:53;:::i;:::-;5379:62;;5464:6;5457:5;5450:21;5504:3;5495:6;5490:3;5486:16;5483:25;5480:45;;;5521:1;5518;5511:12;5480:45;5570:6;5565:3;5558:4;5551:5;5547:16;5534:43;5624:1;5617:4;5608:6;5601:5;5597:18;5593:29;5586:40;5294:338;;;;;:::o;5637:222::-;5680:5;5733:3;5726:4;5718:6;5714:17;5710:27;5700:55;;5751:1;5748;5741:12;5700:55;5773:80;5849:3;5840:6;5827:20;5820:4;5812:6;5808:17;5773:80;:::i;5864:687::-;5970:6;5978;5986;5994;6047:3;6035:9;6026:7;6022:23;6018:33;6015:53;;;6064:1;6061;6054:12;6015:53;6087:29;6106:9;6087:29;:::i;:::-;6077:39;;6135:38;6169:2;6158:9;6154:18;6135:38;:::i;:::-;6125:48;;6224:2;6213:9;6209:18;6196:32;6251:18;6243:6;6240:30;6237:50;;;6283:1;6280;6273:12;6237:50;6306;6348:7;6339:6;6328:9;6324:22;6306:50;:::i;:::-;6296:60;;;6409:2;6398:9;6394:18;6381:32;6438:18;6428:8;6425:32;6422:52;;;6470:1;6467;6460:12;6422:52;6493;6537:7;6526:8;6515:9;6511:24;6493:52;:::i;:::-;6483:62;;;5864:687;;;;;;;:::o;6556:374::-;6633:6;6641;6649;6702:2;6690:9;6681:7;6677:23;6673:32;6670:52;;;6718:1;6715;6708:12;6670:52;6741:29;6760:9;6741:29;:::i;:::-;6731:39;;6789:38;6823:2;6812:9;6808:18;6789:38;:::i;:::-;6556:374;;6779:48;;-1:-1:-1;;;6896:2:1;6881:18;;;;6868:32;;6556:374::o;7158:184::-;7216:6;7269:2;7257:9;7248:7;7244:23;7240:32;7237:52;;;7285:1;7282;7275:12;7237:52;7308:28;7326:9;7308:28;:::i;7725:346::-;7793:6;7801;7854:2;7842:9;7833:7;7829:23;7825:32;7822:52;;;7870:1;7867;7860:12;7822:52;-1:-1:-1;;7915:23:1;;;8035:2;8020:18;;;8007:32;;-1:-1:-1;7725:346:1:o;8970:118::-;9056:5;9049:13;9042:21;9035:5;9032:32;9022:60;;9078:1;9075;9068:12;9093:315;9158:6;9166;9219:2;9207:9;9198:7;9194:23;9190:32;9187:52;;;9235:1;9232;9225:12;9187:52;9258:29;9277:9;9258:29;:::i;:::-;9248:39;;9337:2;9326:9;9322:18;9309:32;9350:28;9372:5;9350:28;:::i;:::-;9397:5;9387:15;;;9093:315;;;;;:::o;9413:713::-;9508:6;9516;9524;9532;9585:3;9573:9;9564:7;9560:23;9556:33;9553:53;;;9602:1;9599;9592:12;9553:53;9625:29;9644:9;9625:29;:::i;:::-;9615:39;;9673:38;9707:2;9696:9;9692:18;9673:38;:::i;:::-;9663:48;-1:-1:-1;9780:2:1;9765:18;;9752:32;;-1:-1:-1;9859:2:1;9844:18;;9831:32;9886:18;9875:30;;9872:50;;;9918:1;9915;9908:12;9872:50;9941:22;;9994:4;9986:13;;9982:27;-1:-1:-1;9972:55:1;;10023:1;10020;10013:12;9972:55;10046:74;10112:7;10107:2;10094:16;10089:2;10085;10081:11;10046:74;:::i;10131:730::-;10226:6;10234;10242;10295:2;10283:9;10274:7;10270:23;10266:32;10263:52;;;10311:1;10308;10301:12;10263:52;10351:9;10338:23;10384:18;10376:6;10373:30;10370:50;;;10416:1;10413;10406:12;10370:50;10439:22;;10492:4;10484:13;;10480:27;-1:-1:-1;10470:55:1;;10521:1;10518;10511:12;10470:55;10561:2;10548:16;10587:18;10579:6;10576:30;10573:50;;;10619:1;10616;10609:12;10573:50;10674:7;10667:4;10657:6;10654:1;10650:14;10646:2;10642:23;10638:34;10635:47;10632:67;;;10695:1;10692;10685:12;10632:67;10726:4;10718:13;;;;10750:6;;-1:-1:-1;10810:20:1;;10797:34;;10131:730;-1:-1:-1;;;10131:730:1:o;10866:495::-;10952:6;10960;10968;10976;11029:3;11017:9;11008:7;11004:23;11000:33;10997:53;;;11046:1;11043;11036:12;10997:53;11091:23;;;-1:-1:-1;11157:38:1;11191:2;11176:18;;11157:38;:::i;11366:258::-;11433:6;11441;11494:2;11482:9;11473:7;11469:23;11465:32;11462:52;;;11510:1;11507;11500:12;11462:52;11533:29;11552:9;11533:29;:::i;:::-;11523:39;;11581:37;11614:2;11603:9;11599:18;11581:37;:::i;11629:447::-;11714:6;11722;11730;11738;11791:3;11779:9;11770:7;11766:23;11762:33;11759:53;;;11808:1;11805;11798:12;11759:53;11831:29;11850:9;11831:29;:::i;:::-;11821:39;;11879:37;11912:2;11901:9;11897:18;11879:37;:::i;12081:260::-;12149:6;12157;12210:2;12198:9;12189:7;12185:23;12181:32;12178:52;;;12226:1;12223;12216:12;12178:52;12249:29;12268:9;12249:29;:::i;:::-;12239:39;;12297:38;12331:2;12320:9;12316:18;12297:38;:::i;12346:380::-;12425:1;12421:12;;;;12468;;;12489:61;;12543:4;12535:6;12531:17;12521:27;;12489:61;12596:2;12588:6;12585:14;12565:18;12562:38;12559:161;;12642:10;12637:3;12633:20;12630:1;12623:31;12677:4;12674:1;12667:15;12705:4;12702:1;12695:15;12559:161;;12346:380;;;:::o;12731:127::-;12792:10;12787:3;12783:20;12780:1;12773:31;12823:4;12820:1;12813:15;12847:4;12844:1;12837:15;12863:127;12924:10;12919:3;12915:20;12912:1;12905:31;12955:4;12952:1;12945:15;12979:4;12976:1;12969:15;12995:135;13034:3;13055:17;;;13052:43;;13075:18;;:::i;:::-;-1:-1:-1;13122:1:1;13111:13;;12995:135::o;13135:167::-;13230:10;13203:18;;;13223;;;13199:43;;13254:19;;13251:45;;;13276:18;;:::i;13307:170::-;13404:10;13397:18;;;13377;;;13373:43;;13428:20;;13425:46;;;13451:18;;:::i;14005:168::-;14078:9;;;14109;;14126:15;;;14120:22;;14106:37;14096:71;;14147:18;;:::i;14178:127::-;14239:10;14234:3;14230:20;14227:1;14220:31;14270:4;14267:1;14260:15;14294:4;14291:1;14284:15;14310:120;14350:1;14376;14366:35;;14381:18;;:::i;:::-;-1:-1:-1;14415:9:1;;14310:120::o;14435:243::-;-1:-1:-1;;;;;14550:42:1;;;14506;;;14502:91;;14605:44;;14602:70;;;14652:18;;:::i;15385:128::-;15452:9;;;15473:11;;;15470:37;;;15487:18;;:::i;15518:125::-;15583:9;;;15604:10;;;15601:36;;;15617:18;;:::i;15648:317::-;-1:-1:-1;;;;;15733:42:1;;;15777;;;15729:91;15840:52;;;;15911:24;;;15901:58;;15939:18;;:::i;:::-;15901:58;15648:317;;;;:::o;15970:240::-;-1:-1:-1;;;;;16039:42:1;;;16083;;;16035:91;;16138:43;;16135:69;;;16184:18;;:::i;16215:188::-;16253:3;16297:10;16290:5;16286:22;16332:10;16323:7;16320:23;16317:49;;16346:18;;:::i;:::-;16395:1;16382:15;;16215:188;-1:-1:-1;;16215:188:1:o;16717:184::-;16787:6;16840:2;16828:9;16819:7;16815:23;16811:32;16808:52;;;16856:1;16853;16846:12;16808:52;-1:-1:-1;16879:16:1;;16717:184;-1:-1:-1;16717:184:1:o;17353:301::-;17482:3;17520:6;17514:13;17566:6;17559:4;17551:6;17547:17;17542:3;17536:37;17628:1;17592:16;;17617:13;;;-1:-1:-1;17592:16:1;17353:301;-1:-1:-1;17353:301:1:o;18009:687::-;18089:6;18142:2;18130:9;18121:7;18117:23;18113:32;18110:52;;;18158:1;18155;18148:12;18110:52;18191:9;18185:16;18224:18;18216:6;18213:30;18210:50;;;18256:1;18253;18246:12;18210:50;18279:22;;18332:4;18324:13;;18320:27;-1:-1:-1;18310:55:1;;18361:1;18358;18351:12;18310:55;18394:2;18388:9;18419:53;18435:36;18464:6;18435:36;:::i;18419:53::-;18495:6;18488:5;18481:21;18543:7;18538:2;18529:6;18525:2;18521:15;18517:24;18514:37;18511:57;;;18564:1;18561;18554:12;18511:57;18612:6;18607:2;18603;18599:11;18594:2;18587:5;18583:14;18577:42;18664:1;18639:18;;;18659:2;18635:27;18628:38;;;;18643:5;18009:687;-1:-1:-1;;;;18009:687:1:o;18701:241::-;18740:7;18819:1;18815:2;18804:17;18800:1;18796:2;18785:17;18781:41;18857:11;18853:2;18842:27;18831:38;;18900:11;18891:7;18888:24;18878:58;;18916:18;;:::i;18947:249::-;19047:2;19036:17;;;19017;;;;19013:41;-1:-1:-1;;;;;;19069:50:1;;-1:-1:-1;;;;;19121:45:1;;19066:101;19063:127;;;19170:18;;:::i;20561:178::-;20600:1;20634:10;20631:1;20627:18;20664:3;20654:37;;20671:18;;:::i;:::-;20729:3;20716:10;20713:1;20709:18;20705:28;20700:33;;;20561:178;;;;:::o;20744:244::-;20855:10;20828:18;;;20848;;;20824:43;20887:28;;;;20934:24;;;20924:58;;20962:18;;:::i;20993:245::-;21091:2;21061:17;;;21080;;;;21057:41;-1:-1:-1;;;;;21113:44:1;;-1:-1:-1;;;;;;21159:49:1;;21110:99;21107:125;;;21212:18;;:::i;21619:305::-;21658:1;21700;21696:2;21685:17;21737:1;21733:2;21722:17;21758:3;21748:37;;21765:18;;:::i;:::-;-1:-1:-1;;;;;;21801:48:1;;-1:-1:-1;;21851:15:1;;21797:70;21794:96;;;21870:18;;:::i;:::-;21904:14;;;21619:305;-1:-1:-1;;;21619:305:1:o;22055:518::-;22157:2;22152:3;22149:11;22146:421;;;22193:5;22190:1;22183:16;22237:4;22234:1;22224:18;22307:2;22295:10;22291:19;22288:1;22284:27;22278:4;22274:38;22343:4;22331:10;22328:20;22325:47;;;-1:-1:-1;22366:4:1;22325:47;22421:2;22416:3;22412:12;22409:1;22405:20;22399:4;22395:31;22385:41;;22476:81;22494:2;22487:5;22484:13;22476:81;;;22553:1;22539:16;;22520:1;22509:13;22476:81;;22749:1299;22875:3;22869:10;22902:18;22894:6;22891:30;22888:56;;;22924:18;;:::i;:::-;22953:97;23043:6;23003:38;23035:4;23029:11;23003:38;:::i;:::-;22997:4;22953:97;:::i;:::-;23099:4;23130:2;23119:14;;23147:1;23142:649;;;;23835:1;23852:6;23849:89;;;-1:-1:-1;23904:19:1;;;23898:26;23849:89;-1:-1:-1;;22706:1:1;22702:11;;;22698:24;22694:29;22684:40;22730:1;22726:11;;;22681:57;23951:81;;23112:930;;23142:649;22002:1;21995:14;;;22039:4;22026:18;;-1:-1:-1;;23178:20:1;;;23296:222;23310:7;23307:1;23304:14;23296:222;;;23392:19;;;23386:26;23371:42;;23499:4;23484:20;;;;23452:1;23440:14;;;;23326:12;23296:222;;;23300:3;23546:6;23537:7;23534:19;23531:201;;;23607:19;;;23601:26;-1:-1:-1;;23690:1:1;23686:14;;;23702:3;23682:24;23678:37;23674:42;23659:58;23644:74;;23531:201;-1:-1:-1;;;;23778:1:1;23762:14;;;23758:22;23745:36;;-1:-1:-1;22749:1299:1:o;24053:245::-;24120:6;24173:2;24161:9;24152:7;24148:23;24144:32;24141:52;;;24189:1;24186;24179:12;24141:52;24221:9;24215:16;24240:28;24262:5;24240:28;:::i;24714:485::-;-1:-1:-1;;;;;24945:32:1;;;24927:51;;25014:32;;25009:2;24994:18;;24987:60;25078:2;25063:18;;25056:34;;;25126:3;25121:2;25106:18;;25099:31;;;-1:-1:-1;;25147:46:1;;25173:19;;25165:6;25147:46;:::i;25204:249::-;25273:6;25326:2;25314:9;25305:7;25301:23;25297:32;25294:52;;;25342:1;25339;25332:12;25294:52;25374:9;25368:16;25393:30;25417:5;25393:30;:::i
Swarm Source
ipfs://ef9a63d329c5cb68fcb78c323435d0abb474f0582e53487911b1c7ec2e400218
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.