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-24 */ // 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); function getProxyCaller() external view returns (address); } //@author 0xPhant0m based on Andre Cronje's voteEscrow contract for Solidly pragma solidity 0.8.27; 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 * int128(PRECISION)) / iMAXTIME; uOld.bias = (uOld.slope * int128(uint128(oldLocked.end - uint32(block.timestamp)))) / int128(PRECISION); } if (newLocked.end > uint32(block.timestamp) && newLocked.amount > 0) { uNew.slope = (newLocked.amount * int128(PRECISION)) / iMAXTIME; uNew.bias = (uNew.slope * int128(uint128(newLocked.end - uint32(block.timestamp)))) / int128(PRECISION); } _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) != tx.origin) 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 with only the additional amount _updateWeightedSupply( additionalAmount, 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; // Find the right historical point Point memory lastPoint; for (uint32 i = userEpoch; i >= 1; i--) { lastPoint = userPointHistory[tokenId][i]; if (lastPoint.ts <= timestamp) { int128 timeDelta = int128(uint128(timestamp - lastPoint.ts)); lastPoint.bias = lastPoint.bias - ((lastPoint.slope * timeDelta) / int128(PRECISION)); if (lastPoint.bias < 0) { lastPoint.bias = 0; } return uint128(uint256(uint128(lastPoint.bias))); } } return 0; } 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; } 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 with proper precision uint256 value = uint256(lock.amount); uint256 slopeCalc = (value * PRECISION) / MAXTIME; // Multiply by PRECISION before division 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 with proper precision uint32 remainingDuration = lock.endTime - uint32(block.timestamp); uint256 bias = (uint256(newSlope) * remainingDuration) / PRECISION; // Divide by PRECISION after multiplication uint256 multiplier = BASE_MULTIPLIER + ((bias * (MAX_MULTIPLIER - BASE_MULTIPLIER)) / (uint256(newSlope) * MAXTIME / PRECISION)); // Adjust precision in denominator 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 }); } } }
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":"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
6080604052606d805463ffffffff60a01b1916600f60a01b1790553480156024575f5ffd5b50602b602f565b60df565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff1615607e5760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460dc5780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b6151d8806100ec5f395ff3fe608060405234801561000f575f5ffd5b50600436106102b1575f3560e01c80638981be0e1161017b578063bbe33ea5116100e4578063ddacc94a1161009e578063e58f594711610079578063e58f5947146107ee578063e985e9c514610813578063f2fde38b14610826578063f7b188a514610839575f5ffd5b8063ddacc94a146107b5578063df0c78ef146107c8578063df215157146107db575f5ffd5b8063bbe33ea51461073f578063bcc0022514610752578063beb8310914610774578063c5b1c7d014610787578063c87b56dd1461078f578063d89dd269146107a2575f5ffd5b806395d89b411161013557806395d89b41146106a257806397612d4b146106aa57806398a3f422146106bd5780639b7d02ad146106dc578063a22cb46514610719578063b88d4fde1461072c575f5ffd5b80638981be0e1461055d57806389f839c6146105705780638b25e8c1146105f35780638da5cb5b146106065780638ff4249014610636578063900cf0cf1461067d575f5ffd5b8063268dc1991161021d578063586c2600116101d7578063586c2600146104ce5780635c975abb146105035780636352211e1461050e57806370a0823114610521578063715018a61461054257806375619ab51461054a575f5ffd5b8063268dc1991461045e5780632e1a7d4d1461046f5780632e720f7d1461048257806342842e0e146104955780635312ea8e146104a85780635594a045146104bb575f5ffd5b80631d237a491161026e5780631d237a49146103635780631f5ab022146103e85780632016a0d2146103fb57806320a194b81461040e57806323b872dd1461042057806324c44c5b14610433575f5ffd5b806301ffc9a7146102b557806306fdde03146102dd578063081812fc146102f2578063095ea7b31461031d5780630f45cc811461033257806313de148b14610343575b5f5ffd5b6102c86102c336600461479f565b610841565b60405190151581526020015b60405180910390f35b6102e5610892565b6040516102d491906147e8565b6103056103003660046147fa565b610933565b6040516001600160a01b0390911681526020016102d4565b61033061032b36600461482c565b610947565b005b6064546001600160a01b0316610305565b610356610351366004614854565b610956565b6040516102d4919061486d565b6103b56103713660046148c2565b606b60209081525f928352604080842090915290825290208054600190910154600f82810b92600160801b9004900b9063ffffffff80821691600160201b90041684565b60408051600f95860b81529390940b602084015263ffffffff9182169383019390935290911660608201526080016102d4565b6103306103f6366004614902565b610a4b565b610330610409366004614a0a565b610d89565b606f54600160a01b900460ff166102c8565b61033061042e366004614a8f565b610f84565b6104466104413660046148c2565b610f9e565b6040516001600160801b0390911681526020016102d4565b606e546001600160801b0316610446565b61033061047d3660046147fa565b6110ae565b610330610490366004614854565b6113d7565b6103306104a3366004614a8f565b611428565b6103306104b63660046147fa565b611442565b606d54610305906001600160a01b031681565b6104f06104dc366004614ac9565b606c6020525f9081526040902054600f0b81565b604051600f9190910b81526020016102d4565b60325460ff166102c8565b61030561051c3660046147fa565b6115db565b61053461052f366004614854565b6115e5565b6040519081526020016102d4565b61033061163d565b610330610558366004614854565b611650565b61033061056b366004614ae2565b6116fa565b6105bc61057e3660046147fa565b60666020525f9081526040902080546001909101546001600160801b0380831692600160801b9004169063ffffffff80821691600160201b90041684565b604080516001600160801b03958616815294909316602085015263ffffffff918216928401929092521660608201526080016102d4565b6104466106013660046147fa565b611a14565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b0316610305565b6103b5610644366004614ac9565b60686020525f908152604090208054600190910154600f82810b92600160801b9004900b9063ffffffff80821691600160201b90041684565b60695461068d9063ffffffff1681565b60405163ffffffff90911681526020016102d4565b6102e5611bb0565b6104466106b8366004614ac9565b611bee565b6105346106cb3660046147fa565b60706020525f908152604090205481565b6107076106ea366004614854565b6001600160a01b03165f9081526067602052604090205460ff1690565b60405160ff90911681526020016102d4565b610330610727366004614b0f565b611c5a565b61033061073a366004614b44565b611c65565b61033061074d366004614baf565b611c7b565b610707610760366004614854565b60676020525f908152604090205460ff1681565b610330610782366004614c24565b6121d0565b6103306126bb565b6102e561079d3660046147fa565b612721565b6104466107b0366004614c47565b612874565b6104466107c33660046148c2565b6128ed565b6104466107d6366004614c47565b612a38565b6105346107e9366004614c6f565b612aec565b61068d6107fc3660046147fa565b606a6020525f908152604090205463ffffffff1681565b6102c8610821366004614c99565b612e96565b610330610834366004614854565b612ee2565b610330612f1c565b5f6001600160e01b031982166380ac58cd60e01b148061087157506001600160e01b03198216635b5e139f60e01b145b8061088c57506301ffc9a760e01b6001600160e01b03198316145b92915050565b5f5160206151835f395f51905f5280546060919081906108b190614cc1565b80601f01602080910402602001604051908101604052809291908181526020018280546108dd90614cc1565b80156109285780601f106108ff57610100808354040283529160200191610928565b820191905f5260205f20905b81548152906001019060200180831161090b57829003601f168201915b505050505091505090565b5f61093d82612f2c565b5061088c82612f63565b610952828233612f9c565b5050565b6001600160a01b0381165f9081526067602052604090205460609060ff168067ffffffffffffffff81111561098d5761098d614945565b6040519080825280602002602001820160405280156109b6578160200160208202803683370190505b5091508060ff165f036109c95750919050565b5f805b606554600160a01b900463ffffffff16811015610a4357846001600160a01b03166109f682612fa9565b6001600160a01b031603610a3b5780848381518110610a1757610a17614cf9565b602090810291909101015281610a2c81614d21565b9250508260ff16821015610a43575b6001016109cc565b505050919050565b610a53612fe2565b610a5b613039565b8180421115610a7d57604051631ab7da6b60e01b815260040160405180910390fd5b33610a87866115db565b6001600160a01b031614610aae576040516359dc379f60e01b815260040160405180910390fd5b5f858152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b900490911660608201529103610b2957604051632254ea3d60e11b815260040160405180910390fd5b5f858260400151610b3a9190614d39565b90505f610b474283614d55565b905062ed4e0063ffffffff82161115610b7357604051637616640160e01b815260040160405180910390fd5b5f610b80845f015161307f565b90505f610b8d82846130c2565b9050866001600160801b0316816001600160801b03161015610bc257604051638199f5f360e01b815260040160405180910390fd5b8451610bce9082613185565b610c1d8a6040518060400160405280885f0151600f0b8152602001886040015163ffffffff168152506040518060400160405280895f0151600f0b81526020018863ffffffff168152506131f7565b6040518060800160405280865f01516001600160801b03168152602001836001600160801b031681526020018563ffffffff1681526020014263ffffffff1681525060665f8c81526020019081526020015f205f820151815f015f6101000a8154816001600160801b0302191690836001600160801b031602179055506020820151815f0160106101000a8154816001600160801b0302191690836001600160801b031602179055506040820151816001015f6101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160046101000a81548163ffffffff021916908363ffffffff16021790555090505089336001600160a01b03167f3032be442129e161b4ae1cdee94871a69de2c16ee2007f31fc209a715673455c8684604051610d6c92919063ffffffff9290921682526001600160801b0316602082015260400190565b60405180910390a3505050505050610d8360015f55565b50505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff165f81158015610dce5750825b90505f8267ffffffffffffffff166001148015610dea5750303b155b905081158015610df8575080155b15610e165760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610e4057845460ff60401b1916600160401b1785555b6001600160a01b0389161580610e5d57506001600160a01b038816155b15610e7b5760405163d92e233d60e01b815260040160405180910390fd5b610e858787613216565b610e8d613228565b610e95613238565b610e9e33613248565b610ea6613259565b606480546001600160a01b03808c166001600160a01b031992831617909255606f8054928b16929091169190911790555f805260686020527fad6f8124f6081c2622ab3a16acd47af73d52fe87b755c3f897263c58ba3fdbd880544263ffffffff90811663ffffffff194392909216600160201b029190911667ffffffffffffffff19909216919091171790558315610f7957845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b610f8e83826132ae565b610f99838383613341565b505050565b5f8163ffffffff165f03610fc557604051637616640160e01b815260040160405180910390fd5b5f838152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b90049091166060820152910361104057604051632254ea3d60e11b815260040160405180910390fd5b5f8382604001516110519190614d39565b90505f61105e4283614d55565b905062ed4e0063ffffffff8216111561108a57604051637616640160e01b815260040160405180910390fd5b5f611097845f015161307f565b90506110a381836130c2565b979650505050505050565b6110b6612fe2565b5f6110c082612fa9565b90506001600160a01b0381166110e857604051626f708760e21b815260040160405180910390fd5b6001600160a01b0381163314611111576040516359dc379f60e01b815260040160405180910390fd5b5f828152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b90049091166060820152910361118c57604051632254ea3d60e11b815260040160405180910390fd5b806040015163ffffffff164263ffffffff1610156111bd5760405163342ad40160e11b815260040160405180910390fd5b8051604080518082018252600f83900b81528184015163ffffffff166020808301919091525f8781526066909152918220828155600101805467ffffffffffffffff191690559061120d86611a14565b90505f670de0b6b3a764000061122f6001600160801b03808516908716614d71565b6112399190614d9c565b9050816001600160801b0316846001600160801b03168261125a9190614d9c565b1461127857604051630fc12e3560e11b815260040160405180910390fd5b5f61128b670de0b6b3a764000083614d9c565b90506001600160801b038111156112b55760405163162908e360e11b815260040160405180910390fd5b606e80548291905f906112d29084906001600160801b0316614daf565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555061131e888560405180604001604052805f600f0b81526020015f63ffffffff168152506131f7565b5f888152606a60205260409020805463ffffffff1916905561133f886133c4565b335f818152606760205260409020805460ff19811660ff9182165f1901909116179055606454611384916001600160a01b03909116906001600160801b0388166133fc565b6040516001600160801b0386168152889033907f8903a5b5d08a841e7f68438387f1da20c84dea756379ed37e633ff3854b99b849060200160405180910390a3505050505050506113d460015f55565b50565b6113df61345f565b6001600160a01b0381166114065760405163d92e233d60e01b815260040160405180910390fd5b606d80546001600160a01b0319166001600160a01b0392909216919091179055565b610f9983838360405180602001604052805f815250611c65565b61144a612fe2565b606f54600160a01b900460ff166114a05760405162461bcd60e51b81526020600482015260156024820152744e6f7420696e20656d657267656e6379206d6f646560581b60448201526064015b60405180910390fd5b336114aa826115db565b6001600160a01b0316146114d1576040516359dc379f60e01b815260040160405180910390fd5b5f818152606660208181526040808420815160808101835281546001600160801b03808216808452600160801b909204168286015260018301805463ffffffff80821696850196909652600160201b810490951660608401528888529590945294905567ffffffffffffffff191690915561154b836133c4565b335f818152606760205260409020805460ff19811660ff9182165f1901909116179055606454611590916001600160a01b03909116906001600160801b0384166133fc565b6040516001600160801b0382168152839033907f4f27eb511b2a4633cfb633ac1c4a99b4c298ca6488b29ec26f3504a5927f67289060200160405180910390a350506113d460015f55565b5f61088c82612f2c565b5f5f5160206151835f395f51905f526001600160a01b03831661161d576040516322718ad960e21b81525f6004820152602401611497565b6001600160a01b039092165f908152600390920160205250604090205490565b61164561345f565b61164e5f6134ba565b565b61165861345f565b6001600160a01b03811661167f5760405163d92e233d60e01b815260040160405180910390fd5b6065546001600160a01b0316156116d85760405162461bcd60e51b815260206004820152601760248201527f4469737472696275746f7220616c7265616479207365740000000000000000006044820152606401611497565b606580546001600160a01b0319166001600160a01b0392909216919091179055565b61170261345f565b606554600160a01b900463ffffffff1681111561172b5750606554600160a01b900463ffffffff165b815b81811015610f99575f61173f82612fa9565b6001600160a01b031614611a0c575f81815260666020908152604091829020825160808101845281546001600160801b03808216808452600160801b909204169382019390935260019091015463ffffffff80821694830194909452600160201b9004909216606083015215806117c65750806040015163ffffffff164263ffffffff1610155b156117d15750611a0c565b80516001600160801b03165f62ed4e006117f3670de0b6b3a764000084614d71565b6117fd9190614d9c565b90506001600160801b0381111561181657505050611a0c565b602083015181906001600160801b038083169116036118385750505050611a0c565b5f4285604001516118499190614d55565b90505f670de0b6b3a764000061186e63ffffffff84166001600160801b038616614d71565b6118789190614d9c565b90505f670de0b6b3a764000061189a62ed4e006001600160801b038716614d71565b6118a49190614d9c565b6118be670de0b6b3a7640000673782dace9d900000614daf565b6118d1906001600160801b031684614d71565b6118db9190614d9c565b6118ed90670de0b6b3a7640000614dce565b9050673782dace9d90000081111561190a5750673782dace9d9000005b670de0b6b3a76400008110156119255750670de0b6b3a76400005b6119788860405180604001604052808a5f0151600f0b81526020018a6040015163ffffffff1681525060405180604001604052808b5f0151600f0b81526020018b6040015163ffffffff168152506131f7565b50506040805160808101825286516001600160801b03908116825293841660208083019182529783015163ffffffff908116838501908152428216606085019081525f8c81526066909b5294909920925191518616600160801b029190951617815595516001909601805491518416600160201b0267ffffffffffffffff1990921696909316959095179490941790555050505b60010161172d565b5f818152606660209081526040808320815160808101835281546001600160801b038082168352600160801b90910416938101939093526001015463ffffffff808216928401839052600160201b90910481166060840152421610611a835750670de0b6b3a764000092915050565b5f611a99670de0b6b3a764000062ed4e00614de1565b6001600160801b0316611abc670de0b6b3a7640000673782dace9d900000614daf565b8351611ad4916001600160801b039081169116614d71565b611ade9190614d9c565b90506001600160801b03811115611b085760405163162908e360e11b815260040160405180910390fd5b604082015181905f90611b1c904290614d55565b90505f611b3863ffffffff83166001600160801b038516614d71565b611b4a90670de0b6b3a7640000614dce565b9050673782dace9d9000006001600160801b0382161115611b795750673782dace9d9000009695505050505050565b670de0b6b3a76400006001600160801b0382161015611ba65750670de0b6b3a76400009695505050505050565b9695505050505050565b7f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930180546060915f5160206151835f395f51905f52916108b190614cc1565b60695463ffffffff9081165f90815260686020908152604080832081516080810183528154600f81810b8352600160801b909104900b938101939093526001015480851691830191909152600160201b9004909216606083015290611c53818461352a565b9392505050565b61095233838361363f565b611c6f84836132ae565b610d83848484846136ee565b611c83612fe2565b611c8b613039565b8080421115611cad57604051631ab7da6b60e01b815260040160405180910390fd5b6002831015611ccf5760405163162908e360e11b815260040160405180910390fd5b5f80805b85811015611dd85733611cfd888884818110611cf157611cf1614cf9565b905060200201356115db565b6001600160a01b031614611d24576040516359dc379f60e01b815260040160405180910390fd5b5f60665f898985818110611d3a57611d3a614cf9565b602090810292909201358352508181019290925260409081015f20815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b900490911660608201529150611dad9085614e0a565b93508263ffffffff16816040015163ffffffff161115611dcf57806040015192505b50600101611cd3565b505f611de44283614d55565b905062ed4e0063ffffffff82161115611e1057604051637616640160e01b815260040160405180910390fd5b5f62ed4e00611e2f670de0b6b3a7640000673782dace9d900000614daf565b6001600160801b0316856001600160801b0316611e4c9190614d71565b611e569190614d9c565b90506001600160801b03811115611e805760405163162908e360e11b815260040160405180910390fd5b6065805482915f91601490611ea190600160a01b900463ffffffff16614e29565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff169050611ed03382613706565b5f5b89811015611fbb575f8b8b83818110611eed57611eed614cf9565b602090810292909201355f818152606684526040808220815160808101835281546001600160801b038082168352600160801b909104168188015260019091015463ffffffff808216838501908152600160201b90920481166060840152835180850185528351600f0b815291511681880152825180840190935283835295820192909252919450929150611f8590849083906131f7565b5f838152606660205260408120908155600101805467ffffffffffffffff19169055611fb0836133c4565b505050600101611ed2565b50604080518082018252600f88900b815263ffffffff871660208083019190915282518084019093525f8084529083015290611ff9908390836131f7565b6040518060800160405280886001600160801b03168152602001846001600160801b031681526020018763ffffffff1681526020014263ffffffff1681525060665f8481526020019081526020015f205f820151815f015f6101000a8154816001600160801b0302191690836001600160801b031602179055506020820151815f0160106101000a8154816001600160801b0302191690836001600160801b031602179055506040820151816001015f6101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055509050508a8a905060675f336001600160a01b03166001600160a01b031681526020019081526020015f205f9054906101000a900460ff160360010160675f336001600160a01b03166001600160a01b031681526020019081526020015f205f6101000a81548160ff021916908360ff16021790555081336001600160a01b03167fdbd81f1b10e6f1395ede56cabac59119f8be0cb5ca3ef0ca44f859782893495489896040516121b79291906001600160801b0392909216825263ffffffff16602082015260400190565b60405180910390a35050505050505050610f9960015f55565b6121d8612fe2565b6121e0613039565b818042111561220257604051631ab7da6b60e01b815260040160405180910390fd5b3261220c866115db565b6001600160a01b031614612233576040516359dc379f60e01b815260040160405180910390fd5b836001600160801b03165f0361225c5760405163162908e360e11b815260040160405180910390fd5b5f858152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b9004909116606082015291036122d757604051632254ea3d60e11b815260040160405180910390fd5b806040015163ffffffff164263ffffffff1610612307576040516307b7d7dd60e51b815260040160405180910390fd5b80515f90612316908790614e0a565b90505f6123228261307f565b90505f4284604001516123359190614d55565b90505f61235163ffffffff83166001600160801b038516614d71565b61236390670de0b6b3a7640000614dce565b9050673782dace9d9000006001600160801b038216111561239757604051638f651fb760e01b815260040160405180910390fd5b866001600160801b0316816001600160801b031610156123ca57604051638199f5f360e01b815260040160405180910390fd5b6064546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015612410573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124349190614e4d565b606454909150612458906001600160a01b031633306001600160801b038e1661371f565b61246b6001600160801b038b1682614dce565b6064546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156124b1573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124d59190614e4d565b146124f3576040516312171d8360e31b815260040160405180910390fd5b6124fd8a83613185565b61254d8b6040518060400160405280895f0151600f0b8152602001896040015163ffffffff16815250604051806040016040528089600f0b81526020018a6040015163ffffffff168152506131f7565b6040518060800160405280866001600160801b03168152602001856001600160801b03168152602001876040015163ffffffff1681526020014263ffffffff1681525060665f8d81526020019081526020015f205f820151815f015f6101000a8154816001600160801b0302191690836001600160801b031602179055506020820151815f0160106101000a8154816001600160801b0302191690836001600160801b031602179055506040820151816001015f6101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055509050508a336001600160a01b03167f1381e2f7d0d4b71a58d34dc3db2051dd52769766e65eabf380c9b4ea93f0890b8c88866040516126a3939291906001600160801b0393841681529183166020830152909116604082015260600190565b60405180910390a350505050505050610d8360015f55565b6126c361345f565b606f805460ff60a01b1916600160a01b1790556126de613259565b606f546040516001600160a01b0390911681527fc0a1c7e9f05b4d536e1ff8606bae9b847cdb43ef4a9b2d7a503a88cee08dccdb906020015b60405180910390a1565b60605f61272d83612fa9565b6001600160a01b03160361275357604051626f708760e21b815260040160405180910390fd5b606d546001600160a01b031661277c576040516338a69c8d60e21b815260040160405180910390fd5b606d54604051602481018490525f9182916001600160a01b039091169060440160408051601f198184030181529181526020820180516001600160e01b031663c87b56dd60e01b179052516127d19190614e64565b5f60405180830381855afa9150503d805f8114612809576040519150601f19603f3d011682016040523d82523d5f602084013e61280e565b606091505b5091509150816128585760405162461bcd60e51b8152602060048201526015602482015274105c9d081c1c9bde1e4818d85b1b0819985a5b1959605a1b6044820152606401611497565b8080602001905181019061286c9190614e7a565b949350505050565b5f63ffffffff82161580612890575062ed4e0063ffffffff8316115b156128ae57604051637616640160e01b815260040160405180910390fd5b826001600160801b03165f036128d75760405163162908e360e11b815260040160405180910390fd5b5f6128e18461307f565b905061286c81846130c2565b5f828152606a602052604081205463ffffffff16808203612911575f91505061088c565b604080516080810182525f808252602082018190529181018290526060810191909152815b60018163ffffffff1610612a2d575f868152606b6020908152604080832063ffffffff80861685529083529281902081516080810183528154600f81810b8352600160801b909104900b9381019390935260010154808416918301829052600160201b90048316606083015290935090861610612a1b575f8260400151866129be9190614d55565b63ffffffff169050670de0b6b3a76400008184602001516129df9190614eef565b6129e99190614f0e565b83516129f59190614f4a565b600f0b8084525f1315612a06575f83525b5050516001600160801b0316915061088c9050565b80612a2581614f77565b915050612936565b505f95945050505050565b606d545f90819063ffffffff600160a01b909104811690841611612a5c5782612a76565b606d54612a7690600160a01b900463ffffffff1684614d55565b90505f62ed4e00612a97670de0b6b3a7640000673782dace9d900000614daf565b6001600160801b0316866001600160801b0316612ab49190614d71565b612abe9190614d9c565b905080612ada63ffffffff84166001600160801b038316614d71565b611ba690670de0b6b3a7640000614dce565b5f612af5612fe2565b612afd613039565b8280421115612b1f57604051631ab7da6b60e01b815260040160405180910390fd5b856001600160801b03165f03612b485760405163162908e360e11b815260040160405180910390fd5b63ffffffff85161580612b63575062ed4e0063ffffffff8616115b15612b8157604051637616640160e01b815260040160405180910390fd5b335f90815260676020526040902054606460ff90911610612bb55760405163133cbc4f60e01b815260040160405180910390fd5b5f612bc08642614d39565b90505f5f612bcf898988613757565b915091505f60405180604001604052808b600f0b81526020018563ffffffff168152509050612c1c5f60405180604001604052805f600f0b81526020015f63ffffffff16815250836131f7565b6064546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015612c62573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c869190614e4d565b606454909150612caa906001600160a01b031633306001600160801b038f1661371f565b612cbd6001600160801b038c1682614dce565b6064546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015612d03573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d279190614e4d565b14612d45576040516312171d8360e31b815260040160405180910390fd5b60658054600163ffffffff600160a01b80840482168381019092160263ffffffff60a01b1990931692909217909255335f818152606760205260409020805460ff80821690950190941660ff19909416939093179092559750612da89088613706565b604080516080810182526001600160801b03808e168252868116602080840191825263ffffffff808b16858701908152428216606087019081525f8f8152606690945296909220945192518416600160801b0292909316919091178355516001909201805493518216600160201b0267ffffffffffffffff199094169290911691909117919091179055612e3c8b84613185565b604080516001600160801b038d16815263ffffffff87166020820152889133917fdbd81f1b10e6f1395ede56cabac59119f8be0cb5ca3ef0ca44f8597828934954910160405180910390a350505050505061286c60015f55565b6001600160a01b039182165f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab00793056020908152604080832093909416825291909152205460ff1690565b612eea61345f565b6001600160a01b038116612f1357604051631e4fbdf760e01b81525f6004820152602401611497565b6113d4816134ba565b612f2461345f565b61164e6138b1565b5f5f612f3783612fa9565b90506001600160a01b03811661088c57604051637e27328960e01b815260048101849052602401611497565b5f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930460205260409020546001600160a01b031690565b610f9983838360016138ea565b5f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930260205260409020546001600160a01b031690565b60025f54036130335760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611497565b60025f55565b60325460ff161561164e5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401611497565b5f6001600160801b0382168161309862ed4e0083614d9c565b90506001600160801b03811115611c535760405163162908e360e11b815260040160405180910390fd5b5f806130dd63ffffffff84166001600160801b038616614d71565b90505f6130f662ed4e006001600160801b038716614d71565b613110670de0b6b3a7640000673782dace9d900000614daf565b613123906001600160801b031684614d71565b61312d9190614d9c565b61313f90670de0b6b3a7640000614dce565b9050673782dace9d90000081111561316357673782dace9d9000009250505061088c565b670de0b6b3a764000081101561286c57670de0b6b3a76400009250505061088c565b5f670de0b6b3a76400006131a56001600160801b03848116908616614d71565b6131af9190614d9c565b606e805491925082915f906131ce9084906001600160801b0316614e0a565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550505050565b6131ff6139fd565b8215610f9957610f99838383613b6f565b60015f55565b61321e613db5565b6109528282613dfe565b613230613db5565b61164e613e2e565b613240613db5565b61164e613e36565b613250613db5565b6113d481613e4a565b613261613039565b6032805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586132963390565b6040516001600160a01b039091168152602001612717565b6001600160a01b038216158015906132d057506065546001600160a01b031615155b156109525760655460405163379607f560e01b8152600481018390526001600160a01b039091169063379607f5906024016020604051808303815f875af115801561331d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f999190614e4d565b6001600160a01b03821661336a57604051633250574960e11b81525f6004820152602401611497565b5f613376838333613e52565b9050836001600160a01b0316816001600160a01b031614610d83576040516364283d7b60e01b81526001600160a01b0380861660048301526024820184905282166044820152606401611497565b5f6133d05f835f613e52565b90506001600160a01b03811661095257604051637e27328960e01b815260048101839052602401611497565b6040516001600160a01b038316602482015260448101829052610f9990849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613f54565b336134917f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b03161461164e5760405163118cdaa760e01b8152336004820152602401611497565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f5f8390505f62093a808083604001516135449190614f95565b61354e9190614fbc565b90505f5b60ff81101561361a5761356862093a8083614d39565b91505f63ffffffff80871690841611156135845785925061359e565b5063ffffffff82165f908152606c6020526040902054600f0b5b60408401516135ad9084614d55565b63ffffffff1684602001516135c29190614eef565b845185906135d1908390614f4a565b600f0b90525063ffffffff808716908416036135ed575061361a565b80846020018181516135ff9190614fdb565b600f0b9052505063ffffffff82166040840152600101613552565b505f825f0151600f0b121561362d575f82525b50516001600160801b03169392505050565b5f5160206151835f395f51905f526001600160a01b03831661367f57604051630b61174360e31b81526001600160a01b0384166004820152602401611497565b6001600160a01b038481165f818152600584016020908152604080832094881680845294825291829020805460ff191687151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a350505050565b6136f9848484610f84565b610d833385858585614027565b610952828260405180602001604052805f81525061414f565b6040516001600160a01b0380851660248301528316604482015260648101829052610d839085906323b872dd60e01b90608401613428565b5f8080613775670de0b6b3a76400006001600160801b038816614d9c565b90505f613792670de0b6b3a7640000673782dace9d900000614daf565b6001600160801b031690505f6137b3670de0b6b3a764000062ed4e00614de1565b6001600160801b03166137c68385614d71565b6137d09190614d9c565b90506001600160801b038111156137fa5760405163162908e360e11b815260040160405180910390fd5b9350835f670de0b6b3a764000061382063ffffffff8a166001600160801b038516614d71565b61382a9190614d9c565b905061383e81670de0b6b3a7640000614dce565b9450673782dace9d9000006001600160801b038616111561387257604051638f651fb760e01b815260040160405180910390fd5b866001600160801b0316856001600160801b031610156138a557604051638199f5f360e01b815260040160405180910390fd5b50505050935093915050565b6138b9614166565b6032805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33613296565b5f5160206151835f395f51905f52818061390c57506001600160a01b03831615155b156139cd575f61391b85612f2c565b90506001600160a01b038416158015906139475750836001600160a01b0316816001600160a01b031614155b801561395a57506139588185612e96565b155b156139835760405163a9fbf51f60e01b81526001600160a01b0385166004820152602401611497565b82156139cb5784866001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5f93845260040160205250506040902080546001600160a01b0319166001600160a01b0392909216919091179055565b60695463ffffffff16613a2f604080516080810182525f80825260208201819052918101829052606081019190915290565b63ffffffff821615613aa85760685f613a49600185614d55565b63ffffffff908116825260208083019390935260409182015f2082516080810184528154600f81810b8352600160801b909104900b948101949094526001015480821692840192909252600160201b9091041660608201529050613ad5565b50604080516080810182525f808252602082015263ffffffff428116928201929092524390911660608201525b60408101515f63ffffffff808316429091161115613b36576040830151613b029063ffffffff1642615008565b6060840151613b179063ffffffff1643615008565b613b2990670de0b6b3a7640000614d71565b613b339190614d9c565b90505b613b42838383876141af565b9250613b4f846001614d39565b6069805463ffffffff191663ffffffff9290921691909117905550505050565b604080516080810182525f808252602082018190529181018290526060810191909152604080516080810182525f8082526020820181905291810182905260608101919091524263ffffffff16846020015163ffffffff16118015613bd957505f845f0151600f0b135b15613c4b57835162ed4e0090613bf890670de0b6b3a764000090614eef565b613c029190614f0e565b600f0b602080840191909152840151670de0b6b3a764000090613c26904290614d55565b63ffffffff168360200151613c3b9190614eef565b613c459190614f0e565b600f0b82525b4263ffffffff16836020015163ffffffff16118015613c6f57505f835f0151600f0b135b15613ce157825162ed4e0090613c8e90670de0b6b3a764000090614eef565b613c989190614f0e565b600f0b602080830191909152830151670de0b6b3a764000090613cbc904290614d55565b63ffffffff168260200151613cd19190614eef565b613cdb9190614f0e565b600f0b81525b613cf58484846020015184602001516143b4565b5f858152606a6020526040812054613d149063ffffffff166001614d39565b5f878152606a60209081526040808320805463ffffffff95861663ffffffff199091168117909155428516878301908152438616606089019081529b8552606b84528285209185529083529220855195909101516001600160801b03908116600160801b02951694909417845551600193909301805497518216600160201b0267ffffffffffffffff19909816939091169290921795909517905550505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661164e57604051631afcd79f60e31b815260040160405180910390fd5b613e06613db5565b5f5160206151835f395f51905f5280613e1f848261505f565b5060018101610d83838261505f565b613210613db5565b613e3e613db5565b6032805460ff19169055565b612eea613db5565b5f5f5160206151835f395f51905f5281613e6b85612fa9565b90506001600160a01b03841615613e8757613e878185876144ef565b6001600160a01b03811615613ec357613ea25f865f5f6138ea565b6001600160a01b0381165f908152600383016020526040902080545f190190555b6001600160a01b03861615613ef3576001600160a01b0386165f9081526003830160205260409020805460010190555b5f85815260028301602052604080822080546001600160a01b0319166001600160a01b038a811691821790925591518893918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a495945050505050565b5f613fa8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166145539092919063ffffffff16565b905080515f1480613fc8575080806020019051810190613fc8919061511a565b610f995760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611497565b6001600160a01b0383163b1561414857604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290614069908890889087908790600401615135565b6020604051808303815f875af19250505080156140a3575060408051601f3d908101601f191682019092526140a091810190615167565b60015b61410a573d8080156140d0576040519150601f19603f3d011682016040523d82523d5f602084013e6140d5565b606091505b5080515f0361410257604051633250574960e11b81526001600160a01b0385166004820152602401611497565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b1461414657604051633250574960e11b81526001600160a01b0385166004820152602401611497565b505b5050505050565b6141598383614561565b610f99335f858585614027565b60325460ff1661164e5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401611497565b604080516080810182525f808252602082018190529181018290526060810191909152845f62093a806141e28188614f95565b6141ec9190614fbc565b90505f5b60ff8110156143a85761420662093a8083614d39565b91505f63ffffffff42811690841611156142225742925061423c565b5063ffffffff82165f908152606c6020526040902054600f0b5b6142468884614d55565b63ffffffff16896020015161425b9190614eef565b89518a9061426a908390614f4a565b600f0b905250602089018051829190614284908390614fdb565b600f0b90525063ffffffff83166040808b0191909152840151670de0b6b3a7640000906142b19085614d55565b6142ca9063ffffffff166001600160801b038a16614d71565b6142d49190614d9c565b846060015163ffffffff166142e99190614dce565b63ffffffff90811660608b015242811690841603614313575063ffffffff431660608901526143a8565b8860685f846143238a6001614d39565b61432d9190614d39565b63ffffffff908116825260208083019390935260409182015f208451938501516001600160801b03908116600160801b02941693909317835590830151600190920180546060909401518216600160201b0267ffffffffffffffff1990941692909116919091179190911790555090955085906001016141f0565b50959695505050505050565b4263ffffffff16846020015163ffffffff1611156144555760208085015163ffffffff165f908152606c9091526040902054600f0b6143f38382614fdb565b9050846020015163ffffffff16846020015163ffffffff160361441d5761441a8282614f4a565b90505b60208581015163ffffffff165f908152606c9091526040902080546001600160801b0319166001600160801b03929092169190911790555b4263ffffffff16836020015163ffffffff161115610d8357836020015163ffffffff16836020015163ffffffff161115610d835760208084015163ffffffff165f908152606c9091526040902054600f0b6144b08282614f4a565b60208086015163ffffffff165f908152606c9091526040902080546001600160801b039092166001600160801b03199092169190911790555050505050565b6144fa8383836145c2565b610f99576001600160a01b03831661452857604051637e27328960e01b815260048101829052602401611497565b60405163177e802f60e01b81526001600160a01b038316600482015260248101829052604401611497565b606061286c84845f85614626565b6001600160a01b03821661458a57604051633250574960e11b81525f6004820152602401611497565b5f61459683835f613e52565b90506001600160a01b03811615610f99576040516339e3563760e11b81525f6004820152602401611497565b5f6001600160a01b0383161580159061286c5750826001600160a01b0316846001600160a01b031614806145fb57506145fb8484612e96565b8061286c5750826001600160a01b031661461483612f63565b6001600160a01b031614949350505050565b6060824710156146875760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401611497565b5f5f866001600160a01b031685876040516146a29190614e64565b5f6040518083038185875af1925050503d805f81146146dc576040519150601f19603f3d011682016040523d82523d5f602084013e6146e1565b606091505b50915091506110a3878383876060831561475b5782515f03614754576001600160a01b0385163b6147545760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611497565b508161286c565b61286c83838151156147705781518083602001fd5b8060405162461bcd60e51b815260040161149791906147e8565b6001600160e01b0319811681146113d4575f5ffd5b5f602082840312156147af575f5ffd5b8135611c538161478a565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611c5360208301846147ba565b5f6020828403121561480a575f5ffd5b5035919050565b80356001600160a01b0381168114614827575f5ffd5b919050565b5f5f6040838503121561483d575f5ffd5b61484683614811565b946020939093013593505050565b5f60208284031215614864575f5ffd5b611c5382614811565b602080825282518282018190525f918401906040840190835b818110156148a4578351835260209384019390920191600101614886565b509095945050505050565b803563ffffffff81168114614827575f5ffd5b5f5f604083850312156148d3575f5ffd5b823591506148e3602084016148af565b90509250929050565b80356001600160801b0381168114614827575f5ffd5b5f5f5f5f60808587031215614915575f5ffd5b84359350614925602086016148af565b92506040850135915061493a606086016148ec565b905092959194509250565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561498257614982614945565b604052919050565b5f67ffffffffffffffff8211156149a3576149a3614945565b50601f01601f191660200190565b5f6149c36149be8461498a565b614959565b90508281528383830111156149d6575f5ffd5b828260208301375f602084830101529392505050565b5f82601f8301126149fb575f5ffd5b611c53838335602085016149b1565b5f5f5f5f60808587031215614a1d575f5ffd5b614a2685614811565b9350614a3460208601614811565b9250604085013567ffffffffffffffff811115614a4f575f5ffd5b614a5b878288016149ec565b925050606085013567ffffffffffffffff811115614a77575f5ffd5b614a83878288016149ec565b91505092959194509250565b5f5f5f60608486031215614aa1575f5ffd5b614aaa84614811565b9250614ab860208501614811565b929592945050506040919091013590565b5f60208284031215614ad9575f5ffd5b611c53826148af565b5f5f60408385031215614af3575f5ffd5b50508035926020909101359150565b80151581146113d4575f5ffd5b5f5f60408385031215614b20575f5ffd5b614b2983614811565b91506020830135614b3981614b02565b809150509250929050565b5f5f5f5f60808587031215614b57575f5ffd5b614b6085614811565b9350614b6e60208601614811565b925060408501359150606085013567ffffffffffffffff811115614b90575f5ffd5b8501601f81018713614ba0575f5ffd5b614a83878235602084016149b1565b5f5f5f60408486031215614bc1575f5ffd5b833567ffffffffffffffff811115614bd7575f5ffd5b8401601f81018613614be7575f5ffd5b803567ffffffffffffffff811115614bfd575f5ffd5b8660208260051b8401011115614c11575f5ffd5b6020918201979096509401359392505050565b5f5f5f5f60808587031215614c37575f5ffd5b84359350614925602086016148ec565b5f5f60408385031215614c58575f5ffd5b614c61836148ec565b91506148e3602084016148af565b5f5f5f5f60808587031215614c82575f5ffd5b614c8b856148ec565b9350614925602086016148af565b5f5f60408385031215614caa575f5ffd5b614cb383614811565b91506148e360208401614811565b600181811c90821680614cd557607f821691505b602082108103614cf357634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f60018201614d3257614d32614d0d565b5060010190565b63ffffffff818116838216019081111561088c5761088c614d0d565b63ffffffff828116828216039081111561088c5761088c614d0d565b808202811582820484141761088c5761088c614d0d565b634e487b7160e01b5f52601260045260245ffd5b5f82614daa57614daa614d88565b500490565b6001600160801b03828116828216039081111561088c5761088c614d0d565b8082018082111561088c5761088c614d0d565b6001600160801b038181168382160290811690818114614e0357614e03614d0d565b5092915050565b6001600160801b03818116838216019081111561088c5761088c614d0d565b5f63ffffffff821663ffffffff8103614e4457614e44614d0d565b60010192915050565b5f60208284031215614e5d575f5ffd5b5051919050565b5f82518060208501845e5f920191825250919050565b5f60208284031215614e8a575f5ffd5b815167ffffffffffffffff811115614ea0575f5ffd5b8201601f81018413614eb0575f5ffd5b8051614ebe6149be8261498a565b818152856020838501011115614ed2575f5ffd5b8160208401602083015e5f91810160200191909152949350505050565b5f82600f0b82600f0b0280600f0b9150808214614e0357614e03614d0d565b5f81600f0b83600f0b80614f2457614f24614d88565b60016001607f1b031982145f1982141615614f4157614f41614d0d565b90059392505050565b600f82810b9082900b0360016001607f1b0319811260016001607f1b038213171561088c5761088c614d0d565b5f63ffffffff821680614f8c57614f8c614d0d565b5f190192915050565b5f63ffffffff831680614faa57614faa614d88565b8063ffffffff84160491505092915050565b63ffffffff8181168382160290811690818114614e0357614e03614d0d565b600f81810b9083900b0160016001607f1b03811360016001607f1b03198212171561088c5761088c614d0d565b8181038181111561088c5761088c614d0d565b601f821115610f9957805f5260205f20601f840160051c810160208510156150405750805b601f840160051c820191505b81811015614148575f815560010161504c565b815167ffffffffffffffff81111561507957615079614945565b61508d816150878454614cc1565b8461501b565b6020601f8211600181146150bf575f83156150a85750848201515b5f19600385901b1c1916600184901b178455614148565b5f84815260208120601f198516915b828110156150ee57878501518255602094850194600190920191016150ce565b508482101561510b57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f6020828403121561512a575f5ffd5b8151611c5381614b02565b6001600160a01b03858116825284166020820152604081018390526080606082018190525f90611ba6908301846147ba565b5f60208284031215615177575f5ffd5b8151611c538161478a56fe80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079300a2646970667358221220733f3b755285dd6711ae30379e134c2d199d910fdbd061a873059f6f8cfcd57564736f6c634300081b0033
Deployed Bytecode
0x608060405234801561000f575f5ffd5b50600436106102b1575f3560e01c80638981be0e1161017b578063bbe33ea5116100e4578063ddacc94a1161009e578063e58f594711610079578063e58f5947146107ee578063e985e9c514610813578063f2fde38b14610826578063f7b188a514610839575f5ffd5b8063ddacc94a146107b5578063df0c78ef146107c8578063df215157146107db575f5ffd5b8063bbe33ea51461073f578063bcc0022514610752578063beb8310914610774578063c5b1c7d014610787578063c87b56dd1461078f578063d89dd269146107a2575f5ffd5b806395d89b411161013557806395d89b41146106a257806397612d4b146106aa57806398a3f422146106bd5780639b7d02ad146106dc578063a22cb46514610719578063b88d4fde1461072c575f5ffd5b80638981be0e1461055d57806389f839c6146105705780638b25e8c1146105f35780638da5cb5b146106065780638ff4249014610636578063900cf0cf1461067d575f5ffd5b8063268dc1991161021d578063586c2600116101d7578063586c2600146104ce5780635c975abb146105035780636352211e1461050e57806370a0823114610521578063715018a61461054257806375619ab51461054a575f5ffd5b8063268dc1991461045e5780632e1a7d4d1461046f5780632e720f7d1461048257806342842e0e146104955780635312ea8e146104a85780635594a045146104bb575f5ffd5b80631d237a491161026e5780631d237a49146103635780631f5ab022146103e85780632016a0d2146103fb57806320a194b81461040e57806323b872dd1461042057806324c44c5b14610433575f5ffd5b806301ffc9a7146102b557806306fdde03146102dd578063081812fc146102f2578063095ea7b31461031d5780630f45cc811461033257806313de148b14610343575b5f5ffd5b6102c86102c336600461479f565b610841565b60405190151581526020015b60405180910390f35b6102e5610892565b6040516102d491906147e8565b6103056103003660046147fa565b610933565b6040516001600160a01b0390911681526020016102d4565b61033061032b36600461482c565b610947565b005b6064546001600160a01b0316610305565b610356610351366004614854565b610956565b6040516102d4919061486d565b6103b56103713660046148c2565b606b60209081525f928352604080842090915290825290208054600190910154600f82810b92600160801b9004900b9063ffffffff80821691600160201b90041684565b60408051600f95860b81529390940b602084015263ffffffff9182169383019390935290911660608201526080016102d4565b6103306103f6366004614902565b610a4b565b610330610409366004614a0a565b610d89565b606f54600160a01b900460ff166102c8565b61033061042e366004614a8f565b610f84565b6104466104413660046148c2565b610f9e565b6040516001600160801b0390911681526020016102d4565b606e546001600160801b0316610446565b61033061047d3660046147fa565b6110ae565b610330610490366004614854565b6113d7565b6103306104a3366004614a8f565b611428565b6103306104b63660046147fa565b611442565b606d54610305906001600160a01b031681565b6104f06104dc366004614ac9565b606c6020525f9081526040902054600f0b81565b604051600f9190910b81526020016102d4565b60325460ff166102c8565b61030561051c3660046147fa565b6115db565b61053461052f366004614854565b6115e5565b6040519081526020016102d4565b61033061163d565b610330610558366004614854565b611650565b61033061056b366004614ae2565b6116fa565b6105bc61057e3660046147fa565b60666020525f9081526040902080546001909101546001600160801b0380831692600160801b9004169063ffffffff80821691600160201b90041684565b604080516001600160801b03958616815294909316602085015263ffffffff918216928401929092521660608201526080016102d4565b6104466106013660046147fa565b611a14565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b0316610305565b6103b5610644366004614ac9565b60686020525f908152604090208054600190910154600f82810b92600160801b9004900b9063ffffffff80821691600160201b90041684565b60695461068d9063ffffffff1681565b60405163ffffffff90911681526020016102d4565b6102e5611bb0565b6104466106b8366004614ac9565b611bee565b6105346106cb3660046147fa565b60706020525f908152604090205481565b6107076106ea366004614854565b6001600160a01b03165f9081526067602052604090205460ff1690565b60405160ff90911681526020016102d4565b610330610727366004614b0f565b611c5a565b61033061073a366004614b44565b611c65565b61033061074d366004614baf565b611c7b565b610707610760366004614854565b60676020525f908152604090205460ff1681565b610330610782366004614c24565b6121d0565b6103306126bb565b6102e561079d3660046147fa565b612721565b6104466107b0366004614c47565b612874565b6104466107c33660046148c2565b6128ed565b6104466107d6366004614c47565b612a38565b6105346107e9366004614c6f565b612aec565b61068d6107fc3660046147fa565b606a6020525f908152604090205463ffffffff1681565b6102c8610821366004614c99565b612e96565b610330610834366004614854565b612ee2565b610330612f1c565b5f6001600160e01b031982166380ac58cd60e01b148061087157506001600160e01b03198216635b5e139f60e01b145b8061088c57506301ffc9a760e01b6001600160e01b03198316145b92915050565b5f5160206151835f395f51905f5280546060919081906108b190614cc1565b80601f01602080910402602001604051908101604052809291908181526020018280546108dd90614cc1565b80156109285780601f106108ff57610100808354040283529160200191610928565b820191905f5260205f20905b81548152906001019060200180831161090b57829003601f168201915b505050505091505090565b5f61093d82612f2c565b5061088c82612f63565b610952828233612f9c565b5050565b6001600160a01b0381165f9081526067602052604090205460609060ff168067ffffffffffffffff81111561098d5761098d614945565b6040519080825280602002602001820160405280156109b6578160200160208202803683370190505b5091508060ff165f036109c95750919050565b5f805b606554600160a01b900463ffffffff16811015610a4357846001600160a01b03166109f682612fa9565b6001600160a01b031603610a3b5780848381518110610a1757610a17614cf9565b602090810291909101015281610a2c81614d21565b9250508260ff16821015610a43575b6001016109cc565b505050919050565b610a53612fe2565b610a5b613039565b8180421115610a7d57604051631ab7da6b60e01b815260040160405180910390fd5b33610a87866115db565b6001600160a01b031614610aae576040516359dc379f60e01b815260040160405180910390fd5b5f858152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b900490911660608201529103610b2957604051632254ea3d60e11b815260040160405180910390fd5b5f858260400151610b3a9190614d39565b90505f610b474283614d55565b905062ed4e0063ffffffff82161115610b7357604051637616640160e01b815260040160405180910390fd5b5f610b80845f015161307f565b90505f610b8d82846130c2565b9050866001600160801b0316816001600160801b03161015610bc257604051638199f5f360e01b815260040160405180910390fd5b8451610bce9082613185565b610c1d8a6040518060400160405280885f0151600f0b8152602001886040015163ffffffff168152506040518060400160405280895f0151600f0b81526020018863ffffffff168152506131f7565b6040518060800160405280865f01516001600160801b03168152602001836001600160801b031681526020018563ffffffff1681526020014263ffffffff1681525060665f8c81526020019081526020015f205f820151815f015f6101000a8154816001600160801b0302191690836001600160801b031602179055506020820151815f0160106101000a8154816001600160801b0302191690836001600160801b031602179055506040820151816001015f6101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160046101000a81548163ffffffff021916908363ffffffff16021790555090505089336001600160a01b03167f3032be442129e161b4ae1cdee94871a69de2c16ee2007f31fc209a715673455c8684604051610d6c92919063ffffffff9290921682526001600160801b0316602082015260400190565b60405180910390a3505050505050610d8360015f55565b50505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff165f81158015610dce5750825b90505f8267ffffffffffffffff166001148015610dea5750303b155b905081158015610df8575080155b15610e165760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610e4057845460ff60401b1916600160401b1785555b6001600160a01b0389161580610e5d57506001600160a01b038816155b15610e7b5760405163d92e233d60e01b815260040160405180910390fd5b610e858787613216565b610e8d613228565b610e95613238565b610e9e33613248565b610ea6613259565b606480546001600160a01b03808c166001600160a01b031992831617909255606f8054928b16929091169190911790555f805260686020527fad6f8124f6081c2622ab3a16acd47af73d52fe87b755c3f897263c58ba3fdbd880544263ffffffff90811663ffffffff194392909216600160201b029190911667ffffffffffffffff19909216919091171790558315610f7957845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b610f8e83826132ae565b610f99838383613341565b505050565b5f8163ffffffff165f03610fc557604051637616640160e01b815260040160405180910390fd5b5f838152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b90049091166060820152910361104057604051632254ea3d60e11b815260040160405180910390fd5b5f8382604001516110519190614d39565b90505f61105e4283614d55565b905062ed4e0063ffffffff8216111561108a57604051637616640160e01b815260040160405180910390fd5b5f611097845f015161307f565b90506110a381836130c2565b979650505050505050565b6110b6612fe2565b5f6110c082612fa9565b90506001600160a01b0381166110e857604051626f708760e21b815260040160405180910390fd5b6001600160a01b0381163314611111576040516359dc379f60e01b815260040160405180910390fd5b5f828152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b90049091166060820152910361118c57604051632254ea3d60e11b815260040160405180910390fd5b806040015163ffffffff164263ffffffff1610156111bd5760405163342ad40160e11b815260040160405180910390fd5b8051604080518082018252600f83900b81528184015163ffffffff166020808301919091525f8781526066909152918220828155600101805467ffffffffffffffff191690559061120d86611a14565b90505f670de0b6b3a764000061122f6001600160801b03808516908716614d71565b6112399190614d9c565b9050816001600160801b0316846001600160801b03168261125a9190614d9c565b1461127857604051630fc12e3560e11b815260040160405180910390fd5b5f61128b670de0b6b3a764000083614d9c565b90506001600160801b038111156112b55760405163162908e360e11b815260040160405180910390fd5b606e80548291905f906112d29084906001600160801b0316614daf565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555061131e888560405180604001604052805f600f0b81526020015f63ffffffff168152506131f7565b5f888152606a60205260409020805463ffffffff1916905561133f886133c4565b335f818152606760205260409020805460ff19811660ff9182165f1901909116179055606454611384916001600160a01b03909116906001600160801b0388166133fc565b6040516001600160801b0386168152889033907f8903a5b5d08a841e7f68438387f1da20c84dea756379ed37e633ff3854b99b849060200160405180910390a3505050505050506113d460015f55565b50565b6113df61345f565b6001600160a01b0381166114065760405163d92e233d60e01b815260040160405180910390fd5b606d80546001600160a01b0319166001600160a01b0392909216919091179055565b610f9983838360405180602001604052805f815250611c65565b61144a612fe2565b606f54600160a01b900460ff166114a05760405162461bcd60e51b81526020600482015260156024820152744e6f7420696e20656d657267656e6379206d6f646560581b60448201526064015b60405180910390fd5b336114aa826115db565b6001600160a01b0316146114d1576040516359dc379f60e01b815260040160405180910390fd5b5f818152606660208181526040808420815160808101835281546001600160801b03808216808452600160801b909204168286015260018301805463ffffffff80821696850196909652600160201b810490951660608401528888529590945294905567ffffffffffffffff191690915561154b836133c4565b335f818152606760205260409020805460ff19811660ff9182165f1901909116179055606454611590916001600160a01b03909116906001600160801b0384166133fc565b6040516001600160801b0382168152839033907f4f27eb511b2a4633cfb633ac1c4a99b4c298ca6488b29ec26f3504a5927f67289060200160405180910390a350506113d460015f55565b5f61088c82612f2c565b5f5f5160206151835f395f51905f526001600160a01b03831661161d576040516322718ad960e21b81525f6004820152602401611497565b6001600160a01b039092165f908152600390920160205250604090205490565b61164561345f565b61164e5f6134ba565b565b61165861345f565b6001600160a01b03811661167f5760405163d92e233d60e01b815260040160405180910390fd5b6065546001600160a01b0316156116d85760405162461bcd60e51b815260206004820152601760248201527f4469737472696275746f7220616c7265616479207365740000000000000000006044820152606401611497565b606580546001600160a01b0319166001600160a01b0392909216919091179055565b61170261345f565b606554600160a01b900463ffffffff1681111561172b5750606554600160a01b900463ffffffff165b815b81811015610f99575f61173f82612fa9565b6001600160a01b031614611a0c575f81815260666020908152604091829020825160808101845281546001600160801b03808216808452600160801b909204169382019390935260019091015463ffffffff80821694830194909452600160201b9004909216606083015215806117c65750806040015163ffffffff164263ffffffff1610155b156117d15750611a0c565b80516001600160801b03165f62ed4e006117f3670de0b6b3a764000084614d71565b6117fd9190614d9c565b90506001600160801b0381111561181657505050611a0c565b602083015181906001600160801b038083169116036118385750505050611a0c565b5f4285604001516118499190614d55565b90505f670de0b6b3a764000061186e63ffffffff84166001600160801b038616614d71565b6118789190614d9c565b90505f670de0b6b3a764000061189a62ed4e006001600160801b038716614d71565b6118a49190614d9c565b6118be670de0b6b3a7640000673782dace9d900000614daf565b6118d1906001600160801b031684614d71565b6118db9190614d9c565b6118ed90670de0b6b3a7640000614dce565b9050673782dace9d90000081111561190a5750673782dace9d9000005b670de0b6b3a76400008110156119255750670de0b6b3a76400005b6119788860405180604001604052808a5f0151600f0b81526020018a6040015163ffffffff1681525060405180604001604052808b5f0151600f0b81526020018b6040015163ffffffff168152506131f7565b50506040805160808101825286516001600160801b03908116825293841660208083019182529783015163ffffffff908116838501908152428216606085019081525f8c81526066909b5294909920925191518616600160801b029190951617815595516001909601805491518416600160201b0267ffffffffffffffff1990921696909316959095179490941790555050505b60010161172d565b5f818152606660209081526040808320815160808101835281546001600160801b038082168352600160801b90910416938101939093526001015463ffffffff808216928401839052600160201b90910481166060840152421610611a835750670de0b6b3a764000092915050565b5f611a99670de0b6b3a764000062ed4e00614de1565b6001600160801b0316611abc670de0b6b3a7640000673782dace9d900000614daf565b8351611ad4916001600160801b039081169116614d71565b611ade9190614d9c565b90506001600160801b03811115611b085760405163162908e360e11b815260040160405180910390fd5b604082015181905f90611b1c904290614d55565b90505f611b3863ffffffff83166001600160801b038516614d71565b611b4a90670de0b6b3a7640000614dce565b9050673782dace9d9000006001600160801b0382161115611b795750673782dace9d9000009695505050505050565b670de0b6b3a76400006001600160801b0382161015611ba65750670de0b6b3a76400009695505050505050565b9695505050505050565b7f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930180546060915f5160206151835f395f51905f52916108b190614cc1565b60695463ffffffff9081165f90815260686020908152604080832081516080810183528154600f81810b8352600160801b909104900b938101939093526001015480851691830191909152600160201b9004909216606083015290611c53818461352a565b9392505050565b61095233838361363f565b611c6f84836132ae565b610d83848484846136ee565b611c83612fe2565b611c8b613039565b8080421115611cad57604051631ab7da6b60e01b815260040160405180910390fd5b6002831015611ccf5760405163162908e360e11b815260040160405180910390fd5b5f80805b85811015611dd85733611cfd888884818110611cf157611cf1614cf9565b905060200201356115db565b6001600160a01b031614611d24576040516359dc379f60e01b815260040160405180910390fd5b5f60665f898985818110611d3a57611d3a614cf9565b602090810292909201358352508181019290925260409081015f20815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b900490911660608201529150611dad9085614e0a565b93508263ffffffff16816040015163ffffffff161115611dcf57806040015192505b50600101611cd3565b505f611de44283614d55565b905062ed4e0063ffffffff82161115611e1057604051637616640160e01b815260040160405180910390fd5b5f62ed4e00611e2f670de0b6b3a7640000673782dace9d900000614daf565b6001600160801b0316856001600160801b0316611e4c9190614d71565b611e569190614d9c565b90506001600160801b03811115611e805760405163162908e360e11b815260040160405180910390fd5b6065805482915f91601490611ea190600160a01b900463ffffffff16614e29565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff169050611ed03382613706565b5f5b89811015611fbb575f8b8b83818110611eed57611eed614cf9565b602090810292909201355f818152606684526040808220815160808101835281546001600160801b038082168352600160801b909104168188015260019091015463ffffffff808216838501908152600160201b90920481166060840152835180850185528351600f0b815291511681880152825180840190935283835295820192909252919450929150611f8590849083906131f7565b5f838152606660205260408120908155600101805467ffffffffffffffff19169055611fb0836133c4565b505050600101611ed2565b50604080518082018252600f88900b815263ffffffff871660208083019190915282518084019093525f8084529083015290611ff9908390836131f7565b6040518060800160405280886001600160801b03168152602001846001600160801b031681526020018763ffffffff1681526020014263ffffffff1681525060665f8481526020019081526020015f205f820151815f015f6101000a8154816001600160801b0302191690836001600160801b031602179055506020820151815f0160106101000a8154816001600160801b0302191690836001600160801b031602179055506040820151816001015f6101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055509050508a8a905060675f336001600160a01b03166001600160a01b031681526020019081526020015f205f9054906101000a900460ff160360010160675f336001600160a01b03166001600160a01b031681526020019081526020015f205f6101000a81548160ff021916908360ff16021790555081336001600160a01b03167fdbd81f1b10e6f1395ede56cabac59119f8be0cb5ca3ef0ca44f859782893495489896040516121b79291906001600160801b0392909216825263ffffffff16602082015260400190565b60405180910390a35050505050505050610f9960015f55565b6121d8612fe2565b6121e0613039565b818042111561220257604051631ab7da6b60e01b815260040160405180910390fd5b3261220c866115db565b6001600160a01b031614612233576040516359dc379f60e01b815260040160405180910390fd5b836001600160801b03165f0361225c5760405163162908e360e11b815260040160405180910390fd5b5f858152606660209081526040808320815160808101835281546001600160801b03808216808452600160801b909204169482019490945260019091015463ffffffff80821693830193909352600160201b9004909116606082015291036122d757604051632254ea3d60e11b815260040160405180910390fd5b806040015163ffffffff164263ffffffff1610612307576040516307b7d7dd60e51b815260040160405180910390fd5b80515f90612316908790614e0a565b90505f6123228261307f565b90505f4284604001516123359190614d55565b90505f61235163ffffffff83166001600160801b038516614d71565b61236390670de0b6b3a7640000614dce565b9050673782dace9d9000006001600160801b038216111561239757604051638f651fb760e01b815260040160405180910390fd5b866001600160801b0316816001600160801b031610156123ca57604051638199f5f360e01b815260040160405180910390fd5b6064546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015612410573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124349190614e4d565b606454909150612458906001600160a01b031633306001600160801b038e1661371f565b61246b6001600160801b038b1682614dce565b6064546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156124b1573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124d59190614e4d565b146124f3576040516312171d8360e31b815260040160405180910390fd5b6124fd8a83613185565b61254d8b6040518060400160405280895f0151600f0b8152602001896040015163ffffffff16815250604051806040016040528089600f0b81526020018a6040015163ffffffff168152506131f7565b6040518060800160405280866001600160801b03168152602001856001600160801b03168152602001876040015163ffffffff1681526020014263ffffffff1681525060665f8d81526020019081526020015f205f820151815f015f6101000a8154816001600160801b0302191690836001600160801b031602179055506020820151815f0160106101000a8154816001600160801b0302191690836001600160801b031602179055506040820151816001015f6101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160046101000a81548163ffffffff021916908363ffffffff1602179055509050508a336001600160a01b03167f1381e2f7d0d4b71a58d34dc3db2051dd52769766e65eabf380c9b4ea93f0890b8c88866040516126a3939291906001600160801b0393841681529183166020830152909116604082015260600190565b60405180910390a350505050505050610d8360015f55565b6126c361345f565b606f805460ff60a01b1916600160a01b1790556126de613259565b606f546040516001600160a01b0390911681527fc0a1c7e9f05b4d536e1ff8606bae9b847cdb43ef4a9b2d7a503a88cee08dccdb906020015b60405180910390a1565b60605f61272d83612fa9565b6001600160a01b03160361275357604051626f708760e21b815260040160405180910390fd5b606d546001600160a01b031661277c576040516338a69c8d60e21b815260040160405180910390fd5b606d54604051602481018490525f9182916001600160a01b039091169060440160408051601f198184030181529181526020820180516001600160e01b031663c87b56dd60e01b179052516127d19190614e64565b5f60405180830381855afa9150503d805f8114612809576040519150601f19603f3d011682016040523d82523d5f602084013e61280e565b606091505b5091509150816128585760405162461bcd60e51b8152602060048201526015602482015274105c9d081c1c9bde1e4818d85b1b0819985a5b1959605a1b6044820152606401611497565b8080602001905181019061286c9190614e7a565b949350505050565b5f63ffffffff82161580612890575062ed4e0063ffffffff8316115b156128ae57604051637616640160e01b815260040160405180910390fd5b826001600160801b03165f036128d75760405163162908e360e11b815260040160405180910390fd5b5f6128e18461307f565b905061286c81846130c2565b5f828152606a602052604081205463ffffffff16808203612911575f91505061088c565b604080516080810182525f808252602082018190529181018290526060810191909152815b60018163ffffffff1610612a2d575f868152606b6020908152604080832063ffffffff80861685529083529281902081516080810183528154600f81810b8352600160801b909104900b9381019390935260010154808416918301829052600160201b90048316606083015290935090861610612a1b575f8260400151866129be9190614d55565b63ffffffff169050670de0b6b3a76400008184602001516129df9190614eef565b6129e99190614f0e565b83516129f59190614f4a565b600f0b8084525f1315612a06575f83525b5050516001600160801b0316915061088c9050565b80612a2581614f77565b915050612936565b505f95945050505050565b606d545f90819063ffffffff600160a01b909104811690841611612a5c5782612a76565b606d54612a7690600160a01b900463ffffffff1684614d55565b90505f62ed4e00612a97670de0b6b3a7640000673782dace9d900000614daf565b6001600160801b0316866001600160801b0316612ab49190614d71565b612abe9190614d9c565b905080612ada63ffffffff84166001600160801b038316614d71565b611ba690670de0b6b3a7640000614dce565b5f612af5612fe2565b612afd613039565b8280421115612b1f57604051631ab7da6b60e01b815260040160405180910390fd5b856001600160801b03165f03612b485760405163162908e360e11b815260040160405180910390fd5b63ffffffff85161580612b63575062ed4e0063ffffffff8616115b15612b8157604051637616640160e01b815260040160405180910390fd5b335f90815260676020526040902054606460ff90911610612bb55760405163133cbc4f60e01b815260040160405180910390fd5b5f612bc08642614d39565b90505f5f612bcf898988613757565b915091505f60405180604001604052808b600f0b81526020018563ffffffff168152509050612c1c5f60405180604001604052805f600f0b81526020015f63ffffffff16815250836131f7565b6064546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015612c62573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c869190614e4d565b606454909150612caa906001600160a01b031633306001600160801b038f1661371f565b612cbd6001600160801b038c1682614dce565b6064546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015612d03573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d279190614e4d565b14612d45576040516312171d8360e31b815260040160405180910390fd5b60658054600163ffffffff600160a01b80840482168381019092160263ffffffff60a01b1990931692909217909255335f818152606760205260409020805460ff80821690950190941660ff19909416939093179092559750612da89088613706565b604080516080810182526001600160801b03808e168252868116602080840191825263ffffffff808b16858701908152428216606087019081525f8f8152606690945296909220945192518416600160801b0292909316919091178355516001909201805493518216600160201b0267ffffffffffffffff199094169290911691909117919091179055612e3c8b84613185565b604080516001600160801b038d16815263ffffffff87166020820152889133917fdbd81f1b10e6f1395ede56cabac59119f8be0cb5ca3ef0ca44f8597828934954910160405180910390a350505050505061286c60015f55565b6001600160a01b039182165f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab00793056020908152604080832093909416825291909152205460ff1690565b612eea61345f565b6001600160a01b038116612f1357604051631e4fbdf760e01b81525f6004820152602401611497565b6113d4816134ba565b612f2461345f565b61164e6138b1565b5f5f612f3783612fa9565b90506001600160a01b03811661088c57604051637e27328960e01b815260048101849052602401611497565b5f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930460205260409020546001600160a01b031690565b610f9983838360016138ea565b5f9081527f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab007930260205260409020546001600160a01b031690565b60025f54036130335760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611497565b60025f55565b60325460ff161561164e5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401611497565b5f6001600160801b0382168161309862ed4e0083614d9c565b90506001600160801b03811115611c535760405163162908e360e11b815260040160405180910390fd5b5f806130dd63ffffffff84166001600160801b038616614d71565b90505f6130f662ed4e006001600160801b038716614d71565b613110670de0b6b3a7640000673782dace9d900000614daf565b613123906001600160801b031684614d71565b61312d9190614d9c565b61313f90670de0b6b3a7640000614dce565b9050673782dace9d90000081111561316357673782dace9d9000009250505061088c565b670de0b6b3a764000081101561286c57670de0b6b3a76400009250505061088c565b5f670de0b6b3a76400006131a56001600160801b03848116908616614d71565b6131af9190614d9c565b606e805491925082915f906131ce9084906001600160801b0316614e0a565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550505050565b6131ff6139fd565b8215610f9957610f99838383613b6f565b60015f55565b61321e613db5565b6109528282613dfe565b613230613db5565b61164e613e2e565b613240613db5565b61164e613e36565b613250613db5565b6113d481613e4a565b613261613039565b6032805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586132963390565b6040516001600160a01b039091168152602001612717565b6001600160a01b038216158015906132d057506065546001600160a01b031615155b156109525760655460405163379607f560e01b8152600481018390526001600160a01b039091169063379607f5906024016020604051808303815f875af115801561331d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f999190614e4d565b6001600160a01b03821661336a57604051633250574960e11b81525f6004820152602401611497565b5f613376838333613e52565b9050836001600160a01b0316816001600160a01b031614610d83576040516364283d7b60e01b81526001600160a01b0380861660048301526024820184905282166044820152606401611497565b5f6133d05f835f613e52565b90506001600160a01b03811661095257604051637e27328960e01b815260048101839052602401611497565b6040516001600160a01b038316602482015260448101829052610f9990849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613f54565b336134917f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b03161461164e5760405163118cdaa760e01b8152336004820152602401611497565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f5f8390505f62093a808083604001516135449190614f95565b61354e9190614fbc565b90505f5b60ff81101561361a5761356862093a8083614d39565b91505f63ffffffff80871690841611156135845785925061359e565b5063ffffffff82165f908152606c6020526040902054600f0b5b60408401516135ad9084614d55565b63ffffffff1684602001516135c29190614eef565b845185906135d1908390614f4a565b600f0b90525063ffffffff808716908416036135ed575061361a565b80846020018181516135ff9190614fdb565b600f0b9052505063ffffffff82166040840152600101613552565b505f825f0151600f0b121561362d575f82525b50516001600160801b03169392505050565b5f5160206151835f395f51905f526001600160a01b03831661367f57604051630b61174360e31b81526001600160a01b0384166004820152602401611497565b6001600160a01b038481165f818152600584016020908152604080832094881680845294825291829020805460ff191687151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a350505050565b6136f9848484610f84565b610d833385858585614027565b610952828260405180602001604052805f81525061414f565b6040516001600160a01b0380851660248301528316604482015260648101829052610d839085906323b872dd60e01b90608401613428565b5f8080613775670de0b6b3a76400006001600160801b038816614d9c565b90505f613792670de0b6b3a7640000673782dace9d900000614daf565b6001600160801b031690505f6137b3670de0b6b3a764000062ed4e00614de1565b6001600160801b03166137c68385614d71565b6137d09190614d9c565b90506001600160801b038111156137fa5760405163162908e360e11b815260040160405180910390fd5b9350835f670de0b6b3a764000061382063ffffffff8a166001600160801b038516614d71565b61382a9190614d9c565b905061383e81670de0b6b3a7640000614dce565b9450673782dace9d9000006001600160801b038616111561387257604051638f651fb760e01b815260040160405180910390fd5b866001600160801b0316856001600160801b031610156138a557604051638199f5f360e01b815260040160405180910390fd5b50505050935093915050565b6138b9614166565b6032805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33613296565b5f5160206151835f395f51905f52818061390c57506001600160a01b03831615155b156139cd575f61391b85612f2c565b90506001600160a01b038416158015906139475750836001600160a01b0316816001600160a01b031614155b801561395a57506139588185612e96565b155b156139835760405163a9fbf51f60e01b81526001600160a01b0385166004820152602401611497565b82156139cb5784866001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5f93845260040160205250506040902080546001600160a01b0319166001600160a01b0392909216919091179055565b60695463ffffffff16613a2f604080516080810182525f80825260208201819052918101829052606081019190915290565b63ffffffff821615613aa85760685f613a49600185614d55565b63ffffffff908116825260208083019390935260409182015f2082516080810184528154600f81810b8352600160801b909104900b948101949094526001015480821692840192909252600160201b9091041660608201529050613ad5565b50604080516080810182525f808252602082015263ffffffff428116928201929092524390911660608201525b60408101515f63ffffffff808316429091161115613b36576040830151613b029063ffffffff1642615008565b6060840151613b179063ffffffff1643615008565b613b2990670de0b6b3a7640000614d71565b613b339190614d9c565b90505b613b42838383876141af565b9250613b4f846001614d39565b6069805463ffffffff191663ffffffff9290921691909117905550505050565b604080516080810182525f808252602082018190529181018290526060810191909152604080516080810182525f8082526020820181905291810182905260608101919091524263ffffffff16846020015163ffffffff16118015613bd957505f845f0151600f0b135b15613c4b57835162ed4e0090613bf890670de0b6b3a764000090614eef565b613c029190614f0e565b600f0b602080840191909152840151670de0b6b3a764000090613c26904290614d55565b63ffffffff168360200151613c3b9190614eef565b613c459190614f0e565b600f0b82525b4263ffffffff16836020015163ffffffff16118015613c6f57505f835f0151600f0b135b15613ce157825162ed4e0090613c8e90670de0b6b3a764000090614eef565b613c989190614f0e565b600f0b602080830191909152830151670de0b6b3a764000090613cbc904290614d55565b63ffffffff168260200151613cd19190614eef565b613cdb9190614f0e565b600f0b81525b613cf58484846020015184602001516143b4565b5f858152606a6020526040812054613d149063ffffffff166001614d39565b5f878152606a60209081526040808320805463ffffffff95861663ffffffff199091168117909155428516878301908152438616606089019081529b8552606b84528285209185529083529220855195909101516001600160801b03908116600160801b02951694909417845551600193909301805497518216600160201b0267ffffffffffffffff19909816939091169290921795909517905550505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661164e57604051631afcd79f60e31b815260040160405180910390fd5b613e06613db5565b5f5160206151835f395f51905f5280613e1f848261505f565b5060018101610d83838261505f565b613210613db5565b613e3e613db5565b6032805460ff19169055565b612eea613db5565b5f5f5160206151835f395f51905f5281613e6b85612fa9565b90506001600160a01b03841615613e8757613e878185876144ef565b6001600160a01b03811615613ec357613ea25f865f5f6138ea565b6001600160a01b0381165f908152600383016020526040902080545f190190555b6001600160a01b03861615613ef3576001600160a01b0386165f9081526003830160205260409020805460010190555b5f85815260028301602052604080822080546001600160a01b0319166001600160a01b038a811691821790925591518893918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a495945050505050565b5f613fa8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166145539092919063ffffffff16565b905080515f1480613fc8575080806020019051810190613fc8919061511a565b610f995760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611497565b6001600160a01b0383163b1561414857604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290614069908890889087908790600401615135565b6020604051808303815f875af19250505080156140a3575060408051601f3d908101601f191682019092526140a091810190615167565b60015b61410a573d8080156140d0576040519150601f19603f3d011682016040523d82523d5f602084013e6140d5565b606091505b5080515f0361410257604051633250574960e11b81526001600160a01b0385166004820152602401611497565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b1461414657604051633250574960e11b81526001600160a01b0385166004820152602401611497565b505b5050505050565b6141598383614561565b610f99335f858585614027565b60325460ff1661164e5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401611497565b604080516080810182525f808252602082018190529181018290526060810191909152845f62093a806141e28188614f95565b6141ec9190614fbc565b90505f5b60ff8110156143a85761420662093a8083614d39565b91505f63ffffffff42811690841611156142225742925061423c565b5063ffffffff82165f908152606c6020526040902054600f0b5b6142468884614d55565b63ffffffff16896020015161425b9190614eef565b89518a9061426a908390614f4a565b600f0b905250602089018051829190614284908390614fdb565b600f0b90525063ffffffff83166040808b0191909152840151670de0b6b3a7640000906142b19085614d55565b6142ca9063ffffffff166001600160801b038a16614d71565b6142d49190614d9c565b846060015163ffffffff166142e99190614dce565b63ffffffff90811660608b015242811690841603614313575063ffffffff431660608901526143a8565b8860685f846143238a6001614d39565b61432d9190614d39565b63ffffffff908116825260208083019390935260409182015f208451938501516001600160801b03908116600160801b02941693909317835590830151600190920180546060909401518216600160201b0267ffffffffffffffff1990941692909116919091179190911790555090955085906001016141f0565b50959695505050505050565b4263ffffffff16846020015163ffffffff1611156144555760208085015163ffffffff165f908152606c9091526040902054600f0b6143f38382614fdb565b9050846020015163ffffffff16846020015163ffffffff160361441d5761441a8282614f4a565b90505b60208581015163ffffffff165f908152606c9091526040902080546001600160801b0319166001600160801b03929092169190911790555b4263ffffffff16836020015163ffffffff161115610d8357836020015163ffffffff16836020015163ffffffff161115610d835760208084015163ffffffff165f908152606c9091526040902054600f0b6144b08282614f4a565b60208086015163ffffffff165f908152606c9091526040902080546001600160801b039092166001600160801b03199092169190911790555050505050565b6144fa8383836145c2565b610f99576001600160a01b03831661452857604051637e27328960e01b815260048101829052602401611497565b60405163177e802f60e01b81526001600160a01b038316600482015260248101829052604401611497565b606061286c84845f85614626565b6001600160a01b03821661458a57604051633250574960e11b81525f6004820152602401611497565b5f61459683835f613e52565b90506001600160a01b03811615610f99576040516339e3563760e11b81525f6004820152602401611497565b5f6001600160a01b0383161580159061286c5750826001600160a01b0316846001600160a01b031614806145fb57506145fb8484612e96565b8061286c5750826001600160a01b031661461483612f63565b6001600160a01b031614949350505050565b6060824710156146875760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401611497565b5f5f866001600160a01b031685876040516146a29190614e64565b5f6040518083038185875af1925050503d805f81146146dc576040519150601f19603f3d011682016040523d82523d5f602084013e6146e1565b606091505b50915091506110a3878383876060831561475b5782515f03614754576001600160a01b0385163b6147545760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611497565b508161286c565b61286c83838151156147705781518083602001fd5b8060405162461bcd60e51b815260040161149791906147e8565b6001600160e01b0319811681146113d4575f5ffd5b5f602082840312156147af575f5ffd5b8135611c538161478a565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611c5360208301846147ba565b5f6020828403121561480a575f5ffd5b5035919050565b80356001600160a01b0381168114614827575f5ffd5b919050565b5f5f6040838503121561483d575f5ffd5b61484683614811565b946020939093013593505050565b5f60208284031215614864575f5ffd5b611c5382614811565b602080825282518282018190525f918401906040840190835b818110156148a4578351835260209384019390920191600101614886565b509095945050505050565b803563ffffffff81168114614827575f5ffd5b5f5f604083850312156148d3575f5ffd5b823591506148e3602084016148af565b90509250929050565b80356001600160801b0381168114614827575f5ffd5b5f5f5f5f60808587031215614915575f5ffd5b84359350614925602086016148af565b92506040850135915061493a606086016148ec565b905092959194509250565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561498257614982614945565b604052919050565b5f67ffffffffffffffff8211156149a3576149a3614945565b50601f01601f191660200190565b5f6149c36149be8461498a565b614959565b90508281528383830111156149d6575f5ffd5b828260208301375f602084830101529392505050565b5f82601f8301126149fb575f5ffd5b611c53838335602085016149b1565b5f5f5f5f60808587031215614a1d575f5ffd5b614a2685614811565b9350614a3460208601614811565b9250604085013567ffffffffffffffff811115614a4f575f5ffd5b614a5b878288016149ec565b925050606085013567ffffffffffffffff811115614a77575f5ffd5b614a83878288016149ec565b91505092959194509250565b5f5f5f60608486031215614aa1575f5ffd5b614aaa84614811565b9250614ab860208501614811565b929592945050506040919091013590565b5f60208284031215614ad9575f5ffd5b611c53826148af565b5f5f60408385031215614af3575f5ffd5b50508035926020909101359150565b80151581146113d4575f5ffd5b5f5f60408385031215614b20575f5ffd5b614b2983614811565b91506020830135614b3981614b02565b809150509250929050565b5f5f5f5f60808587031215614b57575f5ffd5b614b6085614811565b9350614b6e60208601614811565b925060408501359150606085013567ffffffffffffffff811115614b90575f5ffd5b8501601f81018713614ba0575f5ffd5b614a83878235602084016149b1565b5f5f5f60408486031215614bc1575f5ffd5b833567ffffffffffffffff811115614bd7575f5ffd5b8401601f81018613614be7575f5ffd5b803567ffffffffffffffff811115614bfd575f5ffd5b8660208260051b8401011115614c11575f5ffd5b6020918201979096509401359392505050565b5f5f5f5f60808587031215614c37575f5ffd5b84359350614925602086016148ec565b5f5f60408385031215614c58575f5ffd5b614c61836148ec565b91506148e3602084016148af565b5f5f5f5f60808587031215614c82575f5ffd5b614c8b856148ec565b9350614925602086016148af565b5f5f60408385031215614caa575f5ffd5b614cb383614811565b91506148e360208401614811565b600181811c90821680614cd557607f821691505b602082108103614cf357634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f60018201614d3257614d32614d0d565b5060010190565b63ffffffff818116838216019081111561088c5761088c614d0d565b63ffffffff828116828216039081111561088c5761088c614d0d565b808202811582820484141761088c5761088c614d0d565b634e487b7160e01b5f52601260045260245ffd5b5f82614daa57614daa614d88565b500490565b6001600160801b03828116828216039081111561088c5761088c614d0d565b8082018082111561088c5761088c614d0d565b6001600160801b038181168382160290811690818114614e0357614e03614d0d565b5092915050565b6001600160801b03818116838216019081111561088c5761088c614d0d565b5f63ffffffff821663ffffffff8103614e4457614e44614d0d565b60010192915050565b5f60208284031215614e5d575f5ffd5b5051919050565b5f82518060208501845e5f920191825250919050565b5f60208284031215614e8a575f5ffd5b815167ffffffffffffffff811115614ea0575f5ffd5b8201601f81018413614eb0575f5ffd5b8051614ebe6149be8261498a565b818152856020838501011115614ed2575f5ffd5b8160208401602083015e5f91810160200191909152949350505050565b5f82600f0b82600f0b0280600f0b9150808214614e0357614e03614d0d565b5f81600f0b83600f0b80614f2457614f24614d88565b60016001607f1b031982145f1982141615614f4157614f41614d0d565b90059392505050565b600f82810b9082900b0360016001607f1b0319811260016001607f1b038213171561088c5761088c614d0d565b5f63ffffffff821680614f8c57614f8c614d0d565b5f190192915050565b5f63ffffffff831680614faa57614faa614d88565b8063ffffffff84160491505092915050565b63ffffffff8181168382160290811690818114614e0357614e03614d0d565b600f81810b9083900b0160016001607f1b03811360016001607f1b03198212171561088c5761088c614d0d565b8181038181111561088c5761088c614d0d565b601f821115610f9957805f5260205f20601f840160051c810160208510156150405750805b601f840160051c820191505b81811015614148575f815560010161504c565b815167ffffffffffffffff81111561507957615079614945565b61508d816150878454614cc1565b8461501b565b6020601f8211600181146150bf575f83156150a85750848201515b5f19600385901b1c1916600184901b178455614148565b5f84815260208120601f198516915b828110156150ee57878501518255602094850194600190920191016150ce565b508482101561510b57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f6020828403121561512a575f5ffd5b8151611c5381614b02565b6001600160a01b03858116825284166020820152604081018390526080606082018190525f90611ba6908301846147ba565b5f60208284031215615177575f5ffd5b8151611c538161478a56fe80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079300a2646970667358221220733f3b755285dd6711ae30379e134c2d199d910fdbd061a873059f6f8cfcd57564736f6c634300081b0033
Deployed Bytecode Sourcemap
151723:30912:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101704:316;;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;101704:316:0;;;;;;;;102604:149;;;:::i;:::-;;;;;;;:::i;103892:158::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1506:32:1;;;1488:51;;1476:2;1461:18;103892:158:0;1342:203:1;103711:115:0;;;;;;:::i;:::-;;:::i;:::-;;178102:104;178186:12;;-1:-1:-1;;;;;178186:12:0;178102:104;;178597:562;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;153886:68::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;153886:68:0;;;;;;;;;;-1:-1:-1;;;153886: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;153886:68:0;3545:449:1;167745:1650:0;;;;;;:::i;:::-;;:::i;155457:736::-;;;;;;:::i;:::-;;:::i;178214:96::-;178288:14;;-1:-1:-1;;;178288:14:0;;;;178214:96;;162591:191;;;;;;:::i;:::-;;:::i;179988:603::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;7099:47:1;;;7081:66;;7069:2;7054:18;179988:603:0;6935:218:1;178318:109:0;178399:20;;-1:-1:-1;;;;;178399:20:0;178318:109;;163028:1494;;;;;;:::i;:::-;;:::i;178443:146::-;;;;;;:::i;:::-;;:::i;105278:134::-;;;;;;:::i;:::-;;:::i;177286:585::-;;;;;;:::i;:::-;;:::i;154013:23::-;;;;;-1:-1:-1;;;;;154013:23:0;;;153961:45;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;7520:2:1;7509:22;;;;7491:41;;7479:2;7464:18;153961:45:0;7347:191:1;145967:86:0;146038:7;;;;145967:86;;102417:120;;;;;;:::i;:::-;;:::i;102084:271::-;;;;;;:::i;:::-;;:::i;:::-;;;7689:25:1;;;7677:2;7662:18;102084:271:0;7543:177:1;150262:103:0;;;:::i;156201:280::-;;;;;;:::i;:::-;;:::i;180599:2029::-;;;;;;:::i;:::-;;:::i;153612:46::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;153612:46:0;;;;-1:-1:-1;;;153612:46:0;;;;;;;;;-1:-1:-1;;;153612: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;153612:46:0;8076:503:1;156812:858:0;;;;;;:::i;:::-;;:::i;149527:147::-;148358:22;149658:8;-1:-1:-1;;;;;149658:8:0;149527:147;;153754:44;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;153754:44:0;;;;;;;;;;-1:-1:-1;;;153754:44:0;;;;;153805:19;;;;;;;;;;;;8758:10:1;8746:23;;;8728:42;;8716:2;8701:18;153805:19:0;8584:192:1;102822:153:0;;;:::i;171292:199::-;;;;;;:::i;:::-;;:::i;155182:45::-;;;;;;:::i;:::-;;;;;;;;;;;;;;177978:116;;;;;;:::i;:::-;-1:-1:-1;;;;;178066:20:0;178041:5;178066:20;;;:14;:20;;;;;;;;;177978:116;;;;8953:4:1;8941:17;;;8923:36;;8911:2;8896:18;177978:116:0;8781:184:1;104122:146:0;;;;;;:::i;:::-;;:::i;162790:226::-;;;;;;:::i;:::-;;:::i;173175:2544::-;;;;;;:::i;:::-;;:::i;153666:47::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;169408:1874;;;;;;:::i;:::-;;:::i;177106:172::-;;;:::i;179163:495::-;;;;;;:::i;:::-;;:::i;179662:322::-;;;;;;:::i;:::-;;:::i;175728:828::-;;;;;;:::i;:::-;;:::i;176564:506::-;;;;;;:::i;:::-;;:::i;165946:1791::-;;;;;;:::i;:::-;;:::i;153831:48::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;104339:213;;;;;;:::i;:::-;;:::i;150520:220::-;;;;;;:::i;:::-;;:::i;177879:68::-;;;:::i;101704:316::-;101817:4;-1:-1:-1;;;;;;101854:40:0;;-1:-1:-1;;;101854:40:0;;:105;;-1:-1:-1;;;;;;;101911:48:0;;-1:-1:-1;;;101911:48:0;101854:105;:158;;;-1:-1:-1;;;;;;;;;;99727:40:0;;;101976:36;101834:178;101704:316;-1:-1:-1;;101704:316:0:o;102604:149::-;-1:-1:-1;;;;;;;;;;;102731:14:0;;102649:13;;101087:21;;;102731:14;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102604:149;:::o;103892:158::-;103959:7;103979:22;103993:7;103979:13;:22::i;:::-;;104021:21;104034:7;104021:12;:21::i;103711:115::-;103783:35;103792:2;103796:7;25437:10;103783:8;:35::i;:::-;103711:115;;:::o;178597:562::-;-1:-1:-1;;;;;178710:21:0;;178696:11;178710:21;;;:14;:21;;;;;;178658:25;;178710:21;;;178753:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;178753:20:0;;178742:31;;178788:5;:10;;178797:1;178788:10;178784:31;;178800:15;178597:562;;;:::o;178784:31::-;178836:20;;178871:245;178897:12;;-1:-1:-1;;;178897:12:0;;;;178892:17;;178871:245;;;178952:5;-1:-1:-1;;;;;178936:21:0;:12;178945:2;178936:8;:12::i;:::-;-1:-1:-1;;;;;178936:21:0;;178932:173;;179003:2;178978:8;178987:12;178978:22;;;;;;;;:::i;:::-;;;;;;;;;;:27;179024:14;;;;:::i;:::-;;;;179077:5;179061:21;;:12;:21;179057:32;179084:5;179057:32;;178911:4;;178871:245;;;;179136:15;;178597:562;;;:::o;167745:1650::-;143037:21;:19;:21::i;:::-;145572:19:::1;:17;:19::i;:::-;167943:8:::2;156581;156563:15;:26;156559:56;;;156598:17;;-1:-1:-1::0;;;156598:17:0::2;;;;;;;;;;;156559:56;167988:10:::3;167968:16;167976:7:::0;167968::::3;:16::i;:::-;-1:-1:-1::0;;;;;167968:30:0::3;;167964:58;;168007:15;;-1:-1:-1::0;;;168007:15:0::3;;;;;;;;;;;167964:58;168043:24;168070:15:::0;;;:6:::3;:15;::::0;;;;;;;168043:42;;::::3;::::0;::::3;::::0;;;;-1:-1:-1;;;;;168043:42:0;;::::3;::::0;;;-1:-1:-1;;;168043:42:0;;::::3;;::::0;;::::3;::::0;;;;;;;::::3;::::0;::::3;::::0;;::::3;::::0;;;;;;;-1:-1:-1;;;168043:42:0;::::3;::::0;;::::3;::::0;;;;;168100:16;168096:44:::3;;168125:15;;-1:-1:-1::0;;;168125:15:0::3;;;;;;;;;;;168096:44;168196:17;168231:18;168216:4;:12;;;:33;;;;:::i;:::-;168196:53:::0;-1:-1:-1;168260:29:0::3;168292:36;168312:15;168196:53:::0;168292:36:::3;:::i;:::-;168260:68:::0;-1:-1:-1;153054:8:0::3;168343:32;::::0;::::3;;168339:62;;;168384:17;;-1:-1:-1::0;;;168384:17:0::3;;;;;;;;;;;168339:62;168489:16;168508:31;168527:4;:11;;;168508:18;:31::i;:::-;168489:50;;168550:18;168571:54;168592:8;168602:22;168571:20;:54::i;:::-;168550:75;;168653:13;-1:-1:-1::0;;;;;168640:26:0::3;:10;-1:-1:-1::0;;;;;168640:26:0::3;;168636:57;;;168675:18;;-1:-1:-1::0;;;168675:18:0::3;;;;;;;;;;;168636:57;168785:11:::0;;168749:83:::3;::::0;168811:10;168749:21:::3;:83::i;:::-;168876:186;168902:7;168924:57;;;;;;;;168953:4;:11;;;168924:57;;;;;;168968:4;:12;;;168924:57;;;;::::0;168996:55:::3;;;;;;;;169025:4;:11;;;168996:55;;;;;;169040:10;168996:55;;;;::::0;168876:11:::3;:186::i;:::-;169131:173;;;;;;;;169167:4;:11;;;-1:-1:-1::0;;;;;169131:173:0::3;;;;;169284:8;-1:-1:-1::0;;;;;169131:173:0::3;;;;;169202:10;169131:173;;;;;;169246:15;169131:173;;;;::::0;169113:6:::3;:15;169120:7;169113:15;;;;;;;;;;;:191;;;;;;;;;;;;;-1:-1:-1::0;;;;;169113:191:0::3;;;;;-1:-1:-1::0;;;;;169113:191:0::3;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;169113:191:0::3;;;;;-1:-1:-1::0;;;;;169113:191:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;169355:7;169343:10;-1:-1:-1::0;;;;;169330:57:0::3;;169364:10;169376;169330: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;169330:57:0::3;;;;;;;;167953:1442;;;;;145602:1:::2;143081:20:::0;142298:1;143601:7;:22;143418:213;143081:20;167745:1650;;;;:::o;155457:736::-;24565:21;19881:15;;-1:-1:-1;;;19881:15:0;;;;19880:16;;19928:14;;19734:30;20313:16;;:34;;;;;20333:14;20313:34;20293:54;;20358:17;20378:11;:16;;20393:1;20378:16;:50;;;;-1:-1:-1;20406:4:0;20398:25;:30;20378:50;20358:70;;20446:12;20445:13;:30;;;;;20463:12;20462:13;20445:30;20441:93;;;20499:23;;-1:-1:-1;;;20499:23:0;;;;;;;;;;;20441:93;20544:18;;-1:-1:-1;;20544:18:0;20561:1;20544:18;;;20573:69;;;;20608:22;;-1:-1:-1;;;;20608:22:0;-1:-1:-1;;;20608:22:0;;;20573:69;-1:-1:-1;;;;;155653:26:0;::::1;::::0;;:77:::1;;-1:-1:-1::0;;;;;;155699:31:0;::::1;::::0;155653:77:::1;155649:103;;;155739:13;;-1:-1:-1::0;;;155739:13:0::1;;;;;;;;;;;155649:103;155777:27;155791:4;155797:6;155777:13;:27::i;:::-;155815:24;:22;:24::i;:::-;155850:17;:15;:17::i;:::-;155878:26;155893:10;155878:14;:26::i;:::-;155917:8;:6;:8::i;:::-;155936:12;:46:::0;;-1:-1:-1;;;;;155936:46:0;;::::1;-1:-1:-1::0;;;;;;155936:46:0;;::::1;;::::0;;;155993:25:::1;:45:::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;155936:12:::1;156088:15:::0;;:12:::1;:15;::::0;:19;:42;;156169:15:::1;156088;156141:44:::0;;::::1;-1:-1:-1::0;;156117:12:0::1;156088:42:::0;;;::::1;-1:-1:-1::0;;;156088:42:0::1;156141:44:::0;;;;-1:-1:-1;;156141:44:0;;;;;;;::::1;::::0;;20664:104;;;;20699:23;;-1:-1:-1;;;;20699:23:0;;;20742:14;;-1:-1:-1;13944:50:1;;20742:14:0;;13932:2:1;13917:18;20742:14:0;;;;;;;20664:104;19666:1109;;;;;155457:736;;;;:::o;162591:191::-;162691:35;162712:4;162718:7;162691:20;:35::i;:::-;162737:36;162756:4;162761:2;162765:7;162737:18;:36::i;:::-;162591:191;;;:::o;179988:603::-;180092:7;180112:18;:23;;180134:1;180112:23;180108:53;;180144:17;;-1:-1:-1;;;180144:17:0;;;;;;;;;;;180108:53;180174:24;180201:15;;;:6;:15;;;;;;;;180174:42;;;;;;;;;-1:-1:-1;;;;;180174:42:0;;;;;;-1:-1:-1;;;180174:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;180174:42:0;;;;;;;;;;180227:16;180223:44;;180252:15;;-1:-1:-1;;;180252:15:0;;;;;;;;;;;180223:44;180280:17;180315:18;180300:4;:12;;;:33;;;;:::i;:::-;180280:53;-1:-1:-1;180340:24:0;180367:36;180387:15;180280:53;180367:36;:::i;:::-;180340:63;-1:-1:-1;153054:8:0;180414:27;;;;180410:57;;;180450:17;;-1:-1:-1;;;180450:17:0;;;;;;;;;;;180410:57;180480:13;180496:31;180515:4;:11;;;180496:18;:31::i;:::-;180480:47;;180541:46;180562:5;180569:17;180541:20;:46::i;:::-;180534:53;179988:603;-1:-1:-1;;;;;;;179988:603:0:o;163028:1494::-;143037:21;:19;:21::i;:::-;163096:13:::1;163112:17;163121:7;163112:8;:17::i;:::-;163096:33:::0;-1:-1:-1;;;;;;163144:19:0;::::1;163140:48;;163172:16;;-1:-1:-1::0;;;163172:16:0::1;;;;;;;;;;;163140:48;-1:-1:-1::0;;;;;163203:19:0;::::1;163212:10;163203:19;163199:47;;163231:15;;-1:-1:-1::0;;;163231:15:0::1;;;;;;;;;;;163199:47;163267:24;163294:15:::0;;;:6:::1;:15;::::0;;;;;;;163267:42;;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;;;163267:42:0;;::::1;::::0;;;-1:-1:-1;;;163267:42:0;;::::1;;::::0;;::::1;::::0;;;;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;163267:42:0;::::1;::::0;;::::1;::::0;;;;;163324:16;163320:44:::1;;163349:15;;-1:-1:-1::0;;;163349:15:0::1;;;;;;;;;;;163320:44;163405:4;:12;;;163379:38;;163386:15;163379:38;;;163375:67;;;163426:16;;-1:-1:-1::0;;;163426:16:0::1;;;;;;;;;;;163375:67;163480:11:::0;;163543:104:::1;::::0;;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;163623:12;;::::1;::::0;163543:104:::1;;;::::0;;::::1;::::0;;;;163463:14:::1;163667:15:::0;;;:6:::1;:15:::0;;;;;;163660:22;;;;::::1;::::0;;-1:-1:-1;;163660:22:0;;;163543:104;163724:29:::1;163674:7:::0;163724:20:::1;:29::i;:::-;163703:50:::0;-1:-1:-1;163764:22:0::1;153260:4;163790:37;-1:-1:-1::0;;;;;163808:19:0;;::::1;::::0;163790:15;::::1;:37;:::i;:::-;163789:51;;;;:::i;:::-;163764:76;;163899:10;-1:-1:-1::0;;;;;163891:19:0::1;163880:6;-1:-1:-1::0;;;;;163872:15:0::1;163855:14;:32;;;;:::i;:::-;:55;163851:85;;163919:17;;-1:-1:-1::0;;;163919:17:0::1;;;;;;;;;;;163851:85;163947:30;163980:26;153260:4;163980:14:::0;:26:::1;:::i;:::-;163947:59:::0;-1:-1:-1;;;;;;164021:42:0;::::1;164017:70;;;164072:15;;-1:-1:-1::0;;;164072:15:0::1;;;;;;;;;;;164017:70;164098:20;:55:::0;;164130:22;;164098:20;::::1;::::0;:55:::1;::::0;164130:22;;-1:-1:-1;;;;;164098:55:0::1;;:::i;:::-;;;;;;;;-1:-1:-1::0;;;;;164098:55:0::1;;;;;-1:-1:-1::0;;;;;164098:55:0::1;;;;;;164174:50;164186:7;164195;164204:19;;;;;;;;164218:1;164204:19;;;;;;164221:1;164204:19;;;;::::0;164174:11:::1;:50::i;:::-;164252:23;::::0;;;:14:::1;:23;::::0;;;;164245:30;;-1:-1:-1;;164245:30:0::1;::::0;;164296:14:::1;164267:7:::0;164296:5:::1;:14::i;:::-;164361:10;164346:26;::::0;;;:14:::1;:26;::::0;;;;:28;;-1:-1:-1;;164346:28:0;::::1;;::::0;;::::1;-1:-1:-1::0;;164346:28:0;;;::::1;;::::0;;164406:12:::1;::::0;:45:::1;::::0;-1:-1:-1;;;;;164406:12:0;;::::1;::::0;-1:-1:-1;;;;;164406:45:0;::::1;:25;:45::i;:::-;164477:37;::::0;-1:-1:-1;;;;;7099:47:1;;7081:66;;164498:7:0;;164486:10:::1;::::0;164477:37:::1;::::0;7069:2:1;7054:18;164477:37:0::1;;;;;;;163085:1437;;;;;;;143081:20:::0;142298:1;143601:7;:22;143418:213;143081:20;163028:1494;:::o;178443:146::-;149413:13;:11;:13::i;:::-;-1:-1:-1;;;;;178513:23:0;::::1;178509:49;;178545:13;;-1:-1:-1::0;;;178545:13:0::1;;;;;;;;;;;178509:49;178565:8;:20:::0;;-1:-1:-1;;;;;;178565:20:0::1;-1:-1:-1::0;;;;;178565:20:0;;;::::1;::::0;;;::::1;::::0;;178443:146::o;105278:134::-;105365:39;105382:4;105388:2;105392:7;105365:39;;;;;;;;;;;;:16;:39::i;177286:585::-;143037:21;:19;:21::i;:::-;177371:14:::1;::::0;-1:-1:-1;;;177371:14:0;::::1;;;177363:48;;;::::0;-1:-1:-1;;;177363:48:0;;14885:2:1;177363: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;;177363:48:0::1;;;;;;;;;177446:10;177426:16;177434:7:::0;177426::::1;:16::i;:::-;-1:-1:-1::0;;;;;177426:30:0::1;;177422:58;;177465:15;;-1:-1:-1::0;;;177465:15:0::1;;;;;;;;;;;177422:58;177501:24;177528:15:::0;;;:6:::1;:15;::::0;;;;;;;177501:42;;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;;;177501:42:0;;::::1;::::0;;;-1:-1:-1;;;177501:42:0;;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;177501:42:0;::::1;::::0;;::::1;::::0;;;;177610:15;;;;;;;177603:22;;;-1:-1:-1;;177603:22:0;;;;177636:14:::1;177535:7:::0;177636:5:::1;:14::i;:::-;177701:10;177686:26;::::0;;;:14:::1;:26;::::0;;;;:28;;-1:-1:-1;;177686:28:0;::::1;;::::0;;::::1;-1:-1:-1::0;;177686:28:0;;;::::1;;::::0;;177746:12:::1;::::0;:45:::1;::::0;-1:-1:-1;;;;;177746:12:0;;::::1;::::0;-1:-1:-1;;;;;177746:45:0;::::1;:25;:45::i;:::-;177817:46;::::0;-1:-1:-1;;;;;7099:47:1;;7081:66;;177847:7:0;;177835:10:::1;::::0;177817:46:::1;::::0;7069:2:1;7054:18;177817:46:0::1;;;;;;;177352:519;;143081:20:::0;142298:1;143601:7;:22;143418:213;102417:120;102480:7;102507:22;102521:7;102507:13;:22::i;102084:271::-;102147:7;-1:-1:-1;;;;;;;;;;;;;;;;102227:19:0;;102223:89;;102270:30;;-1:-1:-1;;;102270:30:0;;102297:1;102270:30;;;1488:51:1;1461:18;;102270:30:0;1342:203:1;102223:89:0;-1:-1:-1;;;;;102329:18:0;;;;;;;:11;;;;:18;;-1:-1:-1;102329:18:0;;;;;102084:271::o;150262:103::-;149413:13;:11;:13::i;:::-;150327:30:::1;150354:1;150327:18;:30::i;:::-;150262:103::o:0;156201:280::-;149413:13;:11;:13::i;:::-;-1:-1:-1;;;;;156281:26:0;::::1;156277:52;;156316:13;;-1:-1:-1::0;;;156316:13:0::1;;;;;;;;;;;156277:52;156352:12;::::0;-1:-1:-1;;;;;156352:12:0::1;156344:35:::0;156340:74:::1;;156381:33;::::0;-1:-1:-1;;;156381:33:0;;15235:2:1;156381:33:0::1;::::0;::::1;15217:21:1::0;15274:2;15254:18;;;15247:30;15313:25;15293:18;;;15286:53;15356:18;;156381:33:0::1;15033:347:1::0;156340:74:0::1;156425:12;:48:::0;;-1:-1:-1;;;;;;156425:48:0::1;-1:-1:-1::0;;;;;156425:48:0;;;::::1;::::0;;;::::1;::::0;;156201:280::o;180599:2029::-;149413:13;:11;:13::i;:::-;180703:12:::1;::::0;-1:-1:-1;;;180703:12:0;::::1;;;180695:20:::0;::::1;180691:65;;;-1:-1:-1::0;180736:12:0::1;::::0;-1:-1:-1;;;180736:12:0;::::1;;;180691:65;180795:7:::0;180772:1853:::1;180814:5;180804:7;:15;180772:1853;;;180930:1;180901:17;180910:7:::0;180901:8:::1;:17::i;:::-;-1:-1:-1::0;;;;;180901:31:0::1;180897:45:::0;180934:8:::1;180897:45;180963:24;180990:15:::0;;;:6:::1;:15;::::0;;;;;;;;180963:42;;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;;;180963:42:0;;::::1;::::0;;;-1:-1:-1;;;180963:42:0;;::::1;;::::0;;::::1;::::0;;;;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;180963:42:0;::::1;::::0;;::::1;::::0;;;;181020:16;;:59:::1;;;181067:4;:12;;;181040:39;;181047:15;181040:39;;;;181020:59;181016:73;;;181081:8;;;181016:73;181186:11:::0;;-1:-1:-1;;;;;181178:20:0::1;181162:13;153054:8;181230:17;153260:4;181178:20:::0;181230:17:::1;:::i;:::-;181229:29;;;;:::i;:::-;181209:49:::0;-1:-1:-1;;;;;;181315:29:0;::::1;181311:43;;;181346:8;;;;;181311:43;181496:10;::::0;::::1;::::0;181416:9;;-1:-1:-1;;;;;181496:22:0;;::::1;::::0;::::1;::::0;181492:36:::1;;181520:8;;;;;;181492:36;181608:24;181657:15;181635:4;:12;;;:38;;;;:::i;:::-;181608:65:::0;-1:-1:-1;181684:12:0::1;153260:4;181700:37;;::::0;::::1;-1:-1:-1::0;;;;;181700:17:0;::::1;:37;:::i;:::-;181699:51;;;;:::i;:::-;181684:66:::0;-1:-1:-1;181806:18:0::1;153260:4;181907:27;153054:8;-1:-1:-1::0;;;;;181907:17:0;::::1;:27;:::i;:::-;:39;;;;:::i;:::-;181869:32;153212:4;153158;181869:32;:::i;:::-;181861:41;::::0;-1:-1:-1;;;;;181861:41:0::1;:4:::0;:41:::1;:::i;:::-;181860:87;;;;:::i;:::-;181827:121;::::0;153212:4:::1;181827:121;:::i;:::-;181806:142:::0;-1:-1:-1;153158:4:0::1;182013:27:::0;::::1;182009:60;;;-1:-1:-1::0;153158:4:0::1;182009:60;153212:4;182084:28:::0;::::1;182080:62;;;-1:-1:-1::0;153212:4:0::1;182080:62;182197:188;182223:7;182245:57;;;;;;;;182274:4;:11;;;182245:57;;;;;;182289:4;:12;;;182245:57;;;;::::0;182317::::1;;;;;;;;182346:4;:11;;;182317:57;;;;;;182361:4;:12;;;182317:57;;;;::::0;182197:11:::1;:188::i;:::-;-1:-1:-1::0;;182424:175:0::1;::::0;;::::1;::::0;::::1;::::0;;182460:11;;-1:-1:-1;;;;;182424:175:0;;::::1;::::0;;;;::::1;;::::0;;::::1;::::0;;;182495:12;;::::1;::::0;182424:175:::1;::::0;;::::1;::::0;;;;;;182541:15:::1;182424:175:::0;::::1;::::0;;;;;;-1:-1:-1;182406:15:0;;;:6:::1;:15:::0;;;;;;;:193;;;;;::::1;-1:-1:-1::0;;;182406:193:0::1;::::0;;;::::1;;::::0;;;;;;;::::1;::::0;;;;;::::1;-1:-1:-1::0;;;182406:193:0::1;-1:-1:-1::0;;182406:193:0;;;;;;::::1;::::0;;;;;;;::::1;::::0;;-1:-1:-1;;;180772:1853:0::1;180821:9;;180772:1853;;156812:858:::0;156880:7;156927:15;;;:6;:15;;;;;;;;156900:42;;;;;;;;;-1:-1:-1;;;;;156900:42:0;;;;;-1:-1:-1;;;156900:42:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;156900:42:0;;;;;;;;;156964:15;156957:39;;156953:67;;-1:-1:-1;153212:4:0;;156812:858;-1:-1:-1;;156812:858:0:o;156953:67::-;157103:17;157186:19;153260:4;153054:8;157186:19;:::i;:::-;-1:-1:-1;;;;;157123:83:0;157148:32;153212:4;153158;157148:32;:::i;:::-;157132:11;;157124:57;;-1:-1:-1;;;;;157124:57:0;;;;:20;:57;:::i;:::-;157123:83;;;;:::i;:::-;157103:103;-1:-1:-1;;;;;;157221:29:0;;157217:57;;;157259:15;;-1:-1:-1;;;157259:15:0;;;;;;;;;;;157217:57;157358:12;;;;157309:9;;157285:13;;157358:38;;157380:15;;157358:38;:::i;:::-;157340:56;-1:-1:-1;157407:18:0;157455:25;;;;-1:-1:-1;;;;;157455:14:0;;:25;:::i;:::-;157436:45;;153212:4;157436:45;:::i;:::-;157407:75;-1:-1:-1;153158:4:0;-1:-1:-1;;;;;157507:27:0;;;157503:54;;;-1:-1:-1;153158:4:0;;156812:858;-1:-1:-1;;;;;;156812:858:0:o;157503:54::-;153212:4;-1:-1:-1;;;;;157572:28:0;;;157568:56;;;-1:-1:-1;153212:4:0;;156812:858;-1:-1:-1;;;;;;156812:858:0:o;157568:56::-;157652:10;156812:858;-1:-1:-1;;;;;;156812:858:0:o;102822:153::-;102958:9;102951:16;;102869:13;;-1:-1:-1;;;;;;;;;;;101087:21:0;102951:16;;;:::i;171292:199::-;171419:5;;;;;;171361:7;171406:19;;;:12;:19;;;;;;;;171381:44;;;;;;;;;;;;;;;-1:-1:-1;;;171381:44:0;;;;;;;;;;;;171419:5;171381:44;;;;;;;;;;;;-1:-1:-1;;;171381:44:0;;;;;;;;;171361:7;171451:31;171381:44;171472:9;171451;:31::i;:::-;171436:47;171292:199;-1:-1:-1;;;171292:199:0:o;104122:146::-;104208:52;25437:10;104241:8;104251;104208:18;:52::i;162790:226::-;162914:35;162935:4;162941:7;162914:20;:35::i;:::-;162961:47;162984:4;162990:2;162994:7;163003:4;162961:22;:47::i;173175:2544::-;143037:21;:19;:21::i;:::-;145572:19:::1;:17;:19::i;:::-;173312:8:::2;156581;156563:15;:26;156559:56;;;156598:17;;-1:-1:-1::0;;;156598:17:0::2;;;;;;;;;;;156559:56;173355:1:::3;173337:19:::0;::::3;173333:47;;;173365:15;;-1:-1:-1::0;;;173365:15:0::3;;;;;;;;;;;173333:47;173401:19;::::0;;173536:376:::3;173556:19:::0;;::::3;173536:376;;;173625:10;173601:20;173609:8:::0;;173618:1;173609:11;;::::3;;;;;:::i;:::-;;;;;;;173601:7;:20::i;:::-;-1:-1:-1::0;;;;;173601:34:0::3;;173597:62;;173644:15;;-1:-1:-1::0;;;173644:15:0::3;;;;;;;;;;;173597:62;173688:24;173715:6;:19;173722:8;;173731:1;173722:11;;;;;;;:::i;:::-;;::::0;;::::3;::::0;;;::::3;;173715:19:::0;;-1:-1:-1;173715:19:0;;::::3;::::0;;;;;;;;-1:-1:-1;173715:19:0;173688:46;;::::3;::::0;::::3;::::0;;;;-1:-1:-1;;;;;173688:46:0;;::::3;::::0;;;-1:-1:-1;;;173688:46:0;;::::3;;::::0;;::::3;::::0;;;;;;;::::3;::::0;::::3;::::0;;::::3;::::0;;;;;;;-1:-1:-1;;;173688:46:0;::::3;::::0;;::::3;::::0;;;;;-1:-1:-1;173763:26:0::3;::::0;;::::3;:::i;:::-;;;173823:13;173808:28;;:4;:12;;;:28;;;173804:97;;;173873:4;:12;;;173857:28;;173804:97;-1:-1:-1::0;173577:3:0::3;;173536:376;;;-1:-1:-1::0;173971:24:0::3;173998:39;174021:15;173998:13:::0;:39:::3;:::i;:::-;173971:66:::0;-1:-1:-1;153054:8:0::3;174052:27;::::0;::::3;;174048:57;;;174088:17;;-1:-1:-1::0;;;174088:17:0::3;;;;;;;;;;;174048:57;174126:17;153054:8;174171:32;153212:4;153158;174171:32;:::i;:::-;-1:-1:-1::0;;;;;174147:57:0::3;174155:11;-1:-1:-1::0;;;;;174147:20:0::3;:57;;;;:::i;:::-;174146:69;;;;:::i;:::-;174126:89:::0;-1:-1:-1;;;;;;174230:29:0;::::3;174226:57;;;174268:15;;-1:-1:-1::0;;;174268:15:0::3;;;;;;;;;;;174226:57;174375:12;174373:14:::0;;174321:9;;174294:16:::3;::::0;174375:12:::3;::::0;174373:14:::3;::::0;-1:-1:-1;;;174373:14:0;::::3;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;174352:35;;;;174398:33;174408:10;174420;174398:9;:33::i;:::-;174506:9;174501:512;174521:19:::0;;::::3;174501:512;;;174562:15;174580:8;;174589:1;174580:11;;;;;;;:::i;:::-;;::::0;;::::3;::::0;;;::::3;;174606:27;174636:15:::0;;;:6:::3;:15:::0;;;;;;174606:45;;::::3;::::0;::::3;::::0;;;;-1:-1:-1;;;;;174606:45:0;;::::3;::::0;;-1:-1:-1;;;174606:45:0;;::::3;;::::0;;::::3;::::0;;;;::::3;::::0;::::3;::::0;;::::3;::::0;;;;;;-1:-1:-1;;;174606:45:0;;::::3;::::0;::::3;::::0;;;;174720:127;;;;::::3;::::0;;174776:14;;174720:127:::3;;::::0;;174816:15;;174720:127:::3;::::0;;::::3;::::0;174915:19;;;;::::3;::::0;;;;;;;;::::3;::::0;;;;174580:11;;-1:-1:-1;174606:45:0;174720:127;-1:-1:-1;174876:59:0::3;::::0;174580:11;;174720:127;;174876:11:::3;:59::i;:::-;174957:15;::::0;;;:6:::3;:15;::::0;;;;174950:22;;;;::::3;::::0;;-1:-1:-1;;174950:22:0;;;174987:14:::3;174964:7:::0;174987:5:::3;:14::i;:::-;-1:-1:-1::0;;;174542:3:0::3;;174501:512;;;-1:-1:-1::0;175084:110:0::3;::::0;;;;::::3;::::0;;::::3;::::0;;::::3;::::0;;::::3;::::0;::::3;;::::0;;::::3;::::0;;;;175239:19;;;;::::3;::::0;;;175053:28:::3;175239:19:::0;;;;;::::3;::::0;175084:110;175215:53:::3;::::0;175227:10;;175084:110;175215:11:::3;:53::i;:::-;175310:176;;;;;;;;175346:11;-1:-1:-1::0;;;;;175310:176:0::3;;;;;175466:8;-1:-1:-1::0;;;;;175310:176:0::3;;;;;175381:13;175310:176;;;;;;175428:15;175310:176;;;;::::0;175289:6:::3;:18;175296:10;175289:18;;;;;;;;;;;:197;;;;;;;;;;;;;-1:-1:-1::0;;;;;175289:197:0::3;;;;;-1:-1:-1::0;;;;;175289:197:0::3;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;175289:197:0::3;;;;;-1:-1:-1::0;;;;;175289:197:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;175594:8;;:15;;175559:14;:26;175574:10;-1:-1:-1::0;;;;;175559:26:0::3;-1:-1:-1::0;;;;;175559:26:0::3;;;;;;;;;;;;;;;;;;;;;;:51;175613:1;175559:55;175524:14;:26;175539:10;-1:-1:-1::0;;;;;175524:26:0::3;-1:-1:-1::0;;;;;175524:26:0::3;;;;;;;;;;;;;:91;;;;;;;;;;;;;;;;;;175672:10;175660;-1:-1:-1::0;;;;;175652:59:0::3;;175684:11;175697:13;175652:59;;;;;;-1:-1:-1::0;;;;;16465:47:1;;;;16447:66;;16561:10;16549:23;16544:2;16529:18;;16522:51;16435:2;16420:18;;16275:304;175652:59:0::3;;;;;;;;173322:2397;;;;;;;145602:1:::2;143081:20:::0;142298:1;143601:7;:22;143418:213;169408:1874;143037:21;:19;:21::i;:::-;145572:19:::1;:17;:19::i;:::-;169593:8:::2;156581;156563:15;:26;156559:56;;;156598:17;;-1:-1:-1::0;;;156598:17:0::2;;;;;;;;;;;156559:56;169634:9:::3;169614:16;169622:7:::0;169614::::3;:16::i;:::-;-1:-1:-1::0;;;;;169614:29:0::3;;169610:58;;169653:15;;-1:-1:-1::0;;;169653:15:0::3;;;;;;;;;;;169610:58;169679:16;-1:-1:-1::0;;;;;169679:21:0::3;169699:1;169679:21:::0;169675:49:::3;;169709:15;;-1:-1:-1::0;;;169709:15:0::3;;;;;;;;;;;169675:49;169737:24;169764:15:::0;;;:6:::3;:15;::::0;;;;;;;169737:42;;::::3;::::0;::::3;::::0;;;;-1:-1:-1;;;;;169737:42:0;;::::3;::::0;;;-1:-1:-1;;;169737:42:0;;::::3;;::::0;;::::3;::::0;;;;;;;::::3;::::0;::::3;::::0;;::::3;::::0;;;;;;;-1:-1:-1;;;169737:42:0;::::3;::::0;;::::3;::::0;;;;;169790:16;169786:44:::3;;169815:15;;-1:-1:-1::0;;;169815:15:0::3;;;;;;;;;;;169786:44;169868:4;:12;;;169841:39;;169848:15;169841:39;;;169837:65;;169889:13;;-1:-1:-1::0;;;169889:13:0::3;;;;;;;;;;;169837:65;169935:11:::0;;169915:17:::3;::::0;169935:30:::3;::::0;169949:16;;169935:30:::3;:::i;:::-;169915:50;;169972:16;169991:29;170010:9;169991:18;:29::i;:::-;169972:48;;170033:24;170082:15;170060:4;:12;;;:38;;;;:::i;:::-;170033:65:::0;-1:-1:-1;170105:18:0::3;170153:37;;::::0;::::3;-1:-1:-1::0;;;;;170153:17:0;::::3;:37;:::i;:::-;170134:57;::::0;153212:4:::3;170134:57;:::i;:::-;170105:87:::0;-1:-1:-1;153158:4:0::3;-1:-1:-1::0;;;;;170203:27:0;::::3;;170199:59;;;170239:19;;-1:-1:-1::0;;;170239:19:0::3;;;;;;;;;;;170199:59;170282:13;-1:-1:-1::0;;;;;170269:26:0::3;:10;-1:-1:-1::0;;;;;170269:26:0::3;;170265:57;;;170304:18;;-1:-1:-1::0;;;170304:18:0::3;;;;;;;;;;;170265:57;170383:12;::::0;:37:::3;::::0;-1:-1:-1;;;170383:37:0;;170414:4:::3;170383:37;::::0;::::3;1488:51:1::0;170359:21:0::3;::::0;-1:-1:-1;;;;;170383:12:0::3;::::0;:22:::3;::::0;1461:18:1;;170383:37:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;170427:12;::::0;170359:61;;-1:-1:-1;170427:74:0::3;::::0;-1:-1:-1;;;;;170427:12:0::3;170457:10;170477:4;-1:-1:-1::0;;;;;170427:74:0;::::3;:29;:74::i;:::-;170553:32;-1:-1:-1::0;;;;;170553:32:0;::::3;:13:::0;:32:::3;:::i;:::-;170512:12;::::0;:37:::3;::::0;-1:-1:-1;;;170512:37:0;;170543:4:::3;170512:37;::::0;::::3;1488:51:1::0;-1:-1:-1;;;;;170512:12:0;;::::3;::::0;:22:::3;::::0;1461:18:1;;170512:37:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:73;170508:111;;170603:16;;-1:-1:-1::0;;;170603:16:0::3;;;;;;;;;;;170508:111;170695:76;170727:16;170754:10;170695:21;:76::i;:::-;170803:170;170825:7;170843:57;;;;;;;;170872:4;:11;;;170843:57;;;;;;170887:4;:12;;;170843:57;;;;::::0;170911:55:::3;;;;;;;;170940:9;170911:55;;;;;;170953:4;:12;;;170911:55;;;;::::0;170803:11:::3;:170::i;:::-;171030:153;;;;;;;;171062:9;-1:-1:-1::0;;;;;171030:153:0::3;;;;;171167:8;-1:-1:-1::0;;;;;171030:153:0::3;;;;;171091:4;:12;;;171030:153;;;;;;171133:15;171030:153;;;;::::0;171012:6:::3;:15;171019:7;171012:15;;;;;;;;;;;:171;;;;;;;;;;;;;-1:-1:-1::0;;;;;171012:171:0::3;;;;;-1:-1:-1::0;;;;;171012:171:0::3;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;171012:171:0::3;;;;;-1:-1:-1::0;;;;;171012:171:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;171229:7;171217:10;-1:-1:-1::0;;;;;171201:77:0::3;;171238:16;171256:9;171267:10;171201:77;;;;;;;-1:-1:-1::0;;;;;16993:47:1;;;16975:66;;17077:47;;;17072:2;17057:18;;17050:75;17161:47;;;17156:2;17141:18;;17134:75;16963:2;16948:18;;16773:442;171201:77:0::3;;;;;;;;169603:1679;;;;;;145602:1:::2;143081:20:::0;142298:1;143601:7;:22;143418:213;177106:172;149413:13;:11;:13::i;:::-;177167:14:::1;:21:::0;;-1:-1:-1;;;;177167:21:0::1;-1:-1:-1::0;;;177167:21:0::1;::::0;;177199:8:::1;:6;:8::i;:::-;177244:25;::::0;177223:47:::1;::::0;-1:-1:-1;;;;;177244:25:0;;::::1;1488:51:1::0;;177223:47:0::1;::::0;1476:2:1;1461:18;177223:47:0::1;;;;;;;;177106:172::o:0;179163:495::-;179236:13;179291:1;179262:17;179271:7;179262:8;:17::i;:::-;-1:-1:-1;;;;;179262:31:0;;179258:60;;179302:16;;-1:-1:-1;;;179302:16:0;;;;;;;;;;;179258:60;179329:8;;-1:-1:-1;;;;;179329:8:0;179325:52;;179360:17;;-1:-1:-1;;;179360:17:0;;;;;;;;;;;179325:52;179470:8;;179500:53;;;;;7689:25:1;;;179435:12:0;;;;-1:-1:-1;;;;;179470:8:0;;;;7662:18:1;;179500:53:0;;;-1:-1:-1;;179500:53:0;;;;;;;;;;;;;;-1:-1:-1;;;;;179500:53:0;-1:-1:-1;;;179500:53:0;;;179470:90;;;179500:53;179470:90;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;179434:126;;;;179575:7;179567:41;;;;-1:-1:-1;;;179567:41:0;;17728:2:1;179567:41:0;;;17710:21:1;17767:2;17747:18;;;17740:30;-1:-1:-1;;;17786:18:1;;;17779:51;17847:18;;179567:41:0;17526:345:1;179567:41:0;179639:4;179628:26;;;;;;;;;;;;:::i;:::-;179621:33;179163:495;-1:-1:-1;;;;179163:495:0:o;179662:322::-;179747:7;179767:13;;;;;:35;;-1:-1:-1;153054:8:0;179784:18;;;;179767:35;179763:65;;;179811:17;;-1:-1:-1;;;179811:17:0;;;;;;;;;;;179763:65;179839:6;-1:-1:-1;;;;;179839:11:0;179849:1;179839:11;179835:39;;179859:15;;-1:-1:-1;;;179859:15:0;;;;;;;;;;;179835:39;179887:13;179903:26;179922:6;179903:18;:26::i;:::-;179887:42;;179943:37;179964:5;179971:8;179943:20;:37::i;175728:828::-;175809:7;175848:23;;;:14;:23;;;;;;;;175886:14;;;175882:28;;175909:1;175902:8;;;;;175882:28;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;176016:9:0;176000:528;176032:1;176027;:6;;;176000:528;;176067:25;;;;:16;:25;;;;;;;;:28;;;;;;;;;;;;;176055:40;;;;;;;;;;;;;;;-1:-1:-1;;;176055:40:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;176055:40:0;;;;;;;;;;-1:-1:-1;176114:25:0;;;-1:-1:-1;176110:407:0;;176167:16;176213:9;:12;;;176201:9;:24;;;;:::i;:::-;176193:33;;176167:60;;153260:4;176300:9;176282;:15;;;:27;;;;:::i;:::-;176281:49;;;;:::i;:::-;176263:14;;:68;;;;:::i;:::-;176246:85;;;;;:14;-1:-1:-1;176350:85:0;;;176414:1;176397:18;;176350:85;-1:-1:-1;;176484:14:0;-1:-1:-1;;;;;176468:32:0;;-1:-1:-1;176453:48:0;;-1:-1:-1;176453:48:0;176110:407;176035:3;;;;:::i;:::-;;;;176000:528;;;-1:-1:-1;176547:1:0;;175728:828;-1:-1:-1;;;;;175728:828:0:o;176564:506::-;176743:15;;176648:7;;;;176743:15;-1:-1:-1;;;176743:15:0;;;;;176728:30;;;;:78;;176794:12;176728:78;;;176776:15;;176761:30;;-1:-1:-1;;;176776:15:0;;;;176761:12;:30;:::i;:::-;176707:99;-1:-1:-1;176870:17:0;153054:8;176910:32;153212:4;153158;176910:32;:::i;:::-;-1:-1:-1;;;;;176891:52:0;176899:6;-1:-1:-1;;;;;176891:15:0;:52;;;;:::i;:::-;176890:64;;;;:::i;:::-;176870:84;-1:-1:-1;176870:84:0;177036:28;;;;-1:-1:-1;;;;;177036:14:0;;:28;:::i;:::-;177017:48;;153212:4;177017:48;:::i;165946:1791::-;166156:15;143037:21;:19;:21::i;:::-;145572:19:::1;:17;:19::i;:::-;166137:8:::2;156581;156563:15;:26;156559:56;;;156598:17;;-1:-1:-1::0;;;156598:17:0::2;;;;;;;;;;;156559:56;166188:6:::3;-1:-1:-1::0;;;;;166188:11:0::3;166198:1;166188:11:::0;166184:39:::3;;166208:15;;-1:-1:-1::0;;;166208:15:0::3;;;;;;;;;;;166184:39;166238:17;::::0;::::3;::::0;;:43:::3;;-1:-1:-1::0;153054:8:0::3;166259:22;::::0;::::3;;166238:43;166234:73;;;166290:17;;-1:-1:-1::0;;;166290:17:0::3;;;;;;;;;;;166234:73;166337:10;166322:26;::::0;;;:14:::3;:26;::::0;;;;;153315:3:::3;166322:48;:26:::0;;::::3;:48;166318:78;;166379:17;;-1:-1:-1::0;;;166379:17:0::3;;;;;;;;;;;166318:78;166417:17;166437:38;166463:12:::0;166444:15:::3;166437:38;:::i;:::-;166417:58;;166497:13;166512:18;166534:61;166559:6;166567:12;166581:13;166534:24;:61::i;:::-;166496:99;;;;166652:28;166683:102;;;;;;;;166735:6;166683:102;;;;;;166763:10;166683:102;;;;::::0;166652:133:::3;;166852:44;166864:1;166867:19;;;;;;;;166881:1;166867:19;;;;;;166884:1;166867:19;;;;::::0;166888:7:::3;166852:11;:44::i;:::-;166985:12;::::0;:37:::3;::::0;-1:-1:-1;;;166985:37:0;;167016:4:::3;166985:37;::::0;::::3;1488:51:1::0;166961:21:0::3;::::0;-1:-1:-1;;;;;166985:12:0::3;::::0;:22:::3;::::0;1461:18:1;;166985:37:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;167033:12;::::0;166961:61;;-1:-1:-1;167033:64:0::3;::::0;-1:-1:-1;;;;;167033:12:0::3;167063:10;167083:4;-1:-1:-1::0;;;;;167033:64:0;::::3;:29;:64::i;:::-;167153:22;-1:-1:-1::0;;;;;167153:22:0;::::3;:13:::0;:22:::3;:::i;:::-;167112:12;::::0;:37:::3;::::0;-1:-1:-1;;;167112:37:0;;167143:4:::3;167112:37;::::0;::::3;1488:51:1::0;-1:-1:-1;;;;;167112:12:0;;::::3;::::0;:22:::3;::::0;1461:18:1;;167112:37:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:63;167108:106;;167198:16;;-1:-1:-1::0;;;167198:16:0::3;;;;;;;;;;;167108:106;167270:12;:14:::0;;::::3;;-1:-1:-1::0;;;167270:14:0;;::::3;::::0;::::3;::::0;;::::3;::::0;;::::3;;-1:-1:-1::0;;;;167270:14:0;;::::3;::::0;;;::::3;::::0;;;167314:10:::3;-1:-1:-1::0;167299:26:0;;;:14:::3;:26;::::0;;;;:28;;::::3;::::0;;::::3;::::0;;::::3;::::0;;::::3;-1:-1:-1::0;;167299:28:0;;::::3;::::0;;;::::3;::::0;;;167270:14;-1:-1:-1;167359:30:0::3;::::0;167270:14;167359:9:::3;:30::i;:::-;167428:165;::::0;;::::3;::::0;::::3;::::0;;-1:-1:-1;;;;;167428:165:0;;::::3;::::0;;;;::::3;;::::0;;::::3;::::0;;;::::3;::::0;;::::3;::::0;;;;;;167538:15:::3;167428:165:::0;::::3;::::0;;;;;;-1:-1:-1;167410:15:0;;;:6:::3;:15:::0;;;;;;;:183;;;;;::::3;-1:-1:-1::0;;;167410:183:0::3;::::0;;;::::3;::::0;;;::::3;::::0;;;;;;::::3;::::0;;;;;::::3;-1:-1:-1::0;;;167410:183:0::3;-1:-1:-1::0;;167410:183:0;;;;;;::::3;::::0;;;;;;;::::3;::::0;;167614:41:::3;167464:6:::0;167644:10;167614:21:::3;:41::i;:::-;167681:48;::::0;;-1:-1:-1;;;;;16465:47:1;;16447:66;;16561:10;16549:23;;16544:2;16529:18;;16522:51;167701:7:0;;167689:10:::3;::::0;167681:48:::3;::::0;16420:18:1;167681:48:0::3;;;;;;;166173:1564;;;;;145602:1:::2;143081:20:::0;142298:1;143601:7;:22;143418:213;104339;-1:-1:-1;;;;;104507:27:0;;;104427:4;104507:27;;;:20;:27;;;;;;;;:37;;;;;;;;;;;;;;;104339:213::o;150520:220::-;149413:13;:11;:13::i;:::-;-1:-1:-1;;;;;150605:22:0;::::1;150601:93;;150651:31;::::0;-1:-1:-1;;;150651:31:0;;150679:1:::1;150651:31;::::0;::::1;1488:51:1::0;1461:18;;150651:31:0::1;1342:203:1::0;150601:93:0::1;150704:28;150723:8;150704:18;:28::i;177879:68::-:0;149413:13;:11;:13::i;:::-;177929:10:::1;:8;:10::i;117353:247::-:0;117416:7;117436:13;117452:17;117461:7;117452:8;:17::i;:::-;117436:33;-1:-1:-1;;;;;;117484:19:0;;117480:90;;117527:31;;-1:-1:-1;;;117527:31:0;;;;;7689:25:1;;;7662:18;;117527:31:0;7543:177:1;106540:187:0;106610:7;106693:26;;;:17;:26;;;;;;-1:-1:-1;;;;;106693:26:0;;106540:187::o;115469:122::-;115550:33;115559:2;115563:7;115572:4;115578;115550:8;:33::i;106244:175::-;106310:7;106393:18;;;:9;:18;;;;;;-1:-1:-1;;;;;106393:18:0;;106244:175::o;143117:293::-;142342:1;143251:7;;:19;143243:63;;;;-1:-1:-1;;;143243:63:0;;19770:2:1;143243:63:0;;;19752:21:1;19809:2;19789:18;;;19782:30;19848:33;19828:18;;;19821:61;19899:18;;143243:63:0;19568:355:1;143243:63:0;142342:1;143384:7;:18;143117:293::o;146126:108::-;146038:7;;;;146196:9;146188:38;;;;-1:-1:-1;;;146188:38:0;;20130:2:1;146188:38:0;;;20112:21:1;20169:2;20149:18;;;20142:30;-1:-1:-1;;;20188:18:1;;;20181:46;20244:18;;146188:38:0;19928:340:1;172308:275:0;172374:7;-1:-1:-1;;;;;172410:15:0;;172374:7;172456:15;153054:8;172410:15;172456;:::i;:::-;172436:35;-1:-1:-1;;;;;;172486:29:0;;172482:57;;;172524:15;;-1:-1:-1;;;172524:15:0;;;;;;;;;;;172591:576;172676:7;;172749:25;;;;-1:-1:-1;;;;;172749:14:0;;:25;:::i;:::-;172734:40;-1:-1:-1;172843:18:0;172944:24;153054:8;-1:-1:-1;;;;;172944:14:0;;:24;:::i;:::-;172906:32;153212:4;153158;172906:32;:::i;:::-;172898:41;;-1:-1:-1;;;;;172898:41:0;:4;:41;:::i;:::-;172897:72;;;;:::i;:::-;172864:106;;153212:4;172864:106;:::i;:::-;172843:127;-1:-1:-1;153158:4:0;172995:27;;172991:54;;;153158:4;173024:21;;;;;;172991:54;153212:4;173060:28;;173056:56;;;153212:4;173090:22;;;;;;165711:227;165798:22;153260:4;165823:37;-1:-1:-1;;;;;165841:19:0;;;;165823:15;;:37;:::i;:::-;:49;;;;:::i;:::-;165883:20;:47;;165798:74;;-1:-1:-1;165798:74:0;;165883:20;;:47;;165798:74;;-1:-1:-1;;;;;165883:47:0;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;165883:47:0;;;;;-1:-1:-1;;;;;165883:47:0;;;;;;165787:151;165711:227;;:::o;157678:363::-;157834:19;:17;:19::i;:::-;157878:12;;157874:160;;157907:115;157942:7;157969:9;157998;157907:16;:115::i;143418:213::-;142298:1;143601:7;:22;143418:213::o;101250:151::-;22572:20;:18;:20::i;:::-;101354:39:::1;101378:5;101385:7;101354:23;:39::i;142384:113::-:0;22572:20;:18;:20::i;:::-;142455:34:::1;:32;:34::i;145137:99::-:0;22572:20;:18;:20::i;:::-;145201:27:::1;:25;:27::i;148911:129::-:0;22572:20;:18;:20::i;:::-;148994:38:::1;149019:12;148994:24;:38::i;146563:118::-:0;145572:19;:17;:19::i;:::-;146623:7:::1;:14:::0;;-1:-1:-1;;146623:14:0::1;146633:4;146623:14;::::0;;146653:20:::1;146660:12;25437:10:::0;;25357:98;146660:12:::1;146653:20;::::0;-1:-1:-1;;;;;1506:32:1;;;1488:51;;1476:2;1461:18;146653:20:0::1;1342:203:1::0;162323:259:0;-1:-1:-1;;;;;162433:18:0;;;;;;:57;;-1:-1:-1;162463:12:0;;-1:-1:-1;;;;;162463:12:0;162455:35;;162433:57;162429:136;;;162526:12;;:27;;-1:-1:-1;;;162526:27:0;;;;;7689:25:1;;;-1:-1:-1;;;;;162526:12:0;;;;:18;;7662::1;;162526:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;104619:588::-;-1:-1:-1;;;;;104714:16:0;;104710:89;;104754:33;;-1:-1:-1;;;104754:33:0;;104784:1;104754:33;;;1488:51:1;1461:18;;104754:33:0;1342:203:1;104710:89:0;105020:21;105044:34;105052:2;105056:7;25437:10;105044:7;:34::i;:::-;105020:58;;105110:4;-1:-1:-1;;;;;105093:21:0;:13;-1:-1:-1;;;;;105093:21:0;;105089:111;;105138:50;;-1:-1:-1;;;105138:50:0;;-1:-1:-1;;;;;20493:32:1;;;105138:50:0;;;20475:51:1;20542:18;;;20535:34;;;20605:32;;20585:18;;;20578:60;20448:18;;105138:50:0;20273:371:1;112415:232:0;112467:21;112491:40;112507:1;112511:7;112528:1;112491:7;:40::i;:::-;112467:64;-1:-1:-1;;;;;;112546:27:0;;112542:98;;112597:31;;-1:-1:-1;;;112597:31:0;;;;;7689:25:1;;;7662:18;;112597:31:0;7543:177:1;134405:188:0;134526:58;;-1:-1:-1;;;;;20841:32:1;;134526:58:0;;;20823:51:1;20890:18;;;20883:34;;;134499:86:0;;134519:5;;-1:-1:-1;;;134549:23:0;20796:18:1;;134526:58:0;;;;-1:-1:-1;;134526:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;134526:58:0;-1:-1:-1;;;;;;134526:58:0;;;;;;;;;;134499:19;:86::i;149752:166::-;25437:10;149812:7;148358:22;149658:8;-1:-1:-1;;;;;149658:8:0;;149527:147;149812:7;-1:-1:-1;;;;;149812:23:0;;149808:103;;149859:40;;-1:-1:-1;;;149859:40:0;;25437:10;149859:40;;;1488:51:1;1461:18;;149859:40:0;1342:203:1;150900:253:0;148358:22;151051:8;;-1:-1:-1;;;;;;151070:19:0;;-1:-1:-1;;;;;151070:19:0;;;;;;;;151105:40;;151051:8;;;;;151105:40;;150974:24;;151105:40;150963:190;;150900:253;:::o;171499:801::-;171571:7;171591:22;171616:5;171591:30;;171632:9;153100;;171645;:12;;;:19;;;;:::i;:::-;171644:28;;;;:::i;:::-;171632:40;-1:-1:-1;171698:9:0;171693:460;171717:3;171713:1;:7;171693:460;;;171742:10;153100:9;171742:10;;:::i;:::-;;-1:-1:-1;171767:13:0;171803:6;;;;;;;;171799:119;;;171835:1;171830:6;;171799:119;;;-1:-1:-1;171886:16:0;;;;;;;:12;:16;;;;;;;;171799:119;171988:12;;;;171983:17;;:2;:17;:::i;:::-;171975:26;;171950:9;:15;;;:52;;;;:::i;:::-;171932:70;;:9;;:70;;;;;:::i;:::-;;;;;-1:-1:-1;172021:7:0;;;;;;;;172017:53;;172049:5;;;172017:53;172103:6;172084:9;:15;;:25;;;;;;;:::i;:::-;;;;;-1:-1:-1;;172124:17:0;;;:12;;;:17;171722:3;;171693:460;;;;172186:1;172169:9;:14;;;:18;;;172165:69;;;172221:1;172204:18;;172165:69;-1:-1:-1;172275:14:0;-1:-1:-1;;;;;172259:32:0;;171499:801;-1:-1:-1;;;171499:801:0:o;116734:376::-;-1:-1:-1;;;;;;;;;;;;;;;;116898:22:0;;116894:93;;116944:31;;-1:-1:-1;;;116944:31:0;;-1:-1:-1;;;;;1506:32:1;;116944:31:0;;;1488:51:1;1461:18;;116944:31:0;1342:203:1;116894:93:0;-1:-1:-1;;;;;116997:27:0;;;;;;;:20;;;:27;;;;;;;;:37;;;;;;;;;;;;;:48;;-1:-1:-1;;116997:48:0;;;;;;;;;;117061:41;;540::1;;;117061::0;;513:18:1;117061:41:0;;;;;;;116827:283;116734:376;;;:::o;105483:236::-;105597:31;105610:4;105616:2;105620:7;105597:12;:31::i;:::-;105639:72;25437:10;105687:4;105693:2;105697:7;105706:4;105639:33;:72::i;111537:102::-;111605:26;111615:2;111619:7;111605:26;;;;;;;;;;;;:9;:26::i;134838:216::-;134977:68;;-1:-1:-1;;;;;21830:32:1;;;134977:68:0;;;21812:51:1;21899:32;;21879:18;;;21872:60;21948:18;;;21941:34;;;134950:96:0;;134970:5;;-1:-1:-1;;;135000:27:0;21785:18:1;;134977:68:0;21610:371:1;164530:1173:0;164681:13;;;164799:27;153260:4;-1:-1:-1;;;;;164799:15:0;;:27;:::i;:::-;164776:50;-1:-1:-1;165069:22:0;165094:32;153212:4;153158;165094:32;:::i;:::-;-1:-1:-1;;;;;165069:57:0;;-1:-1:-1;165148:17:0;165203:19;153260:4;153054:8;165203:19;:::i;:::-;-1:-1:-1;;;;;165168:55:0;165169:29;165184:14;165169:12;:29;:::i;:::-;165168:55;;;;:::i;:::-;165148:75;-1:-1:-1;;;;;;165238:29:0;;165234:57;;;165276:15;;-1:-1:-1;;;165276:15:0;;;;;;;;;;;165234:57;165318:9;-1:-1:-1;165318:9:0;165406:26;153260:4;165436:29;;;;-1:-1:-1;;;;;165436:14:0;;:29;:::i;:::-;165435:43;;;;:::i;:::-;165406:72;-1:-1:-1;165510:36:0;165406:72;153212:4;165510:36;:::i;:::-;165489:58;-1:-1:-1;153158:4:0;-1:-1:-1;;;;;165572:27:0;;;165568:59;;;165608:19;;-1:-1:-1;;;165608:19:0;;;;;;;;;;;165568:59;165655:13;-1:-1:-1;;;;;165642:26:0;:10;-1:-1:-1;;;;;165642:26:0;;165638:57;;;165677:18;;-1:-1:-1;;;165677:18:0;;;;;;;;;;;165638:57;164716:987;;;;164530:1173;;;;;;:::o;146822:120::-;145831:16;:14;:16::i;:::-;146881:7:::1;:15:::0;;-1:-1:-1;;146881:15:0::1;::::0;;146912:22:::1;25437:10:::0;146921:12:::1;25357:98:::0;115779:736;-1:-1:-1;;;;;;;;;;;115997:9:0;;:31;;-1:-1:-1;;;;;;116010:18:0;;;;115997:31;115993:471;;;116045:13;116061:22;116075:7;116061:13;:22::i;:::-;116045:38;-1:-1:-1;;;;;;116214:18:0;;;;;;:35;;;116245:4;-1:-1:-1;;;;;116236:13:0;:5;-1:-1:-1;;;;;116236:13:0;;;116214:35;:69;;;;;116254:29;116271:5;116278:4;116254:16;:29::i;:::-;116253:30;116214:69;116210:144;;;116311:27;;-1:-1:-1;;;116311:27:0;;-1:-1:-1;;;;;1506:32:1;;116311:27:0;;;1488:51:1;1461:18;;116311:27:0;1342:203:1;116210:144:0;116374:9;116370:83;;;116429:7;116425:2;-1:-1:-1;;;;;116409:28:0;116418:5;-1:-1:-1;;;;;116409:28:0;;;;;;;;;;;116370:83;116030:434;115993:471;116476:26;;;;:17;;:26;;-1:-1:-1;;116476:26:0;;;:31;;-1:-1:-1;;;;;;116476:31:0;-1:-1:-1;;;;;116476:31:0;;;;;;;;;;115779:736::o;158049:950::-;158114:5;;;;158130:22;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;158130:22:0;158177:10;;;;158173:289;;158216:12;:24;158229:10;158238:1;158229:6;:10;:::i;:::-;158216:24;;;;;;;;;;;;;;;;;;-1:-1:-1;158216:24:0;158204:36;;;;;;;;;;;;;;;-1:-1:-1;;;158204:36:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;158204:36:0;;;;;;;;;-1:-1:-1;158173:289:0;;;-1:-1:-1;158285:165:0;;;;;;;;-1:-1:-1;158285:165:0;;;;;;;;158374:15;158285:165;;;;;;;;;158421:12;158285:165;;;;;;;158173:289;158498:12;;;;158474:21;158568:40;;;;158575:15;158568:40;;;;158564:198;;;158736:12;;;;158718:30;;;;:15;:30;:::i;:::-;158675:13;;;;158660:28;;;;:12;:28;:::i;:::-;158647:42;;153260:4;158647:42;:::i;:::-;158646:103;;;;:::i;:::-;158625:125;;158564:198;158825:135;158865:9;158889:14;158918:10;158943:6;158825:25;:135::i;:::-;158813:147;-1:-1:-1;158981:10:0;:6;158990:1;158981:10;:::i;:::-;158973:5;:18;;-1:-1:-1;;158973:18:0;;;;;;;;;;;;-1:-1:-1;;;;158049:950:0:o;160295:1198::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;160549:15:0;160526:39;;:9;:13;;;:39;;;:63;;;;;160588:1;160569:9;:16;;;:20;;;160526:63;160522:276;;;160620:16;;153054:8;;160620:36;;153260:4;;160620:36;:::i;:::-;160619:49;;;;:::i;:::-;160606:62;;:10;;;;:62;;;;160724:13;;;153260:4;;160724:39;;160747:15;;160724:39;:::i;:::-;160716:48;;160696:4;:10;;;:69;;;;:::i;:::-;160695:91;;;;:::i;:::-;160683:103;;;;160522:276;160845:15;160822:39;;:9;:13;;;:39;;;:63;;;;;160884:1;160865:9;:16;;;:20;;;160822:63;160818:276;;;160916:16;;153054:8;;160916:36;;153260:4;;160916:36;:::i;:::-;160915:49;;;;:::i;:::-;160902:62;;:10;;;;:62;;;;161020:13;;;153260:4;;161020:39;;161043:15;;161020:39;:::i;:::-;161012:48;;160992:4;:10;;;:69;;;;:::i;:::-;160991:91;;;;:::i;:::-;160979:103;;;;160818:276;161106:134;161146:9;161170;161194:4;:10;;;161219:4;:10;;;161106:25;:134::i;:::-;161253:16;161272:23;;;:14;:23;;;;;;:27;;:23;;;:27;:::i;:::-;161310:23;;;;:14;:23;;;;;;;;:35;;;;;;-1:-1:-1;;161310:35:0;;;;;;;;161373:15;161356:33;;:7;;;:33;;;161418:12;161400:31;;:8;;;:31;;;161442:25;;;:16;:25;;;;;:36;;;;;;;;:43;;;;;;;-1:-1:-1;;;;;161442:43:0;;;-1:-1:-1;;;161442:43:0;;;;;;;;;;161310:35;161442:43;;;;;;;;;;-1:-1:-1;;;161442:43:0;-1:-1:-1;;161442:43:0;;;;;;;;;;;;;;;;;-1:-1:-1;;;;160295:1198:0:o;22732:145::-;24565:21;24246:40;-1:-1:-1;;;24246:40:0;;;;22795:75;;22841:17;;-1:-1:-1;;;22841:17:0;;;;;;;;;;;101409:223;22572:20;:18;:20::i;:::-;-1:-1:-1;;;;;;;;;;;101087:21:0;101579:15:::1;101589:5:::0;101087:21;101579:15:::1;:::i;:::-;-1:-1:-1::0;101605:9:0::1;::::0;::::1;:19;101617:7:::0;101605:9;:19:::1;:::i;142505:111::-:0;22572:20;:18;:20::i;145244:97::-;22572:20;:18;:20::i;:::-;145318:7:::1;:15:::0;;-1:-1:-1;;145318:15:0::1;::::0;;145244:97::o;149048:240::-;22572:20;:18;:20::i;109617:886::-;109703:7;-1:-1:-1;;;;;;;;;;;109703:7:0;109794:17;109803:7;109794:8;:17::i;:::-;109779:32;-1:-1:-1;;;;;;109874:18:0;;;109870:88;;109909:37;109926:4;109932;109938:7;109909:16;:37::i;:::-;-1:-1:-1;;;;;110005:18:0;;;110001:265;;110123:48;110140:1;110144:7;110161:1;110165:5;110123:8;:48::i;:::-;-1:-1:-1;;;;;110217:17:0;;;;;;:11;;;:17;;;;;:22;;-1:-1:-1;;110217:22:0;;;110001:265;-1:-1:-1;;;;;110282:16:0;;;110278:113;;-1:-1:-1;;;;;110344:15:0;;;;;;:11;;;:15;;;;;:20;;110363:1;110344:20;;;110278:113;110403:18;;;;:9;;;:18;;;;;;:23;;-1:-1:-1;;;;;;110403:23:0;-1:-1:-1;;;;;110403:23:0;;;;;;;;;110444:27;;110403:18;;110444:27;;;;;;;110491:4;109617:886;-1:-1:-1;;;;;109617:886:0:o;138828:660::-;139263:23;139289:69;139317:4;139289:69;;;;;;;;;;;;;;;;;139297:5;-1:-1:-1;;;;;139289:27:0;;;:69;;;;;:::i;:::-;139263:95;;139377:10;:17;139398:1;139377:22;:56;;;;139414:10;139403:30;;;;;;;;;;;;:::i;:::-;139369:111;;;;-1:-1:-1;;;139369:111:0;;24695:2:1;139369:111:0;;;24677:21:1;24734:2;24714:18;;;24707:30;24773:34;24753:18;;;24746:62;-1:-1:-1;;;24824:18:1;;;24817:40;24874:19;;139369:111:0;24493: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;111866:210::-;111961:18;111967:2;111971:7;111961:5;:18::i;:::-;111990:78;25437:10;112046:1;112050:2;112054:7;112063:4;111990:33;:78::i;146311:108::-;146038:7;;;;146370:41;;;;-1:-1:-1;;;146370:41:0;;25850:2:1;146370:41:0;;;25832:21:1;25889:2;25869:18;;;25862:30;-1:-1:-1;;;25908:18:1;;;25901:50;25968:18;;146370:41:0;25648:344:1;159007:1276:0;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;159242:9:0;159210:29;153100:9;159275:21;153100:9;159275:14;:21;:::i;:::-;159274:30;;;;:::i;:::-;159262:42;-1:-1:-1;159330:9:0;159325:914;159349:3;159345:1;:7;159325:914;;;159374:10;153100:9;159374:10;;:::i;:::-;;-1:-1:-1;159399:13:0;159449:28;159461:15;159449:28;;;;;;159445:163;;;159510:15;159498:28;;159445:163;;;-1:-1:-1;159576:16:0;;;;;;;:12;:16;;;;;;;;159445:163;159687:19;159692:14;159687:2;:19;:::i;:::-;159679:28;;159654:9;:15;;;:54;;;;:::i;:::-;159636:72;;:9;;:72;;;;;:::i;:::-;;;;;-1:-1:-1;159723:15:0;;;:25;;159742:6;;159723:15;:25;;159742:6;;159723:25;:::i;:::-;;;;;-1:-1:-1;159763:17:0;;;:12;;;;:17;;;;159898:19;;;153260:4;;159893:24;;159778:2;159893:24;:::i;:::-;159870:48;;;;-1:-1:-1;;;;;159870:19:0;;:48;:::i;:::-;159869:62;;;;:::i;:::-;159818:16;:20;;;:113;;;;;;:::i;:::-;159795:137;;;;:13;;;:137;159978:15;159965:29;;;;;;159961:219;;-1:-1:-1;160015:36:0;160038:12;160015:36;:13;;;:36;160070:5;;159961:219;160155:9;160116:12;:36;160149:1;160129:10;:6;160138:1;160129:10;:::i;:::-;:22;;;;:::i;:::-;160116:36;;;;;;;;;;;;;;;;;;-1:-1:-1;160116:36:0;:48;;;;;;-1:-1:-1;;;;;160116:48:0;;;-1:-1:-1;;;160116:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;160116:48:0;-1:-1:-1;;160116:48:0;;;;;;;;;;;;;;;;;-1:-1:-1;160225:2:0;;-1:-1:-1;160225:2:0;;159354:3;;159325:914;;;-1:-1:-1;160266:9:0;;159007:1276;-1:-1:-1;;;;;;159007:1276:0:o;161501:814::-;161724:15;161701:39;;:9;:13;;;:39;;;161697:314;;;161789:13;;;;;161776:27;;161757:16;161776:27;;;:12;:27;;;;;;;;;161818:21;161831:8;161776:27;161818:21;:::i;:::-;;;161875:9;:13;;;161858:30;;:9;:13;;;:30;;;161854:92;;161909:21;161922:8;161909:21;;:::i;:::-;;;161854:92;161973:13;;;;;161960:27;;;;;;:12;:27;;;;;;:39;;-1:-1:-1;;;;;;161960:39:0;-1:-1:-1;;;;;161960:39:0;;;;;;;;;;161697:314;162050:15;162027:39;;:9;:13;;;:39;;;162023:285;;;162103:9;:13;;;162087:29;;:9;:13;;;:29;;;162083:214;;;162169:13;;;;;162156:27;;162137:16;162156:27;;;:12;:27;;;;;;;;;162202:21;162215:8;162156:27;162202:21;:::i;:::-;162255:13;;;;;162242:27;;;;;;:12;:27;;;;;;:39;;-1:-1:-1;;;;;162242:39:0;;;-1:-1:-1;;;;;;162242:39:0;;;;;;;;;-1:-1:-1;161501:814:0;;;;:::o;107766:376::-;107879:38;107893:5;107900:7;107909;107879:13;:38::i;:::-;107874:261;;-1:-1:-1;;;;;107938:19:0;;107934:190;;107985:31;;-1:-1:-1;;;107985:31:0;;;;;7689:25:1;;;7662:18;;107985:31:0;7543:177:1;107934:190:0;108064:44;;-1:-1:-1;;;108064:44:0;;-1:-1:-1;;;;;20841:32:1;;108064:44:0;;;20823:51:1;20890:18;;;20883:34;;;20796:18;;108064:44:0;20649:274:1;128228:229:0;128365:12;128397:52;128419:6;128427:4;128433:1;128436:12;128397:21;:52::i;110839:335::-;-1:-1:-1;;;;;110907:16:0;;110903:89;;110947:33;;-1:-1:-1;;;110947:33:0;;110977:1;110947:33;;;1488:51:1;1461:18;;110947:33:0;1342:203:1;110903:89:0;111002:21;111026:32;111034:2;111038:7;111055:1;111026:7;:32::i;:::-;111002:56;-1:-1:-1;;;;;;111073:27:0;;;111069:98;;111124:31;;-1:-1:-1;;;111124:31:0;;111152:1;111124:31;;;1488:51:1;1461:18;;111124:31:0;1342:203:1;107047:276:0;107150:4;-1:-1:-1;;;;;107187:21:0;;;;;;:128;;;107235:7;-1:-1:-1;;;;;107226:16:0;:5;-1:-1:-1;;;;;107226:16:0;;:52;;;;107246:32;107263:5;107270:7;107246:16;:32::i;:::-;107226:88;;;;107307:7;-1:-1:-1;;;;;107282:32:0;:21;107295:7;107282:12;:21::i;:::-;-1:-1:-1;;;;;107282:32:0;;;107047:276;-1:-1:-1;;;;107047:276:0:o;129314:455::-;129484:12;129542:5;129517:21;:30;;129509:81;;;;-1:-1:-1;;;129509:81:0;;26199:2:1;129509:81:0;;;26181:21:1;26238:2;26218:18;;;26211:30;26277:34;26257:18;;;26250:62;-1:-1:-1;;;26328:18:1;;;26321:36;26374:19;;129509:81:0;25997:402:1;129509:81:0;129602:12;129616:23;129643:6;-1:-1:-1;;;;;129643:11:0;129662:5;129669:4;129643:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;129601:73;;;;129692:69;129719:6;129727:7;129736:10;129748:12;132072;132101:7;132097:427;;;132129:10;:17;132150:1;132129:22;132125:290;;-1:-1:-1;;;;;125768:19:0;;;132339:60;;;;-1:-1:-1;;;132339:60:0;;26606:2:1;132339:60:0;;;26588:21:1;26645:2;26625:18;;;26618:30;26684:31;26664:18;;;26657:59;26733:18;;132339:60:0;26404:353:1;132339:60:0;-1:-1:-1;132436:10:0;132429:17;;132097:427;132479:33;132487:10;132499:12;133234:17;;:21;133230:388;;133466:10;133460:17;133523:15;133510:10;133506:2;133502:19;133495:44;133230:388;133593:12;133586:20;;-1:-1:-1;;;133586: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:125::-;15450:9;;;15471:10;;;15468:36;;;15484:18;;:::i;15515:317::-;-1:-1:-1;;;;;15600:42:1;;;15644;;;15596:91;15707:52;;;;15778:24;;;15768:58;;15806:18;;:::i;:::-;15768:58;15515:317;;;;:::o;15837:240::-;-1:-1:-1;;;;;15906:42:1;;;15950;;;15902:91;;16005:43;;16002:69;;;16051:18;;:::i;16082:188::-;16120:3;16164:10;16157:5;16153:22;16199:10;16190:7;16187:23;16184:49;;16213:18;;:::i;:::-;16262:1;16249:15;;16082:188;-1:-1:-1;;16082:188:1:o;16584:184::-;16654:6;16707:2;16695:9;16686:7;16682:23;16678:32;16675:52;;;16723:1;16720;16713:12;16675:52;-1:-1:-1;16746:16:1;;16584:184;-1:-1:-1;16584:184:1:o;17220:301::-;17349:3;17387:6;17381:13;17433:6;17426:4;17418:6;17414:17;17409:3;17403:37;17495:1;17459:16;;17484:13;;;-1:-1:-1;17459:16:1;17220:301;-1:-1:-1;17220:301:1:o;17876:687::-;17956:6;18009:2;17997:9;17988:7;17984:23;17980:32;17977:52;;;18025:1;18022;18015:12;17977:52;18058:9;18052:16;18091:18;18083:6;18080:30;18077:50;;;18123:1;18120;18113:12;18077:50;18146:22;;18199:4;18191:13;;18187:27;-1:-1:-1;18177:55:1;;18228:1;18225;18218:12;18177:55;18261:2;18255:9;18286:53;18302:36;18331:6;18302:36;:::i;18286:53::-;18362:6;18355:5;18348:21;18410:7;18405:2;18396:6;18392:2;18388:15;18384:24;18381:37;18378:57;;;18431:1;18428;18421:12;18378:57;18479:6;18474:2;18470;18466:11;18461:2;18454:5;18450:14;18444:42;18531:1;18506:18;;;18526:2;18502:27;18495:38;;;;18510:5;17876:687;-1:-1:-1;;;;17876:687:1:o;18568:241::-;18607:7;18686:1;18682:2;18671:17;18667:1;18663:2;18652:17;18648:41;18724:11;18720:2;18709:27;18698:38;;18767:11;18758:7;18755:24;18745:58;;18783:18;;:::i;18814:305::-;18853:1;18895;18891:2;18880:17;18932:1;18928:2;18917:17;18953:3;18943:37;;18960:18;;:::i;:::-;-1:-1:-1;;;;;;18996:48:1;;-1:-1:-1;;19046:15:1;;18992:70;18989:96;;;19065:18;;:::i;:::-;19099:14;;;18814:305;-1:-1:-1;;;18814:305:1:o;19124:249::-;19224:2;19213:17;;;19194;;;;19190:41;-1:-1:-1;;;;;;19246:50:1;;-1:-1:-1;;;;;19298:45:1;;19243:101;19240:127;;;19347:18;;:::i;19378:185::-;19416:3;19460:10;19453:5;19449:22;19490:7;19480:41;;19501:18;;:::i;:::-;-1:-1:-1;;19537:20:1;;19378:185;-1:-1:-1;;19378:185:1:o;20928:178::-;20967:1;21001:10;20998:1;20994:18;21031:3;21021:37;;21038:18;;:::i;:::-;21096:3;21083:10;21080:1;21076:18;21072:28;21067:33;;;20928:178;;;;:::o;21111:244::-;21222:10;21195:18;;;21215;;;21191:43;21254:28;;;;21301:24;;;21291:58;;21329:18;;:::i;21360:245::-;21458:2;21428:17;;;21447;;;;21424:41;-1:-1:-1;;;;;21480:44:1;;-1:-1:-1;;;;;;21526:49:1;;21477:99;21474:125;;;21579:18;;:::i;21986:128::-;22053:9;;;22074:11;;;22071:37;;;22088:18;;:::i;22245:518::-;22347:2;22342:3;22339:11;22336:421;;;22383:5;22380:1;22373:16;22427:4;22424:1;22414:18;22497:2;22485:10;22481:19;22478:1;22474:27;22468:4;22464:38;22533:4;22521:10;22518:20;22515:47;;;-1:-1:-1;22556:4:1;22515:47;22611:2;22606:3;22602:12;22599:1;22595:20;22589:4;22585:31;22575:41;;22666:81;22684:2;22677:5;22674:13;22666:81;;;22743:1;22729:16;;22710:1;22699:13;22666:81;;22939:1299;23065:3;23059:10;23092:18;23084:6;23081:30;23078:56;;;23114:18;;:::i;:::-;23143:97;23233:6;23193:38;23225:4;23219:11;23193:38;:::i;:::-;23187:4;23143:97;:::i;:::-;23289:4;23320:2;23309:14;;23337:1;23332:649;;;;24025:1;24042:6;24039:89;;;-1:-1:-1;24094:19:1;;;24088:26;24039:89;-1:-1:-1;;22896:1:1;22892:11;;;22888:24;22884:29;22874:40;22920:1;22916:11;;;22871:57;24141:81;;23302:930;;23332:649;22192:1;22185:14;;;22229:4;22216:18;;-1:-1:-1;;23368:20:1;;;23486:222;23500:7;23497:1;23494:14;23486:222;;;23582:19;;;23576:26;23561:42;;23689:4;23674:20;;;;23642:1;23630:14;;;;23516:12;23486:222;;;23490:3;23736:6;23727:7;23724:19;23721:201;;;23797:19;;;23791:26;-1:-1:-1;;23880:1:1;23876:14;;;23892:3;23872:24;23868:37;23864:42;23849:58;23834:74;;23721:201;-1:-1:-1;;;;23968:1:1;23952:14;;;23948:22;23935:36;;-1:-1:-1;22939:1299:1:o;24243:245::-;24310:6;24363:2;24351:9;24342:7;24338:23;24334:32;24331:52;;;24379:1;24376;24369:12;24331:52;24411:9;24405:16;24430:28;24452:5;24430:28;:::i;24904:485::-;-1:-1:-1;;;;;25135:32:1;;;25117:51;;25204:32;;25199:2;25184:18;;25177:60;25268:2;25253:18;;25246:34;;;25316:3;25311:2;25296:18;;25289:31;;;-1:-1:-1;;25337:46:1;;25363:19;;25355:6;25337:46;:::i;25394:249::-;25463:6;25516:2;25504:9;25495:7;25491:23;25487:32;25484:52;;;25532:1;25529;25522:12;25484:52;25564:9;25558:16;25583:30;25607:5;25583:30;:::i
Swarm Source
ipfs://733f3b755285dd6711ae30379e134c2d199d910fdbd061a873059f6f8cfcd575
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.