Contract Overview
Balance:
0 CRO
CRO Value:
$0.00
My Name Tag:
Not Available, login to update
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0x51f48b1961b8c4cc5178fea19d4d7b44aa23426d0cce8b1fc81e6a94f639113a | Initialize | 3740526 | 619 days 8 hrs ago | Tectonic: Deployer | IN | 0xd838e27de51b20e8f4b6b4da12088ad5eed90a90 | 0 CRO | 0.802870205755 | |
0xe2c2224c1f09de31730ada949d35cdcf7ffb601c8ecf385f128942661757a21a | 0x60a06040 | 2116462 | 730 days 2 hrs ago | Tectonic: Deployer | IN | Create: TectonicStakingPoolV2 | 0 CRO | 23.88651 |
[ Download CSV Export ]
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
TectonicStakingPoolV2
Compiler Version
v0.8.3+commit.8d00100c
Contract Source Code (Solidity)
/** *Submitted for verification at cronoscan.com on 2022-03-29 */ // Sources flattened with hardhat v2.6.4 https://hardhat.org // File @openzeppelin/contracts-upgradeable/utils/[email protected] // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Address.sol) pragma solidity ^0.8.0; /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, "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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(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) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason 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 { // 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File @openzeppelin/contracts-upgradeable/proxy/utils/[email protected] // OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; /** * @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 a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [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 initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the // contract may have been reentered. require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} modifier, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } } // File @openzeppelin/contracts-upgradeable/utils/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { __Context_init_unchained(); } 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; } uint256[50] private __gap; } // File @openzeppelin/contracts-upgradeable/access/[email protected] // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Context_init_unchained(); __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } uint256[49] private __gap; } // File @openzeppelin/contracts-upgradeable/security/[email protected] // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) 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() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } uint256[49] private __gap; } // File openzeppelin-solidity/contracts/token/ERC20/[email protected] pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, uint256 amount ) external returns (bool); /** * @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); } // File openzeppelin-solidity/contracts/token/ERC20/extensions/[email protected] pragma solidity ^0.8.0; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File openzeppelin-solidity/contracts/utils/[email protected] pragma solidity ^0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File openzeppelin-solidity/contracts/token/ERC20/[email protected] pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} } // File openzeppelin-solidity/contracts/token/ERC20/extensions/[email protected] pragma solidity ^0.8.0; /** * @dev Extension of {ERC20} that allows token holders to destroy both their own * tokens and those that they have an allowance for, in a way that can be * recognized off-chain (via event analysis). */ abstract contract ERC20Burnable is Context, ERC20 { /** * @dev Destroys `amount` tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 amount) public virtual { _burn(_msgSender(), amount); } /** * @dev Destroys `amount` tokens from `account`, deducting from the caller's * allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `amount`. */ function burnFrom(address account, uint256 amount) public virtual { uint256 currentAllowance = allowance(account, _msgSender()); require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance"); unchecked { _approve(account, _msgSender(), currentAllowance - amount); } _burn(account, amount); } } // File openzeppelin-solidity/contracts/security/[email protected] 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 Pausable is Context { /** * @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. */ constructor() { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { 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()); } } // File openzeppelin-solidity/contracts/token/ERC20/extensions/[email protected] pragma solidity ^0.8.0; /** * @dev ERC20 token with pausable token transfers, minting and burning. * * Useful for scenarios such as preventing trades until the end of an evaluation * period, or having an emergency switch for freezing all token transfers in the * event of a large bug. */ abstract contract ERC20Pausable is ERC20, Pausable { /** * @dev See {ERC20-_beforeTokenTransfer}. * * Requirements: * * - the contract must not be paused. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual override { super._beforeTokenTransfer(from, to, amount); require(!paused(), "ERC20Pausable: token transfer while paused"); } } // File openzeppelin-solidity/contracts/utils/[email protected] pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { 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_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } } // File openzeppelin-solidity/contracts/utils/introspection/[email protected] pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File openzeppelin-solidity/contracts/utils/introspection/[email protected] pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 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); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File openzeppelin-solidity/contracts/access/[email protected] pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { function hasRole(bytes32 role, address account) external view returns (bool); function getRoleAdmin(bytes32 role) external view returns (bytes32); function grantRole(bytes32 role, address account) external; function revokeRole(bytes32 role, address account) external; function renounceRole(bytes32 role, address account) external; } /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{20}) is missing role (0x[0-9a-f]{32})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role, _msgSender()); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{20}) is missing role (0x[0-9a-f]{32})$/ */ function _checkRole(bytes32 role, address account) internal view { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(uint160(account), 20), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { emit RoleAdminChanged(role, getRoleAdmin(role), adminRole); _roles[role].adminRole = adminRole; } function _grantRole(bytes32 role, address account) private { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } function _revokeRole(bytes32 role, address account) private { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } } // File openzeppelin-solidity/contracts/utils/structs/[email protected] pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } } // File openzeppelin-solidity/contracts/access/[email protected] pragma solidity ^0.8.0; /** * @dev External interface of AccessControlEnumerable declared to support ERC165 detection. */ interface IAccessControlEnumerable { function getRoleMember(bytes32 role, uint256 index) external view returns (address); function getRoleMemberCount(bytes32 role) external view returns (uint256); } /** * @dev Extension of {AccessControl} that allows enumerating the members of each role. */ abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl { using EnumerableSet for EnumerableSet.AddressSet; mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view override returns (address) { return _roleMembers[role].at(index); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view override returns (uint256) { return _roleMembers[role].length(); } /** * @dev Overload {grantRole} to track enumerable memberships */ function grantRole(bytes32 role, address account) public virtual override { super.grantRole(role, account); _roleMembers[role].add(account); } /** * @dev Overload {revokeRole} to track enumerable memberships */ function revokeRole(bytes32 role, address account) public virtual override { super.revokeRole(role, account); _roleMembers[role].remove(account); } /** * @dev Overload {renounceRole} to track enumerable memberships */ function renounceRole(bytes32 role, address account) public virtual override { super.renounceRole(role, account); _roleMembers[role].remove(account); } /** * @dev Overload {_setupRole} to track enumerable memberships */ function _setupRole(bytes32 role, address account) internal virtual override { super._setupRole(role, account); _roleMembers[role].add(account); } } // File openzeppelin-solidity/contracts/token/ERC20/presets/[email protected] pragma solidity ^0.8.0; /** * @dev {ERC20} token, including: * * - ability for holders to burn (destroy) their tokens * - a minter role that allows for token minting (creation) * - a pauser role that allows to stop all token transfers * * This contract uses {AccessControl} to lock permissioned functions using the * different roles - head to its documentation for details. * * The account that deploys the contract will be granted the minter and pauser * roles, as well as the default admin role, which will let it grant both minter * and pauser roles to other accounts. */ contract ERC20PresetMinterPauser is Context, AccessControlEnumerable, ERC20Burnable, ERC20Pausable { bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); /** * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the * account that deploys the contract. * * See {ERC20-constructor}. */ constructor(string memory name, string memory symbol) ERC20(name, symbol) { _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); _setupRole(MINTER_ROLE, _msgSender()); _setupRole(PAUSER_ROLE, _msgSender()); } /** * @dev Creates `amount` new tokens for `to`. * * See {ERC20-_mint}. * * Requirements: * * - the caller must have the `MINTER_ROLE`. */ function mint(address to, uint256 amount) public virtual { require(hasRole(MINTER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have minter role to mint"); _mint(to, amount); } /** * @dev Pauses all token transfers. * * See {ERC20Pausable} and {Pausable-_pause}. * * Requirements: * * - the caller must have the `PAUSER_ROLE`. */ function pause() public virtual { require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have pauser role to pause"); _pause(); } /** * @dev Unpauses all token transfers. * * See {ERC20Pausable} and {Pausable-_unpause}. * * Requirements: * * - the caller must have the `PAUSER_ROLE`. */ function unpause() public virtual { require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have pauser role to unpause"); _unpause(); } function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual override(ERC20, ERC20Pausable) { super._beforeTokenTransfer(from, to, amount); } } // File contracts/StakingPool/xTonic.sol pragma solidity ^0.8.0; contract xTonic is ERC20PresetMinterPauser { constructor () ERC20PresetMinterPauser("xTONIC", "xTONIC") {} function transferMinterRole(address _newMinter) public { require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "xTONIC: must have admin role to transfer"); grantRole(MINTER_ROLE, _newMinter); if (hasRole(MINTER_ROLE, _msgSender())) { revokeRole(MINTER_ROLE, _msgSender()); } } } // File contracts/StakingPool/TectonicStakingPoolStorage.sol pragma solidity ^0.8.0; contract TectonicStakingPoolStorageV1 { address public _tonic; xTonic public _xTonic; mapping (address => uint) _cooldownBlockNum; // The block number which user can release his staked tokens. mapping (address => uint) _cooldownTokens; uint32 public _cooldownPeriod; bool public tcmPublicAccess; } contract TectonicStakingPoolStorageV2 { mapping (address => bool) public allowedConversionCallers; mapping (address => uint256 ) public withdrawalExchangeRates; } // File contracts/Interfaces/IVVSRouter02.sol pragma solidity ^0.8.0; interface IVVSRouter02 { function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; } // File contracts/Interfaces/IPriceOracle.sol pragma solidity ^0.8.0; interface IPriceOracle { function getPrice(ERC20 _token) external view returns (uint); } // File openzeppelin-solidity/contracts/utils/[email protected] pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, "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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return _verifyCallResult(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) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(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) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) private pure returns (bytes memory) { if (success) { return returndata; } else { // 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File openzeppelin-solidity/contracts/token/ERC20/utils/[email protected] 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 SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 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( IERC20 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)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @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(IERC20 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"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File contracts/StakingPool/TCMClient.sol pragma solidity ^0.8.0; abstract contract TokenConversionClient is Initializable { using EnumerableSet for EnumerableSet.AddressSet; using SafeERC20 for ERC20; event ConversionsPerformed( address[][] paths, uint[] amounts, uint[] errorCodes, uint tonicAmount ); event TokenRegistered( address token ); event TokenDeregistered( address token ); event CallerRewardChanged( uint oldRewardRatio, uint newRewardRatio ); event ImplementationChanged( address oldImplementation, address newImplementation ); // This contract is used as a sort of interface to the TokenConversionModule contract. Inherit from it to use TokenConversionModule // It manages the current implementation and does delegatecalls to it for all supported function address public tcmImplementation; EnumerableSet.AddressSet registeredTokens; uint public callerRewardRatio; uint public constant callerRewardBase = 1 ether; modifier onlyRegisteredInputTokens(address[][] memory _paths) { for(uint i = 0; i < _paths.length; i++){ require(registeredTokens.contains(_paths[i][0]), "Input token is not registered"); } _; } function tcmClient_initialize(address _tcmImplementation, uint _callerRewardRatio) internal { _setTcmImplementation(_tcmImplementation); _setCallerRewardRatio(_callerRewardRatio); } function _setTcmImplementation(address _tcmImplementation) internal { require(_tcmImplementation != address(0), "tcmImplementation cannot be the zero address"); bool isUpdate = tcmImplementation != address(0); emit ImplementationChanged(tcmImplementation, _tcmImplementation); tcmImplementation = _tcmImplementation; } function _performConversionForTokens( address[][] memory _paths, uint[] memory _amounts ) onlyRegisteredInputTokens(_paths) internal returns( uint[] memory errorCodes, uint tonicAmount, uint minTonicAmount ) { require(_paths.length == _amounts.length, "Paths and amounts must be of the same length"); uint[] memory amounts; (errorCodes, amounts, tonicAmount, minTonicAmount) = abi.decode( _delegate(abi.encodeWithSignature("performConversionForTokens(address[][],uint256[])", _paths, _amounts)), (uint[], uint[], uint, uint) ); _rewardCaller(tonicAmount, minTonicAmount); emit ConversionsPerformed(_paths, amounts, errorCodes, tonicAmount); } function _performConversionForTokensFullBalance( address[][] memory _paths ) internal onlyRegisteredInputTokens(_paths) returns( uint[] memory errorCodes, uint tonicAmount, uint minTonicAmount ){ uint[] memory amounts; (errorCodes, amounts, tonicAmount, minTonicAmount) = abi.decode( _delegate(abi.encodeWithSignature("performConversionForTokensFullBalance(address[][])", _paths)), (uint[], uint[], uint, uint) ); _rewardCaller(tonicAmount, minTonicAmount); emit ConversionsPerformed(_paths, amounts, errorCodes, tonicAmount); } // TODO: These view methods are for testing andprobably not needed in production. Review / Remove before deploying. function _getVvsAddress() internal view returns (address){ return abi.decode(_delegateStatic(abi.encodeWithSignature("getVvsAddress()")), (address)); } function _getTonicAddress() internal view returns (address){ return abi.decode(_delegateStatic(abi.encodeWithSignature("getTonicAddress()")), (address)); } function _getEthAddress() internal view returns (address){ return abi.decode(_delegateStatic(abi.encodeWithSignature("getEthAddress()")), (address)); } function _getRegisteredTokens() internal view returns (address[] memory registeredTokensArray){ registeredTokensArray = new address[](registeredTokens.length()); for(uint i = 0; i < registeredTokens.length(); i++){ registeredTokensArray[i] = registeredTokens.at(i); } } function _registerTokens(address[] memory _tokens) internal { for(uint i = 0; i < _tokens.length; i++){ _registerToken(_tokens[i]); } } function _registerToken(address _token) internal { require(!registeredTokens.contains(_token), "Token already registered"); registeredTokens.add(_token); emit TokenRegistered(_token); } function _deregisterToken(address _token) internal { require(registeredTokens.contains(_token), "Token is not registered"); registeredTokens.remove(_token); emit TokenDeregistered(_token); } function _setCallerRewardRatio(uint _callerRewardRatio) internal { require(_callerRewardRatio < callerRewardBase, "Caller reward ratio must be less than 100%"); emit CallerRewardChanged(callerRewardRatio, _callerRewardRatio); callerRewardRatio = _callerRewardRatio; } // TODO: Review if we want to let the user specify the address to receive the reward on function _rewardCaller(uint _tonicAmount, uint _minTonicAmount) internal { if(_tonicAmount == 0) return; uint rewardAmount = ((_tonicAmount - _minTonicAmount) * callerRewardRatio) / callerRewardBase; address tonicAddress = _getTonicAddress(); ERC20(tonicAddress).safeTransfer(msg.sender, rewardAmount); } function _delegate(bytes memory callData) internal returns (bytes memory returnData) { bool success; (success, returnData) = tcmImplementation.delegatecall(callData); require(success, string(returnData)); } // This method is used to allow delegatecalls in view methods // source: https://ethereum.stackexchange.com/questions/82342/how-to-perform-delegate-call-inside-of-view-call-staticall function _delegateStatic(bytes memory callData) internal view returns (bytes memory returnData) { bool success; (success, returnData) = address(this).staticcall(callData); require(success, string(returnData)); } // This fallback is used to allow delegatecalls in view methods // and also to enable the implementation to do external calls on itself (as in the try catch block for performConversionForToken) fallback(bytes calldata callData) external returns(bytes memory){ require(msg.sender == address(this)); return _delegate(callData); } } // File contracts/StakingPool/TectonicStakingPool.sol pragma solidity ^0.8.0; contract TectonicStakingPool is OwnableUpgradeable, ReentrancyGuardUpgradeable, TectonicStakingPoolStorageV1, TokenConversionClient { uint public immutable exchangeRateBase = 1e20; // Events event TonicStaked(address indexed user, uint tonicStaked, uint xTonicMinted); event TonicUnstaked(address indexed user, uint xTonicLocked, uint releasableBlockNum); event TonicReleased(address indexed user, uint xTonicBurned, uint tonicReleased); event ExchangeRateUpdated(uint newExchangeRate, uint timestamp); event CooldownChanged(uint oldCooldown, uint newCooldown); function initialize(address xTonicAddress, address tonicAddress, uint32 cooldownPeriod, address tcmImplementation, uint callerRewardRatio) public initializer { // Initialize the base contract and TCM __Ownable_init(); TokenConversionClient.tcmClient_initialize(tcmImplementation, callerRewardRatio); // Set TONIC token address _tonic = tonicAddress; // Set xTONIC token address. The TectonicStakingPool should become its authorized minter _xTonic = xTonic(xTonicAddress); // cooldownPeriod in blocks for unstaking _cooldownPeriod = cooldownPeriod; } // amount: Tonic Amount to stake function stake(uint amount) external { // Caculate the exchange rate before transferring to avoid math errors uint exchangeRate = getExchangeRateInternal(); require(amount >= 100 ether, "Amount must be equal to or greater than 100 TONIC"); require(doTransferTonicIn(amount), "Tonic: Transfer failed"); // Mint xTonic and transfer to user uint mintAmount = amount * exchangeRate / exchangeRateBase; mintForUser(msg.sender, mintAmount); emit TonicStaked(msg.sender, amount, mintAmount); } // amount: xTonic amount to unstake function unstake(uint amount) external virtual { // ensure the user have enough xTonic to unstake require(xTonic(_xTonic).balanceOf(msg.sender) >= amount, "No enough xTonic to unstake"); // ensure this contract have allowance to spend xTonic require(xTonic(_xTonic).allowance(msg.sender, address(this)) >= amount, "No enough allowance to spend xTonic"); // Transfer unstaked amount to this contract. During cooldown period, the xTonic will be locked in Staking Pool require(doTransferXTonicIn(amount), "xTonic: Transfer failed"); // Increase cooldownTokens _cooldownTokens[msg.sender] = _cooldownTokens[msg.sender] + amount; // Set cooldown block number _cooldownBlockNum[msg.sender] = block.number + _cooldownPeriod; emit TonicUnstaked(msg.sender, amount, _cooldownBlockNum[msg.sender]); } function release() external virtual { require(getReleasableTokens(msg.sender) > 0, "No available tokens for release"); uint tokenToRelease = getReleasableTokens(msg.sender); uint exchangeRate = getExchangeRateInternal(); uint tonicAmount = tokenToRelease * exchangeRateBase / exchangeRate; // Clear cooldown _cooldownTokens[msg.sender] = 0; _cooldownBlockNum[msg.sender] = 0; // Burn xTonic xTonic(_xTonic).burn(tokenToRelease); // Redeem Tonic and transfer back to the user // If exceed the max amount of pooled tonic, only transfer the max amount uint poolTonicAmount = IERC20(_tonic).balanceOf(address(this)); if (tonicAmount > poolTonicAmount) { tonicAmount = poolTonicAmount; } IERC20(_tonic).transfer(msg.sender, tonicAmount); emit TonicReleased(msg.sender, tokenToRelease, tonicAmount); } // Use by admin: To pull TONIC reserve out from the pool to a destination address function emergencyPull(uint amount, address dstAddress) onlyOwner external { require(amount > 0, "Amount must be greater than 0"); require(dstAddress != address(0), "Cannot pull to zero address"); // Transfer TONIC to destination address IERC20(_tonic).transfer(dstAddress, amount); } // anyone can call to increase the tonic reserve, an event will be emitted function contribute(uint amount) external { require(doTransferTonicIn(amount), "Tonic: Transfer failed"); uint exchangeRateAfter = getExchangeRateInternal(); emit ExchangeRateUpdated(exchangeRateAfter, block.timestamp); } // View functions function getReleasableTokens(address user) public view returns (uint) { // Return 0 if user has no cooldown tokens if (_cooldownTokens[user] == 0 || _cooldownBlockNum[user] == 0) { return 0; } uint cooldownTokens = _cooldownTokens[user]; if (block.number > _cooldownBlockNum[user]) { return cooldownTokens; } else { return 0; } } function getExchangeRate() public view returns (uint) { return getExchangeRateInternal(); } function getCooldownTokens(address user) public view returns (uint) { return _cooldownTokens[user]; } function getCooldownBlockNum(address user) public view returns (uint) { return _cooldownBlockNum[user]; } // TCM associated functions (Public) function performConversionForTokens( address[][] memory _paths, uint[] memory _amounts ) external virtual returns ( uint[] memory errorCodes, uint tonicAmount, uint minTonicAmount ) { require(tcmPublicAccess || msg.sender == owner(), "Public access to token conversion is not enabled"); uint beforeExchangeRate = getExchangeRateInternal(); (uint[] memory _errorCodes, uint _tonicAmount, uint _minTonicAmount) = _performConversionForTokens(_paths, _amounts); uint afterExchangeRate = getExchangeRateInternal(); if (afterExchangeRate != beforeExchangeRate) { emit ExchangeRateUpdated(afterExchangeRate, block.timestamp); } return (_errorCodes, _tonicAmount, _minTonicAmount); } function performConversionForTokensFullBalance( address[][] memory _paths ) external virtual returns ( uint[] memory errorCodes, uint tonicAmount, uint minTonicAmount ){ require(tcmPublicAccess || msg.sender == owner(), "Public access to token conversion is not enabled"); uint beforeExchangeRate = getExchangeRateInternal(); (uint[] memory _errorCodes, uint _tonicAmount, uint _minTonicAmount) = _performConversionForTokensFullBalance(_paths); uint afterExchangeRate = getExchangeRateInternal(); if (afterExchangeRate != beforeExchangeRate) { emit ExchangeRateUpdated(afterExchangeRate, block.timestamp); } return (_errorCodes, _tonicAmount, _minTonicAmount); } // TCM associated functions (Admin-Only) function registerTokens(address[] memory _tokens) onlyOwner external { _registerTokens(_tokens); } function registerToken(address _token) onlyOwner external { _registerToken(_token); } function deregisterToken(address _token) onlyOwner external { _deregisterToken(_token); } function setCallerRewardRatio(uint _callerRewardRatio) onlyOwner external { _setCallerRewardRatio(_callerRewardRatio); } function setTcmImplementation(address _tcmImplementation) onlyOwner external { _setTcmImplementation(_tcmImplementation); } // Admin-Only functions function setCooldownPeriod(uint32 newCooldownPeriod) onlyOwner external { emit CooldownChanged(_cooldownPeriod, newCooldownPeriod); _cooldownPeriod = newCooldownPeriod; } function enableTcmConvertPublicAccess() onlyOwner external { tcmPublicAccess = true; } // Internal functions function getExchangeRateInternal() internal view returns (uint) { uint tonicBalance = IERC20(_tonic).balanceOf(address(this)); uint xTonicSupply = _xTonic.totalSupply(); if (xTonicSupply == 0) { // Return base exchange rate if the pool is empty return exchangeRateBase; } return xTonicSupply * exchangeRateBase / tonicBalance; } function doTransferTonicIn(uint amount) internal returns (bool) { // TODO: Check balance before and after transfer return IERC20(_tonic).transferFrom(msg.sender, address(this), amount); } function doTransferXTonicIn(uint amount) internal returns (bool) { return IERC20(_xTonic).transferFrom(msg.sender, address(this), amount); } function mintForUser(address to, uint amount) internal { require(to != address(0), "Invalid address"); xTonic(_xTonic).mint(to, amount); } receive() external payable { // TODO: Check if any checks regarding the sender are needed } } // File contracts/StakingPool/TectonicStakingPoolV2.sol pragma solidity ^0.8.0; contract TectonicStakingPoolV2 is TectonicStakingPool, TectonicStakingPoolStorageV2 { modifier isAllowedToConvert() { require(tcmPublicAccess || msg.sender == owner() || allowedConversionCallers[msg.sender], "Caller is not allowed to convert tokens"); _; } // TCM associated functions (Public) function performConversionForTokens( address[][] memory _paths, uint[] memory _amounts ) external override isAllowedToConvert returns ( uint[] memory errorCodes, uint tonicAmount, uint minTonicAmount ) { uint beforeExchangeRate = getExchangeRateInternal(); (uint[] memory _errorCodes, uint _tonicAmount, uint _minTonicAmount) = _performConversionForTokens(_paths, _amounts); uint afterExchangeRate = getExchangeRateInternal(); if (afterExchangeRate != beforeExchangeRate) { emit ExchangeRateUpdated(afterExchangeRate, block.timestamp); } return (_errorCodes, _tonicAmount, _minTonicAmount); } function performConversionForTokensFullBalance( address[][] memory _paths ) external override isAllowedToConvert returns ( uint[] memory errorCodes, uint tonicAmount, uint minTonicAmount ) { uint beforeExchangeRate = getExchangeRateInternal(); (uint[] memory _errorCodes, uint _tonicAmount, uint _minTonicAmount) = _performConversionForTokensFullBalance(_paths); uint afterExchangeRate = getExchangeRateInternal(); if (afterExchangeRate != beforeExchangeRate) { emit ExchangeRateUpdated(afterExchangeRate, block.timestamp); } return (_errorCodes, _tonicAmount, _minTonicAmount); } // TCM associated functions (Admin-Only) function addAllowedConversionCallers(address[] memory _callers) onlyOwner external { for(uint i = 0; i < _callers.length; i++) { allowedConversionCallers[_callers[i]] = true; } } function removeAllowedConversionCallers(address[] memory _callers) onlyOwner external { for(uint i = 0; i < _callers.length; i++) { allowedConversionCallers[_callers[i]] = false; } } // Revised unstaking logic function unstake(uint amount) external override { // ensure the user have enough xTonic to unstake require(xTonic(_xTonic).balanceOf(msg.sender) >= amount, "No enough xTonic to unstake"); // ensure this contract have allowance to spend xTonic require(xTonic(_xTonic).allowance(msg.sender, address(this)) >= amount, "No enough allowance to spend xTonic"); // Transfer unstaked amount to this contract. During cooldown period, the xTonic will be locked in Staking Pool require(doTransferXTonicIn(amount), "xTonic: Transfer failed"); // Increase cooldownTokens _cooldownTokens[msg.sender] = _cooldownTokens[msg.sender] + amount; // Set cooldown block number _cooldownBlockNum[msg.sender] = block.number + _cooldownPeriod; withdrawalExchangeRates[msg.sender] = getExchangeRateInternal(); emit TonicUnstaked(msg.sender, amount, _cooldownBlockNum[msg.sender]); } function release() external override { require(getReleasableTokens(msg.sender) > 0, "No available tokens for release"); uint tokenToRelease = getReleasableTokens(msg.sender); uint exchangeRate = getWithdrawalExchangeRate(msg.sender); uint tonicAmount = tokenToRelease * exchangeRateBase / exchangeRate; // Clear cooldown _cooldownTokens[msg.sender] = 0; _cooldownBlockNum[msg.sender] = 0; // Burn xTonic xTonic(_xTonic).burn(tokenToRelease); // Redeem Tonic and transfer back to the user // If exceed the max amount of pooled tonic, only transfer the max amount uint poolTonicAmount = IERC20(_tonic).balanceOf(address(this)); if (tonicAmount > poolTonicAmount) { tonicAmount = poolTonicAmount; } IERC20(_tonic).transfer(msg.sender, tonicAmount); emit TonicReleased(msg.sender, tokenToRelease, tonicAmount); } function getWithdrawalExchangeRate(address _user) internal returns (uint exchangeRate) { exchangeRate = withdrawalExchangeRates[_user]; uint256 currentExchangeRate = getExchangeRateInternal(); if(exchangeRate < currentExchangeRate || exchangeRate == 0) { exchangeRate = currentExchangeRate; } withdrawalExchangeRates[_user] = 0; return exchangeRate; } }
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldRewardRatio","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newRewardRatio","type":"uint256"}],"name":"CallerRewardChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[][]","name":"paths","type":"address[][]"},{"indexed":false,"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"errorCodes","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"tonicAmount","type":"uint256"}],"name":"ConversionsPerformed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldCooldown","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newCooldown","type":"uint256"}],"name":"CooldownChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newExchangeRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"ExchangeRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldImplementation","type":"address"},{"indexed":false,"internalType":"address","name":"newImplementation","type":"address"}],"name":"ImplementationChanged","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":"token","type":"address"}],"name":"TokenDeregistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"TokenRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"xTonicBurned","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tonicReleased","type":"uint256"}],"name":"TonicReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"tonicStaked","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"xTonicMinted","type":"uint256"}],"name":"TonicStaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"xTonicLocked","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"releasableBlockNum","type":"uint256"}],"name":"TonicUnstaked","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[],"name":"_cooldownPeriod","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_tonic","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_xTonic","outputs":[{"internalType":"contract xTonic","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_callers","type":"address[]"}],"name":"addAllowedConversionCallers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowedConversionCallers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"callerRewardBase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"callerRewardRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"contribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"deregisterToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"dstAddress","type":"address"}],"name":"emergencyPull","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableTcmConvertPublicAccess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"exchangeRateBase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getCooldownBlockNum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getCooldownTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExchangeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getReleasableTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"xTonicAddress","type":"address"},{"internalType":"address","name":"tonicAddress","type":"address"},{"internalType":"uint32","name":"cooldownPeriod","type":"uint32"},{"internalType":"address","name":"tcmImplementation","type":"address"},{"internalType":"uint256","name":"callerRewardRatio","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[][]","name":"_paths","type":"address[][]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"performConversionForTokens","outputs":[{"internalType":"uint256[]","name":"errorCodes","type":"uint256[]"},{"internalType":"uint256","name":"tonicAmount","type":"uint256"},{"internalType":"uint256","name":"minTonicAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[][]","name":"_paths","type":"address[][]"}],"name":"performConversionForTokensFullBalance","outputs":[{"internalType":"uint256[]","name":"errorCodes","type":"uint256[]"},{"internalType":"uint256","name":"tonicAmount","type":"uint256"},{"internalType":"uint256","name":"minTonicAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"registerToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"}],"name":"registerTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_callers","type":"address[]"}],"name":"removeAllowedConversionCallers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_callerRewardRatio","type":"uint256"}],"name":"setCallerRewardRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"newCooldownPeriod","type":"uint32"}],"name":"setCooldownPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tcmImplementation","type":"address"}],"name":"setTcmImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tcmImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tcmPublicAccess","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"withdrawalExchangeRates","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60a060405268056bc75e2d6310000060809081525034801561002057600080fd5b506080516155ea620000596000396000818161176801528181611f4d015281816120930152818161260e015261263901526155ea6000f3fe6080604052600436106101fd5760003560e01c806386d1a69f1161010d578063b24710e5116100a0578063c9920d071161006f578063c9920d07146107c7578063cb7aab3c146107de578063e6aa216c14610809578063e920978f14610834578063f2fde38b1461085f57610204565b8063b24710e514610721578063bab2af1d1461074c578063bc9b96c714610775578063c1cbbca71461079e57610204565b8063a4b4661d116100dc578063a4b4661d1461067b578063a694fc3a146106a4578063acbbd84a146106cd578063ad6cf644146106f857610204565b806386d1a69f146105d357806386e13927146105ea5780638da5cb5b14610613578063a15fc1ef1461063e57610204565b806341a3c9b411610190578063578af2f31161015f578063578af2f3146104da578063614869d6146105195780636c9ed5bf14610556578063715018a61461057f578063737f41fe1461059657610204565b806341a3c9b4146104205780634c3dae741461045d578063528cf0f014610486578063562d2c91146104af57610204565b8063109f9b91116101cc578063109f9b9114610364578063201514651461038f5780632e17de78146103cc5780633dbd1386146103f557610204565b80630198375c146102a85780630937536d146102d157806309824a80146103105780630fab0e761461033957610204565b3661020457005b34801561021057600080fd5b5060003660603073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461024e57600080fd5b61029b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610888565b9050915050805190602001f35b3480156102b457600080fd5b506102cf60048036038101906102ca9190613fcb565b610966565b005b3480156102dd57600080fd5b506102f860048036038101906102f39190613ea3565b6109ee565b6040516103079392919061476c565b60405180910390f35b34801561031c57600080fd5b5061033760048036038101906103329190613d58565b610b56565b005b34801561034557600080fd5b5061034e610bde565b60405161035b91906147aa565b60405180910390f35b34801561037057600080fd5b50610379610bf1565b60405161038691906147c5565b60405180910390f35b34801561039b57600080fd5b506103b660048036038101906103b19190613d58565b610c17565b6040516103c391906147aa565b60405180910390f35b3480156103d857600080fd5b506103f360048036038101906103ee9190613fcb565b610c37565b005b34801561040157600080fd5b5061040a61102d565b6040516104179190614615565b60405180910390f35b34801561042c57600080fd5b5061044760048036038101906104429190613d58565b611053565b6040516104549190614ae2565b60405180910390f35b34801561046957600080fd5b50610484600480360381019061047f9190613e21565b61106b565b005b34801561049257600080fd5b506104ad60048036038101906104a89190613e21565b6111a2565b005b3480156104bb57600080fd5b506104c46112d9565b6040516104d19190614ae2565b60405180910390f35b3480156104e657600080fd5b5061050160048036038101906104fc9190613e62565b6112df565b6040516105109392919061476c565b60405180910390f35b34801561052557600080fd5b50610540600480360381019061053b9190613d58565b611446565b60405161054d9190614ae2565b60405180910390f35b34801561056257600080fd5b5061057d60048036038101906105789190613daa565b61148f565b005b34801561058b57600080fd5b5061059461162d565b005b3480156105a257600080fd5b506105bd60048036038101906105b89190613d58565b6116b5565b6040516105ca9190614ae2565b60405180910390f35b3480156105df57600080fd5b506105e86116fe565b005b3480156105f657600080fd5b50610611600480360381019061060c919061401d565b611a76565b005b34801561061f57600080fd5b50610628611c59565b6040516106359190614615565b60405180910390f35b34801561064a57600080fd5b5061066560048036038101906106609190613d58565b611c83565b6040516106729190614ae2565b60405180910390f35b34801561068757600080fd5b506106a2600480360381019061069d9190614059565b611dbe565b005b3480156106b057600080fd5b506106cb60048036038101906106c69190613fcb565b611ea9565b005b3480156106d957600080fd5b506106e2611fe3565b6040516106ef9190614615565b60405180910390f35b34801561070457600080fd5b5061071f600480360381019061071a9190613d58565b612009565b005b34801561072d57600080fd5b50610736612091565b6040516107439190614ae2565b60405180910390f35b34801561075857600080fd5b50610773600480360381019061076e9190613d58565b6120b5565b005b34801561078157600080fd5b5061079c60048036038101906107979190613e21565b61213d565b005b3480156107aa57600080fd5b506107c560048036038101906107c09190613fcb565b6121c5565b005b3480156107d357600080fd5b506107dc612256565b005b3480156107ea57600080fd5b506107f36122ef565b6040516108009190614ae2565b60405180910390f35b34801561081557600080fd5b5061081e6122fb565b60405161082b9190614ae2565b60405180910390f35b34801561084057600080fd5b5061084961230a565b6040516108569190614b26565b60405180910390f35b34801561086b57600080fd5b5061088660048036038101906108819190613d58565b612320565b005b60606000609b60059054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16836040516108d391906145fe565b600060405180830381855af49150503d806000811461090e576040519150601f19603f3d011682016040523d82523d6000602084013e610913565b606091505b50809350819250505080829061095f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095691906147e0565b60405180910390fd5b5050919050565b61096e612418565b73ffffffffffffffffffffffffffffffffffffffff1661098c611c59565b73ffffffffffffffffffffffffffffffffffffffff16146109e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109d990614982565b60405180910390fd5b6109eb81612420565b50565b6060600080609b60049054906101000a900460ff1680610a405750610a11611c59565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b80610a945750609f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b610ad3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aca90614802565b60405180910390fd5b6000610add6124af565b90506000806000610aee8989612675565b9250925092506000610afe6124af565b9050848114610b41577fc8d1043f24843c0a1c9251fdc30017d84e87498fbcf232af9f86816b5e182bde8142604051610b38929190614afd565b60405180910390a15b83838397509750975050505050509250925092565b610b5e612418565b73ffffffffffffffffffffffffffffffffffffffff16610b7c611c59565b73ffffffffffffffffffffffffffffffffffffffff1614610bd2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc990614982565b60405180910390fd5b610bdb816128c0565b50565b609b60049054906101000a900460ff1681565b609860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b609f6020528060005260406000206000915054906101000a900460ff1681565b80609860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401610c939190614615565b60206040518083038186803b158015610cab57600080fd5b505afa158015610cbf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce39190613ff4565b1015610d24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1b90614a42565b60405180910390fd5b80609860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b8152600401610d82929190614630565b60206040518083038186803b158015610d9a57600080fd5b505afa158015610dae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd29190613ff4565b1015610e13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0a906148a2565b60405180910390fd5b610e1c81612963565b610e5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5290614922565b60405180910390fd5b80609a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610ea69190614cf0565b609a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550609b60009054906101000a900463ffffffff1663ffffffff1643610f0d9190614cf0565b609960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610f586124af565b60a060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff167f87259e912a5ed237b56573e0344f148d7722cfb26e8be1434fdcd91a1cee0dc882609960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054604051611022929190614afd565b60405180910390a250565b609760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60a06020528060005260406000206000915090505481565b611073612418565b73ffffffffffffffffffffffffffffffffffffffff16611091611c59565b73ffffffffffffffffffffffffffffffffffffffff16146110e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110de90614982565b60405180910390fd5b60005b815181101561119e576001609f6000848481518110611132577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061119690614f09565b9150506110ea565b5050565b6111aa612418565b73ffffffffffffffffffffffffffffffffffffffff166111c8611c59565b73ffffffffffffffffffffffffffffffffffffffff161461121e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121590614982565b60405180910390fd5b60005b81518110156112d5576000609f6000848481518110611269577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555080806112cd90614f09565b915050611221565b5050565b609e5481565b6060600080609b60049054906101000a900460ff16806113315750611302611c59565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b806113855750609f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6113c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113bb90614802565b60405180910390fd5b60006113ce6124af565b905060008060006113de88612a1d565b92509250925060006113ee6124af565b9050848114611431577fc8d1043f24843c0a1c9251fdc30017d84e87498fbcf232af9f86816b5e182bde8142604051611428929190614afd565b60405180910390a15b83838397509750975050505050509193909250565b6000609a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600060019054906101000a900460ff166114b75760008054906101000a900460ff16156114c0565b6114bf612c22565b5b6114ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f690614942565b60405180910390fd5b60008060019054906101000a900460ff16159050801561154f576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b611557612c33565b6115618383612c94565b84609760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555085609860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083609b60006101000a81548163ffffffff021916908363ffffffff16021790555080156116255760008060016101000a81548160ff0219169083151502179055505b505050505050565b611635612418565b73ffffffffffffffffffffffffffffffffffffffff16611653611c59565b73ffffffffffffffffffffffffffffffffffffffff16146116a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116a090614982565b60405180910390fd5b6116b36000612caa565b565b6000609960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600061170933611c83565b11611749576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611740906149c2565b60405180910390fd5b600061175433611c83565b9050600061176133612d70565b90506000817f0000000000000000000000000000000000000000000000000000000000000000846117929190614d77565b61179c9190614d46565b90506000609a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000609960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550609860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68846040518263ffffffff1660e01b81526004016118839190614ae2565b600060405180830381600087803b15801561189d57600080fd5b505af11580156118b1573d6000803e3d6000fd5b505050506000609760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016119129190614615565b60206040518083038186803b15801561192a57600080fd5b505afa15801561193e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119629190613ff4565b905080821115611970578091505b609760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b81526004016119cd929190614690565b602060405180830381600087803b1580156119e757600080fd5b505af11580156119fb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1f9190613fa2565b503373ffffffffffffffffffffffffffffffffffffffff167f05d5932bcec8703632de6d5ab41f329f9a3e0ee5b6604839bf44bd6211ed442c8584604051611a68929190614afd565b60405180910390a250505050565b611a7e612418565b73ffffffffffffffffffffffffffffffffffffffff16611a9c611c59565b73ffffffffffffffffffffffffffffffffffffffff1614611af2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ae990614982565b60405180910390fd5b60008211611b35576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b2c90614882565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611ba5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9c90614962565b60405180910390fd5b609760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb82846040518363ffffffff1660e01b8152600401611c02929190614690565b602060405180830381600087803b158015611c1c57600080fd5b505af1158015611c30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c549190613fa2565b505050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600080609a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541480611d1157506000609960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054145b15611d1f5760009050611db9565b6000609a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050609960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054431115611db35780915050611db9565b60009150505b919050565b611dc6612418565b73ffffffffffffffffffffffffffffffffffffffff16611de4611c59565b73ffffffffffffffffffffffffffffffffffffffff1614611e3a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e3190614982565b60405180910390fd5b7f0731af75921ee6c66096a5c95daa1adcf95ff01e0ce8063a2369cb218ee4bcc9609b60009054906101000a900463ffffffff1682604051611e7d929190614b41565b60405180910390a180609b60006101000a81548163ffffffff021916908363ffffffff16021790555050565b6000611eb36124af565b905068056bc75e2d63100000821015611f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef890614902565b60405180910390fd5b611f0a82612e22565b611f49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f4090614a82565b60405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000008284611f789190614d77565b611f829190614d46565b9050611f8e3382612edc565b3373ffffffffffffffffffffffffffffffffffffffff167f89862a6c8c8e54095c5bdd8e96be8d4d993c6d5e94f7499441b1ebb1379df5d38483604051611fd6929190614afd565b60405180910390a2505050565b609b60059054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b612011612418565b73ffffffffffffffffffffffffffffffffffffffff1661202f611c59565b73ffffffffffffffffffffffffffffffffffffffff1614612085576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161207c90614982565b60405180910390fd5b61208e81612fdf565b50565b7f000000000000000000000000000000000000000000000000000000000000000081565b6120bd612418565b73ffffffffffffffffffffffffffffffffffffffff166120db611c59565b73ffffffffffffffffffffffffffffffffffffffff1614612131576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161212890614982565b60405180910390fd5b61213a81613145565b50565b612145612418565b73ffffffffffffffffffffffffffffffffffffffff16612163611c59565b73ffffffffffffffffffffffffffffffffffffffff16146121b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121b090614982565b60405180910390fd5b6121c2816131e7565b50565b6121ce81612e22565b61220d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161220490614a82565b60405180910390fd5b60006122176124af565b90507fc8d1043f24843c0a1c9251fdc30017d84e87498fbcf232af9f86816b5e182bde814260405161224a929190614afd565b60405180910390a15050565b61225e612418565b73ffffffffffffffffffffffffffffffffffffffff1661227c611c59565b73ffffffffffffffffffffffffffffffffffffffff16146122d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c990614982565b60405180910390fd5b6001609b60046101000a81548160ff021916908315150217905550565b670de0b6b3a764000081565b60006123056124af565b905090565b609b60009054906101000a900463ffffffff1681565b612328612418565b73ffffffffffffffffffffffffffffffffffffffff16612346611c59565b73ffffffffffffffffffffffffffffffffffffffff161461239c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161239390614982565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561240c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161240390614842565b60405180910390fd5b61241581612caa565b50565b600033905090565b670de0b6b3a7640000811061246a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612461906148e2565b60405180910390fd5b7f1611ae9ee684061e21e25664225775d950bd29d383e917977a3310abd1a8efc5609e548260405161249d929190614afd565b60405180910390a180609e8190555050565b600080609760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161250d9190614615565b60206040518083038186803b15801561252557600080fd5b505afa158015612539573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061255d9190613ff4565b90506000609860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156125c957600080fd5b505afa1580156125dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126019190613ff4565b90506000811415612636577f000000000000000000000000000000000000000000000000000000000000000092505050612672565b817f0000000000000000000000000000000000000000000000000000000000000000826126639190614d77565b61266d9190614d46565b925050505b90565b60606000808460005b815181101561276e5761271c8282815181106126c3577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151600081518110612704577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151609c61325390919063ffffffff16565b61275b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161275290614862565b60405180910390fd5b808061276690614f09565b91505061267e565b5084518651146127b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127aa90614a02565b60405180910390fd5b606061284d87876040516024016127cb9291906146db565b6040516020818303038152906040527f0937536d000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610888565b8060200190518101906128609190613f0f565b8096508197508294508398505050505061287a8484613283565b7f25f7a7c3fd28c094e8424f875e7fc5a751d7b0c31523b39f13f99015600f2734878287876040516128af9493929190614712565b60405180910390a150509250925092565b6128d481609c61325390919063ffffffff16565b15612914576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161290b90614ac2565b60405180910390fd5b61292881609c6132ff90919063ffffffff16565b507f158412daecdc1456d01568828bcdb18464cc7f1ce0215ddbc3f3cfede9d1e63d816040516129589190614615565b60405180910390a150565b6000609860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b81526004016129c493929190614659565b602060405180830381600087803b1580156129de57600080fd5b505af11580156129f2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a169190613fa2565b9050919050565b60606000808360005b8151811015612b1657612ac4828281518110612a6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151600081518110612aac577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151609c61325390919063ffffffff16565b612b03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612afa90614862565b60405180910390fd5b8080612b0e90614f09565b915050612a26565b506060612baf86604051602401612b2d91906146b9565b6040516020818303038152906040527f578af2f3000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610888565b806020019051810190612bc29190613f0f565b80965081975082945083985050505050612bdc8484613283565b7f25f7a7c3fd28c094e8424f875e7fc5a751d7b0c31523b39f13f99015600f273486828787604051612c119493929190614712565b60405180910390a150509193909250565b6000612c2d3061332f565b15905090565b600060019054906101000a900460ff16612c82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c7990614a62565b60405180910390fd5b612c8a613342565b612c92613393565b565b612c9d82612fdf565b612ca681612420565b5050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600060a060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000612dbe6124af565b905080821080612dce5750600082145b15612dd7578091505b600060a060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050919050565b6000609760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b8152600401612e8393929190614659565b602060405180830381600087803b158015612e9d57600080fd5b505af1158015612eb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ed59190613fa2565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612f4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f4390614822565b60405180910390fd5b609860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1983836040518363ffffffff1660e01b8152600401612fa9929190614690565b600060405180830381600087803b158015612fc357600080fd5b505af1158015612fd7573d6000803e3d6000fd5b505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561304f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613046906149a2565b60405180910390fd5b60008073ffffffffffffffffffffffffffffffffffffffff16609b60059054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141590507fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d3609b60059054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040516130f8929190614630565b60405180910390a181609b60056101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b61315981609c61325390919063ffffffff16565b613198576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161318f906149e2565b60405180910390fd5b6131ac81609c6133f490919063ffffffff16565b507f1d735ca20b63676dde668b718be78606b061d6bd7534ff815a90a121a6c084b6816040516131dc9190614615565b60405180910390a150565b60005b815181101561324f5761323c82828151811061322f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101516128c0565b808061324790614f09565b9150506131ea565b5050565b600061327b836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613424565b905092915050565b6000821415613291576132fb565b6000670de0b6b3a7640000609e5483856132ab9190614dd1565b6132b59190614d77565b6132bf9190614d46565b905060006132cb613447565b90506132f833838373ffffffffffffffffffffffffffffffffffffffff166134ec9092919063ffffffff16565b50505b5050565b6000613327836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613572565b905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff16613391576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161338890614a62565b60405180910390fd5b565b600060019054906101000a900460ff166133e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133d990614a62565b60405180910390fd5b6133f26133ed612418565b612caa565b565b600061341c836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6135e2565b905092915050565b600080836001016000848152602001908152602001600020541415905092915050565b60006134d46040516024016040516020818303038152906040527f13be693b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613768565b8060200190518101906134e79190613d81565b905090565b61356d8363a9059cbb60e01b848460405160240161350b929190614690565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613824565b505050565b600061357e8383613424565b6135d75782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506135dc565b600090505b92915050565b6000808360010160008481526020019081526020016000205490506000811461375c5760006001826136149190614dd1565b905060006001866000018054905061362c9190614dd1565b90508181146136e7576000866000018281548110613673577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001549050808760000184815481106136bd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480613721577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050613762565b60009150505b92915050565b606060003073ffffffffffffffffffffffffffffffffffffffff168360405161379191906145fe565b600060405180830381855afa9150503d80600081146137cc576040519150601f19603f3d011682016040523d82523d6000602084013e6137d1565b606091505b50809350819250505080829061381d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161381491906147e0565b60405180910390fd5b5050919050565b6000613886826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166138eb9092919063ffffffff16565b90506000815111156138e657808060200190518101906138a69190613fa2565b6138e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138dc90614aa2565b60405180910390fd5b5b505050565b60606138fa8484600085613903565b90509392505050565b606082471015613948576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161393f906148c2565b60405180910390fd5b61395185613a17565b613990576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161398790614a22565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516139b991906145fe565b60006040518083038185875af1925050503d80600081146139f6576040519150601f19603f3d011682016040523d82523d6000602084013e6139fb565b606091505b5091509150613a0b828286613a2a565b92505050949350505050565b600080823b905060008111915050919050565b60608315613a3a57829050613a8a565b600083511115613a4d5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a8191906147e0565b60405180910390fd5b9392505050565b6000613aa4613a9f84614b8f565b614b6a565b90508083825260208201905082856020860282011115613ac357600080fd5b60005b85811015613af35781613ad98882613c32565b845260208401935060208301925050600181019050613ac6565b5050509392505050565b6000613b10613b0b84614bbb565b614b6a565b9050808382526020820190508260005b85811015613b505781358501613b368882613c5c565b845260208401935060208301925050600181019050613b20565b5050509392505050565b6000613b6d613b6884614be7565b614b6a565b90508083825260208201905082856020860282011115613b8c57600080fd5b60005b85811015613bbc5781613ba28882613d19565b845260208401935060208301925050600181019050613b8f565b5050509392505050565b6000613bd9613bd484614be7565b614b6a565b90508083825260208201905082856020860282011115613bf857600080fd5b60005b85811015613c285781613c0e8882613d2e565b845260208401935060208301925050600181019050613bfb565b5050509392505050565b600081359050613c4181615541565b92915050565b600081519050613c5681615558565b92915050565b600082601f830112613c6d57600080fd5b8135613c7d848260208601613a91565b91505092915050565b600082601f830112613c9757600080fd5b8135613ca7848260208601613afd565b91505092915050565b600082601f830112613cc157600080fd5b8135613cd1848260208601613b5a565b91505092915050565b600082601f830112613ceb57600080fd5b8151613cfb848260208601613bc6565b91505092915050565b600081519050613d138161556f565b92915050565b600081359050613d2881615586565b92915050565b600081519050613d3d81615586565b92915050565b600081359050613d528161559d565b92915050565b600060208284031215613d6a57600080fd5b6000613d7884828501613c32565b91505092915050565b600060208284031215613d9357600080fd5b6000613da184828501613c47565b91505092915050565b600080600080600060a08688031215613dc257600080fd5b6000613dd088828901613c32565b9550506020613de188828901613c32565b9450506040613df288828901613d43565b9350506060613e0388828901613c32565b9250506080613e1488828901613d19565b9150509295509295909350565b600060208284031215613e3357600080fd5b600082013567ffffffffffffffff811115613e4d57600080fd5b613e5984828501613c5c565b91505092915050565b600060208284031215613e7457600080fd5b600082013567ffffffffffffffff811115613e8e57600080fd5b613e9a84828501613c86565b91505092915050565b60008060408385031215613eb657600080fd5b600083013567ffffffffffffffff811115613ed057600080fd5b613edc85828601613c86565b925050602083013567ffffffffffffffff811115613ef957600080fd5b613f0585828601613cb0565b9150509250929050565b60008060008060808587031215613f2557600080fd5b600085015167ffffffffffffffff811115613f3f57600080fd5b613f4b87828801613cda565b945050602085015167ffffffffffffffff811115613f6857600080fd5b613f7487828801613cda565b9350506040613f8587828801613d2e565b9250506060613f9687828801613d2e565b91505092959194509250565b600060208284031215613fb457600080fd5b6000613fc284828501613d04565b91505092915050565b600060208284031215613fdd57600080fd5b6000613feb84828501613d19565b91505092915050565b60006020828403121561400657600080fd5b600061401484828501613d2e565b91505092915050565b6000806040838503121561403057600080fd5b600061403e85828601613d19565b925050602061404f85828601613c32565b9150509250929050565b60006020828403121561406b57600080fd5b600061407984828501613d43565b91505092915050565b600061408e83836140c6565b60208301905092915050565b60006140a683836140e4565b905092915050565b60006140ba83836145c2565b60208301905092915050565b6140cf81614e05565b82525050565b6140de81614e05565b82525050565b60006140ef82614c43565b6140f98185614ca1565b935061410483614c13565b8060005b8381101561413557815161411c8882614082565b975061412783614c7a565b925050600181019050614108565b5085935050505092915050565b600061414d82614c4e565b6141578185614cb2565b93508360208202850161416985614c23565b8060005b858110156141a55784840389528151614186858261409a565b945061419183614c87565b925060208a0199505060018101905061416d565b50829750879550505050505092915050565b60006141c282614c59565b6141cc8185614cc3565b93506141d783614c33565b8060005b838110156142085781516141ef88826140ae565b97506141fa83614c94565b9250506001810190506141db565b5085935050505092915050565b61421e81614e29565b82525050565b600061422f82614c64565b6142398185614cd4565b9350614249818560208601614ea5565b80840191505092915050565b61425e81614e6f565b82525050565b600061426f82614c6f565b6142798185614cdf565b9350614289818560208601614ea5565b61429281614fdf565b840191505092915050565b60006142aa602783614cdf565b91506142b582614ff0565b604082019050919050565b60006142cd600f83614cdf565b91506142d88261503f565b602082019050919050565b60006142f0602683614cdf565b91506142fb82615068565b604082019050919050565b6000614313601d83614cdf565b915061431e826150b7565b602082019050919050565b6000614336601d83614cdf565b9150614341826150e0565b602082019050919050565b6000614359602383614cdf565b915061436482615109565b604082019050919050565b600061437c602683614cdf565b915061438782615158565b604082019050919050565b600061439f602a83614cdf565b91506143aa826151a7565b604082019050919050565b60006143c2603183614cdf565b91506143cd826151f6565b604082019050919050565b60006143e5601783614cdf565b91506143f082615245565b602082019050919050565b6000614408602e83614cdf565b91506144138261526e565b604082019050919050565b600061442b601b83614cdf565b9150614436826152bd565b602082019050919050565b600061444e602083614cdf565b9150614459826152e6565b602082019050919050565b6000614471602c83614cdf565b915061447c8261530f565b604082019050919050565b6000614494601f83614cdf565b915061449f8261535e565b602082019050919050565b60006144b7601783614cdf565b91506144c282615387565b602082019050919050565b60006144da602c83614cdf565b91506144e5826153b0565b604082019050919050565b60006144fd601d83614cdf565b9150614508826153ff565b602082019050919050565b6000614520601b83614cdf565b915061452b82615428565b602082019050919050565b6000614543602b83614cdf565b915061454e82615451565b604082019050919050565b6000614566601683614cdf565b9150614571826154a0565b602082019050919050565b6000614589602a83614cdf565b9150614594826154c9565b604082019050919050565b60006145ac601883614cdf565b91506145b782615518565b602082019050919050565b6145cb81614e55565b82525050565b6145da81614e55565b82525050565b6145e981614e93565b82525050565b6145f881614e5f565b82525050565b600061460a8284614224565b915081905092915050565b600060208201905061462a60008301846140d5565b92915050565b600060408201905061464560008301856140d5565b61465260208301846140d5565b9392505050565b600060608201905061466e60008301866140d5565b61467b60208301856140d5565b61468860408301846145d1565b949350505050565b60006040820190506146a560008301856140d5565b6146b260208301846145d1565b9392505050565b600060208201905081810360008301526146d38184614142565b905092915050565b600060408201905081810360008301526146f58185614142565b9050818103602083015261470981846141b7565b90509392505050565b6000608082019050818103600083015261472c8187614142565b9050818103602083015261474081866141b7565b9050818103604083015261475481856141b7565b905061476360608301846145d1565b95945050505050565b6000606082019050818103600083015261478681866141b7565b905061479560208301856145d1565b6147a260408301846145d1565b949350505050565b60006020820190506147bf6000830184614215565b92915050565b60006020820190506147da6000830184614255565b92915050565b600060208201905081810360008301526147fa8184614264565b905092915050565b6000602082019050818103600083015261481b8161429d565b9050919050565b6000602082019050818103600083015261483b816142c0565b9050919050565b6000602082019050818103600083015261485b816142e3565b9050919050565b6000602082019050818103600083015261487b81614306565b9050919050565b6000602082019050818103600083015261489b81614329565b9050919050565b600060208201905081810360008301526148bb8161434c565b9050919050565b600060208201905081810360008301526148db8161436f565b9050919050565b600060208201905081810360008301526148fb81614392565b9050919050565b6000602082019050818103600083015261491b816143b5565b9050919050565b6000602082019050818103600083015261493b816143d8565b9050919050565b6000602082019050818103600083015261495b816143fb565b9050919050565b6000602082019050818103600083015261497b8161441e565b9050919050565b6000602082019050818103600083015261499b81614441565b9050919050565b600060208201905081810360008301526149bb81614464565b9050919050565b600060208201905081810360008301526149db81614487565b9050919050565b600060208201905081810360008301526149fb816144aa565b9050919050565b60006020820190508181036000830152614a1b816144cd565b9050919050565b60006020820190508181036000830152614a3b816144f0565b9050919050565b60006020820190508181036000830152614a5b81614513565b9050919050565b60006020820190508181036000830152614a7b81614536565b9050919050565b60006020820190508181036000830152614a9b81614559565b9050919050565b60006020820190508181036000830152614abb8161457c565b9050919050565b60006020820190508181036000830152614adb8161459f565b9050919050565b6000602082019050614af760008301846145d1565b92915050565b6000604082019050614b1260008301856145d1565b614b1f60208301846145d1565b9392505050565b6000602082019050614b3b60008301846145ef565b92915050565b6000604082019050614b5660008301856145e0565b614b6360208301846145e0565b9392505050565b6000614b74614b85565b9050614b808282614ed8565b919050565b6000604051905090565b600067ffffffffffffffff821115614baa57614ba9614fb0565b5b602082029050602081019050919050565b600067ffffffffffffffff821115614bd657614bd5614fb0565b5b602082029050602081019050919050565b600067ffffffffffffffff821115614c0257614c01614fb0565b5b602082029050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b6000614cfb82614e55565b9150614d0683614e55565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614d3b57614d3a614f52565b5b828201905092915050565b6000614d5182614e55565b9150614d5c83614e55565b925082614d6c57614d6b614f81565b5b828204905092915050565b6000614d8282614e55565b9150614d8d83614e55565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614dc657614dc5614f52565b5b828202905092915050565b6000614ddc82614e55565b9150614de783614e55565b925082821015614dfa57614df9614f52565b5b828203905092915050565b6000614e1082614e35565b9050919050565b6000614e2282614e35565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff82169050919050565b6000614e7a82614e81565b9050919050565b6000614e8c82614e35565b9050919050565b6000614e9e82614e5f565b9050919050565b60005b83811015614ec3578082015181840152602081019050614ea8565b83811115614ed2576000848401525b50505050565b614ee182614fdf565b810181811067ffffffffffffffff82111715614f0057614eff614fb0565b5b80604052505050565b6000614f1482614e55565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614f4757614f46614f52565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f43616c6c6572206973206e6f7420616c6c6f77656420746f20636f6e7665727460008201527f20746f6b656e7300000000000000000000000000000000000000000000000000602082015250565b7f496e76616c696420616464726573730000000000000000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f496e70757420746f6b656e206973206e6f742072656769737465726564000000600082015250565b7f416d6f756e74206d7573742062652067726561746572207468616e2030000000600082015250565b7f4e6f20656e6f75676820616c6c6f77616e636520746f207370656e642078546f60008201527f6e69630000000000000000000000000000000000000000000000000000000000602082015250565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b7f43616c6c65722072657761726420726174696f206d757374206265206c65737360008201527f207468616e203130302500000000000000000000000000000000000000000000602082015250565b7f416d6f756e74206d75737420626520657175616c20746f206f7220677265617460008201527f6572207468616e2031303020544f4e4943000000000000000000000000000000602082015250565b7f78546f6e69633a205472616e73666572206661696c6564000000000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f43616e6e6f742070756c6c20746f207a65726f20616464726573730000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f74636d496d706c656d656e746174696f6e2063616e6e6f74206265207468652060008201527f7a65726f20616464726573730000000000000000000000000000000000000000602082015250565b7f4e6f20617661696c61626c6520746f6b656e7320666f722072656c6561736500600082015250565b7f546f6b656e206973206e6f742072656769737465726564000000000000000000600082015250565b7f506174687320616e6420616d6f756e7473206d757374206265206f662074686560008201527f2073616d65206c656e6774680000000000000000000000000000000000000000602082015250565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b7f4e6f20656e6f7567682078546f6e696320746f20756e7374616b650000000000600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f546f6e69633a205472616e73666572206661696c656400000000000000000000600082015250565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b7f546f6b656e20616c726561647920726567697374657265640000000000000000600082015250565b61554a81614e05565b811461555557600080fd5b50565b61556181614e17565b811461556c57600080fd5b50565b61557881614e29565b811461558357600080fd5b50565b61558f81614e55565b811461559a57600080fd5b50565b6155a681614e5f565b81146155b157600080fd5b5056fea2646970667358221220fa4ac3966f60195db9f0a12e971c16e6921fd860e60e1bf052fe1816890635bf64736f6c63430008030033
Deployed Bytecode
0x6080604052600436106101fd5760003560e01c806386d1a69f1161010d578063b24710e5116100a0578063c9920d071161006f578063c9920d07146107c7578063cb7aab3c146107de578063e6aa216c14610809578063e920978f14610834578063f2fde38b1461085f57610204565b8063b24710e514610721578063bab2af1d1461074c578063bc9b96c714610775578063c1cbbca71461079e57610204565b8063a4b4661d116100dc578063a4b4661d1461067b578063a694fc3a146106a4578063acbbd84a146106cd578063ad6cf644146106f857610204565b806386d1a69f146105d357806386e13927146105ea5780638da5cb5b14610613578063a15fc1ef1461063e57610204565b806341a3c9b411610190578063578af2f31161015f578063578af2f3146104da578063614869d6146105195780636c9ed5bf14610556578063715018a61461057f578063737f41fe1461059657610204565b806341a3c9b4146104205780634c3dae741461045d578063528cf0f014610486578063562d2c91146104af57610204565b8063109f9b91116101cc578063109f9b9114610364578063201514651461038f5780632e17de78146103cc5780633dbd1386146103f557610204565b80630198375c146102a85780630937536d146102d157806309824a80146103105780630fab0e761461033957610204565b3661020457005b34801561021057600080fd5b5060003660603073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461024e57600080fd5b61029b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610888565b9050915050805190602001f35b3480156102b457600080fd5b506102cf60048036038101906102ca9190613fcb565b610966565b005b3480156102dd57600080fd5b506102f860048036038101906102f39190613ea3565b6109ee565b6040516103079392919061476c565b60405180910390f35b34801561031c57600080fd5b5061033760048036038101906103329190613d58565b610b56565b005b34801561034557600080fd5b5061034e610bde565b60405161035b91906147aa565b60405180910390f35b34801561037057600080fd5b50610379610bf1565b60405161038691906147c5565b60405180910390f35b34801561039b57600080fd5b506103b660048036038101906103b19190613d58565b610c17565b6040516103c391906147aa565b60405180910390f35b3480156103d857600080fd5b506103f360048036038101906103ee9190613fcb565b610c37565b005b34801561040157600080fd5b5061040a61102d565b6040516104179190614615565b60405180910390f35b34801561042c57600080fd5b5061044760048036038101906104429190613d58565b611053565b6040516104549190614ae2565b60405180910390f35b34801561046957600080fd5b50610484600480360381019061047f9190613e21565b61106b565b005b34801561049257600080fd5b506104ad60048036038101906104a89190613e21565b6111a2565b005b3480156104bb57600080fd5b506104c46112d9565b6040516104d19190614ae2565b60405180910390f35b3480156104e657600080fd5b5061050160048036038101906104fc9190613e62565b6112df565b6040516105109392919061476c565b60405180910390f35b34801561052557600080fd5b50610540600480360381019061053b9190613d58565b611446565b60405161054d9190614ae2565b60405180910390f35b34801561056257600080fd5b5061057d60048036038101906105789190613daa565b61148f565b005b34801561058b57600080fd5b5061059461162d565b005b3480156105a257600080fd5b506105bd60048036038101906105b89190613d58565b6116b5565b6040516105ca9190614ae2565b60405180910390f35b3480156105df57600080fd5b506105e86116fe565b005b3480156105f657600080fd5b50610611600480360381019061060c919061401d565b611a76565b005b34801561061f57600080fd5b50610628611c59565b6040516106359190614615565b60405180910390f35b34801561064a57600080fd5b5061066560048036038101906106609190613d58565b611c83565b6040516106729190614ae2565b60405180910390f35b34801561068757600080fd5b506106a2600480360381019061069d9190614059565b611dbe565b005b3480156106b057600080fd5b506106cb60048036038101906106c69190613fcb565b611ea9565b005b3480156106d957600080fd5b506106e2611fe3565b6040516106ef9190614615565b60405180910390f35b34801561070457600080fd5b5061071f600480360381019061071a9190613d58565b612009565b005b34801561072d57600080fd5b50610736612091565b6040516107439190614ae2565b60405180910390f35b34801561075857600080fd5b50610773600480360381019061076e9190613d58565b6120b5565b005b34801561078157600080fd5b5061079c60048036038101906107979190613e21565b61213d565b005b3480156107aa57600080fd5b506107c560048036038101906107c09190613fcb565b6121c5565b005b3480156107d357600080fd5b506107dc612256565b005b3480156107ea57600080fd5b506107f36122ef565b6040516108009190614ae2565b60405180910390f35b34801561081557600080fd5b5061081e6122fb565b60405161082b9190614ae2565b60405180910390f35b34801561084057600080fd5b5061084961230a565b6040516108569190614b26565b60405180910390f35b34801561086b57600080fd5b5061088660048036038101906108819190613d58565b612320565b005b60606000609b60059054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16836040516108d391906145fe565b600060405180830381855af49150503d806000811461090e576040519150601f19603f3d011682016040523d82523d6000602084013e610913565b606091505b50809350819250505080829061095f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095691906147e0565b60405180910390fd5b5050919050565b61096e612418565b73ffffffffffffffffffffffffffffffffffffffff1661098c611c59565b73ffffffffffffffffffffffffffffffffffffffff16146109e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109d990614982565b60405180910390fd5b6109eb81612420565b50565b6060600080609b60049054906101000a900460ff1680610a405750610a11611c59565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b80610a945750609f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b610ad3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aca90614802565b60405180910390fd5b6000610add6124af565b90506000806000610aee8989612675565b9250925092506000610afe6124af565b9050848114610b41577fc8d1043f24843c0a1c9251fdc30017d84e87498fbcf232af9f86816b5e182bde8142604051610b38929190614afd565b60405180910390a15b83838397509750975050505050509250925092565b610b5e612418565b73ffffffffffffffffffffffffffffffffffffffff16610b7c611c59565b73ffffffffffffffffffffffffffffffffffffffff1614610bd2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc990614982565b60405180910390fd5b610bdb816128c0565b50565b609b60049054906101000a900460ff1681565b609860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b609f6020528060005260406000206000915054906101000a900460ff1681565b80609860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401610c939190614615565b60206040518083038186803b158015610cab57600080fd5b505afa158015610cbf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce39190613ff4565b1015610d24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1b90614a42565b60405180910390fd5b80609860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b8152600401610d82929190614630565b60206040518083038186803b158015610d9a57600080fd5b505afa158015610dae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd29190613ff4565b1015610e13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0a906148a2565b60405180910390fd5b610e1c81612963565b610e5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5290614922565b60405180910390fd5b80609a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610ea69190614cf0565b609a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550609b60009054906101000a900463ffffffff1663ffffffff1643610f0d9190614cf0565b609960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610f586124af565b60a060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff167f87259e912a5ed237b56573e0344f148d7722cfb26e8be1434fdcd91a1cee0dc882609960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054604051611022929190614afd565b60405180910390a250565b609760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60a06020528060005260406000206000915090505481565b611073612418565b73ffffffffffffffffffffffffffffffffffffffff16611091611c59565b73ffffffffffffffffffffffffffffffffffffffff16146110e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110de90614982565b60405180910390fd5b60005b815181101561119e576001609f6000848481518110611132577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808061119690614f09565b9150506110ea565b5050565b6111aa612418565b73ffffffffffffffffffffffffffffffffffffffff166111c8611c59565b73ffffffffffffffffffffffffffffffffffffffff161461121e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121590614982565b60405180910390fd5b60005b81518110156112d5576000609f6000848481518110611269577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555080806112cd90614f09565b915050611221565b5050565b609e5481565b6060600080609b60049054906101000a900460ff16806113315750611302611c59565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b806113855750609f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6113c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113bb90614802565b60405180910390fd5b60006113ce6124af565b905060008060006113de88612a1d565b92509250925060006113ee6124af565b9050848114611431577fc8d1043f24843c0a1c9251fdc30017d84e87498fbcf232af9f86816b5e182bde8142604051611428929190614afd565b60405180910390a15b83838397509750975050505050509193909250565b6000609a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600060019054906101000a900460ff166114b75760008054906101000a900460ff16156114c0565b6114bf612c22565b5b6114ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f690614942565b60405180910390fd5b60008060019054906101000a900460ff16159050801561154f576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b611557612c33565b6115618383612c94565b84609760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555085609860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083609b60006101000a81548163ffffffff021916908363ffffffff16021790555080156116255760008060016101000a81548160ff0219169083151502179055505b505050505050565b611635612418565b73ffffffffffffffffffffffffffffffffffffffff16611653611c59565b73ffffffffffffffffffffffffffffffffffffffff16146116a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116a090614982565b60405180910390fd5b6116b36000612caa565b565b6000609960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600061170933611c83565b11611749576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611740906149c2565b60405180910390fd5b600061175433611c83565b9050600061176133612d70565b90506000817f0000000000000000000000000000000000000000000000056bc75e2d63100000846117929190614d77565b61179c9190614d46565b90506000609a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000609960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550609860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68846040518263ffffffff1660e01b81526004016118839190614ae2565b600060405180830381600087803b15801561189d57600080fd5b505af11580156118b1573d6000803e3d6000fd5b505050506000609760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016119129190614615565b60206040518083038186803b15801561192a57600080fd5b505afa15801561193e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119629190613ff4565b905080821115611970578091505b609760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b81526004016119cd929190614690565b602060405180830381600087803b1580156119e757600080fd5b505af11580156119fb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1f9190613fa2565b503373ffffffffffffffffffffffffffffffffffffffff167f05d5932bcec8703632de6d5ab41f329f9a3e0ee5b6604839bf44bd6211ed442c8584604051611a68929190614afd565b60405180910390a250505050565b611a7e612418565b73ffffffffffffffffffffffffffffffffffffffff16611a9c611c59565b73ffffffffffffffffffffffffffffffffffffffff1614611af2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ae990614982565b60405180910390fd5b60008211611b35576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b2c90614882565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611ba5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9c90614962565b60405180910390fd5b609760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb82846040518363ffffffff1660e01b8152600401611c02929190614690565b602060405180830381600087803b158015611c1c57600080fd5b505af1158015611c30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c549190613fa2565b505050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600080609a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541480611d1157506000609960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054145b15611d1f5760009050611db9565b6000609a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050609960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054431115611db35780915050611db9565b60009150505b919050565b611dc6612418565b73ffffffffffffffffffffffffffffffffffffffff16611de4611c59565b73ffffffffffffffffffffffffffffffffffffffff1614611e3a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e3190614982565b60405180910390fd5b7f0731af75921ee6c66096a5c95daa1adcf95ff01e0ce8063a2369cb218ee4bcc9609b60009054906101000a900463ffffffff1682604051611e7d929190614b41565b60405180910390a180609b60006101000a81548163ffffffff021916908363ffffffff16021790555050565b6000611eb36124af565b905068056bc75e2d63100000821015611f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef890614902565b60405180910390fd5b611f0a82612e22565b611f49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f4090614a82565b60405180910390fd5b60007f0000000000000000000000000000000000000000000000056bc75e2d631000008284611f789190614d77565b611f829190614d46565b9050611f8e3382612edc565b3373ffffffffffffffffffffffffffffffffffffffff167f89862a6c8c8e54095c5bdd8e96be8d4d993c6d5e94f7499441b1ebb1379df5d38483604051611fd6929190614afd565b60405180910390a2505050565b609b60059054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b612011612418565b73ffffffffffffffffffffffffffffffffffffffff1661202f611c59565b73ffffffffffffffffffffffffffffffffffffffff1614612085576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161207c90614982565b60405180910390fd5b61208e81612fdf565b50565b7f0000000000000000000000000000000000000000000000056bc75e2d6310000081565b6120bd612418565b73ffffffffffffffffffffffffffffffffffffffff166120db611c59565b73ffffffffffffffffffffffffffffffffffffffff1614612131576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161212890614982565b60405180910390fd5b61213a81613145565b50565b612145612418565b73ffffffffffffffffffffffffffffffffffffffff16612163611c59565b73ffffffffffffffffffffffffffffffffffffffff16146121b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121b090614982565b60405180910390fd5b6121c2816131e7565b50565b6121ce81612e22565b61220d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161220490614a82565b60405180910390fd5b60006122176124af565b90507fc8d1043f24843c0a1c9251fdc30017d84e87498fbcf232af9f86816b5e182bde814260405161224a929190614afd565b60405180910390a15050565b61225e612418565b73ffffffffffffffffffffffffffffffffffffffff1661227c611c59565b73ffffffffffffffffffffffffffffffffffffffff16146122d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c990614982565b60405180910390fd5b6001609b60046101000a81548160ff021916908315150217905550565b670de0b6b3a764000081565b60006123056124af565b905090565b609b60009054906101000a900463ffffffff1681565b612328612418565b73ffffffffffffffffffffffffffffffffffffffff16612346611c59565b73ffffffffffffffffffffffffffffffffffffffff161461239c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161239390614982565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561240c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161240390614842565b60405180910390fd5b61241581612caa565b50565b600033905090565b670de0b6b3a7640000811061246a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612461906148e2565b60405180910390fd5b7f1611ae9ee684061e21e25664225775d950bd29d383e917977a3310abd1a8efc5609e548260405161249d929190614afd565b60405180910390a180609e8190555050565b600080609760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161250d9190614615565b60206040518083038186803b15801561252557600080fd5b505afa158015612539573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061255d9190613ff4565b90506000609860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156125c957600080fd5b505afa1580156125dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126019190613ff4565b90506000811415612636577f0000000000000000000000000000000000000000000000056bc75e2d6310000092505050612672565b817f0000000000000000000000000000000000000000000000056bc75e2d63100000826126639190614d77565b61266d9190614d46565b925050505b90565b60606000808460005b815181101561276e5761271c8282815181106126c3577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151600081518110612704577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151609c61325390919063ffffffff16565b61275b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161275290614862565b60405180910390fd5b808061276690614f09565b91505061267e565b5084518651146127b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127aa90614a02565b60405180910390fd5b606061284d87876040516024016127cb9291906146db565b6040516020818303038152906040527f0937536d000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610888565b8060200190518101906128609190613f0f565b8096508197508294508398505050505061287a8484613283565b7f25f7a7c3fd28c094e8424f875e7fc5a751d7b0c31523b39f13f99015600f2734878287876040516128af9493929190614712565b60405180910390a150509250925092565b6128d481609c61325390919063ffffffff16565b15612914576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161290b90614ac2565b60405180910390fd5b61292881609c6132ff90919063ffffffff16565b507f158412daecdc1456d01568828bcdb18464cc7f1ce0215ddbc3f3cfede9d1e63d816040516129589190614615565b60405180910390a150565b6000609860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b81526004016129c493929190614659565b602060405180830381600087803b1580156129de57600080fd5b505af11580156129f2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a169190613fa2565b9050919050565b60606000808360005b8151811015612b1657612ac4828281518110612a6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151600081518110612aac577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151609c61325390919063ffffffff16565b612b03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612afa90614862565b60405180910390fd5b8080612b0e90614f09565b915050612a26565b506060612baf86604051602401612b2d91906146b9565b6040516020818303038152906040527f578af2f3000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610888565b806020019051810190612bc29190613f0f565b80965081975082945083985050505050612bdc8484613283565b7f25f7a7c3fd28c094e8424f875e7fc5a751d7b0c31523b39f13f99015600f273486828787604051612c119493929190614712565b60405180910390a150509193909250565b6000612c2d3061332f565b15905090565b600060019054906101000a900460ff16612c82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c7990614a62565b60405180910390fd5b612c8a613342565b612c92613393565b565b612c9d82612fdf565b612ca681612420565b5050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600060a060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000612dbe6124af565b905080821080612dce5750600082145b15612dd7578091505b600060a060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050919050565b6000609760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856040518463ffffffff1660e01b8152600401612e8393929190614659565b602060405180830381600087803b158015612e9d57600080fd5b505af1158015612eb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ed59190613fa2565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612f4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f4390614822565b60405180910390fd5b609860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1983836040518363ffffffff1660e01b8152600401612fa9929190614690565b600060405180830381600087803b158015612fc357600080fd5b505af1158015612fd7573d6000803e3d6000fd5b505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561304f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613046906149a2565b60405180910390fd5b60008073ffffffffffffffffffffffffffffffffffffffff16609b60059054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141590507fcfbf4028add9318bbf716f08c348595afb063b0e9feed1f86d33681a4b3ed4d3609b60059054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040516130f8929190614630565b60405180910390a181609b60056101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b61315981609c61325390919063ffffffff16565b613198576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161318f906149e2565b60405180910390fd5b6131ac81609c6133f490919063ffffffff16565b507f1d735ca20b63676dde668b718be78606b061d6bd7534ff815a90a121a6c084b6816040516131dc9190614615565b60405180910390a150565b60005b815181101561324f5761323c82828151811061322f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101516128c0565b808061324790614f09565b9150506131ea565b5050565b600061327b836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613424565b905092915050565b6000821415613291576132fb565b6000670de0b6b3a7640000609e5483856132ab9190614dd1565b6132b59190614d77565b6132bf9190614d46565b905060006132cb613447565b90506132f833838373ffffffffffffffffffffffffffffffffffffffff166134ec9092919063ffffffff16565b50505b5050565b6000613327836000018373ffffffffffffffffffffffffffffffffffffffff1660001b613572565b905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff16613391576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161338890614a62565b60405180910390fd5b565b600060019054906101000a900460ff166133e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016133d990614a62565b60405180910390fd5b6133f26133ed612418565b612caa565b565b600061341c836000018373ffffffffffffffffffffffffffffffffffffffff1660001b6135e2565b905092915050565b600080836001016000848152602001908152602001600020541415905092915050565b60006134d46040516024016040516020818303038152906040527f13be693b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613768565b8060200190518101906134e79190613d81565b905090565b61356d8363a9059cbb60e01b848460405160240161350b929190614690565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613824565b505050565b600061357e8383613424565b6135d75782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506135dc565b600090505b92915050565b6000808360010160008481526020019081526020016000205490506000811461375c5760006001826136149190614dd1565b905060006001866000018054905061362c9190614dd1565b90508181146136e7576000866000018281548110613673577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001549050808760000184815481106136bd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480613721577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050613762565b60009150505b92915050565b606060003073ffffffffffffffffffffffffffffffffffffffff168360405161379191906145fe565b600060405180830381855afa9150503d80600081146137cc576040519150601f19603f3d011682016040523d82523d6000602084013e6137d1565b606091505b50809350819250505080829061381d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161381491906147e0565b60405180910390fd5b5050919050565b6000613886826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166138eb9092919063ffffffff16565b90506000815111156138e657808060200190518101906138a69190613fa2565b6138e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138dc90614aa2565b60405180910390fd5b5b505050565b60606138fa8484600085613903565b90509392505050565b606082471015613948576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161393f906148c2565b60405180910390fd5b61395185613a17565b613990576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161398790614a22565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516139b991906145fe565b60006040518083038185875af1925050503d80600081146139f6576040519150601f19603f3d011682016040523d82523d6000602084013e6139fb565b606091505b5091509150613a0b828286613a2a565b92505050949350505050565b600080823b905060008111915050919050565b60608315613a3a57829050613a8a565b600083511115613a4d5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a8191906147e0565b60405180910390fd5b9392505050565b6000613aa4613a9f84614b8f565b614b6a565b90508083825260208201905082856020860282011115613ac357600080fd5b60005b85811015613af35781613ad98882613c32565b845260208401935060208301925050600181019050613ac6565b5050509392505050565b6000613b10613b0b84614bbb565b614b6a565b9050808382526020820190508260005b85811015613b505781358501613b368882613c5c565b845260208401935060208301925050600181019050613b20565b5050509392505050565b6000613b6d613b6884614be7565b614b6a565b90508083825260208201905082856020860282011115613b8c57600080fd5b60005b85811015613bbc5781613ba28882613d19565b845260208401935060208301925050600181019050613b8f565b5050509392505050565b6000613bd9613bd484614be7565b614b6a565b90508083825260208201905082856020860282011115613bf857600080fd5b60005b85811015613c285781613c0e8882613d2e565b845260208401935060208301925050600181019050613bfb565b5050509392505050565b600081359050613c4181615541565b92915050565b600081519050613c5681615558565b92915050565b600082601f830112613c6d57600080fd5b8135613c7d848260208601613a91565b91505092915050565b600082601f830112613c9757600080fd5b8135613ca7848260208601613afd565b91505092915050565b600082601f830112613cc157600080fd5b8135613cd1848260208601613b5a565b91505092915050565b600082601f830112613ceb57600080fd5b8151613cfb848260208601613bc6565b91505092915050565b600081519050613d138161556f565b92915050565b600081359050613d2881615586565b92915050565b600081519050613d3d81615586565b92915050565b600081359050613d528161559d565b92915050565b600060208284031215613d6a57600080fd5b6000613d7884828501613c32565b91505092915050565b600060208284031215613d9357600080fd5b6000613da184828501613c47565b91505092915050565b600080600080600060a08688031215613dc257600080fd5b6000613dd088828901613c32565b9550506020613de188828901613c32565b9450506040613df288828901613d43565b9350506060613e0388828901613c32565b9250506080613e1488828901613d19565b9150509295509295909350565b600060208284031215613e3357600080fd5b600082013567ffffffffffffffff811115613e4d57600080fd5b613e5984828501613c5c565b91505092915050565b600060208284031215613e7457600080fd5b600082013567ffffffffffffffff811115613e8e57600080fd5b613e9a84828501613c86565b91505092915050565b60008060408385031215613eb657600080fd5b600083013567ffffffffffffffff811115613ed057600080fd5b613edc85828601613c86565b925050602083013567ffffffffffffffff811115613ef957600080fd5b613f0585828601613cb0565b9150509250929050565b60008060008060808587031215613f2557600080fd5b600085015167ffffffffffffffff811115613f3f57600080fd5b613f4b87828801613cda565b945050602085015167ffffffffffffffff811115613f6857600080fd5b613f7487828801613cda565b9350506040613f8587828801613d2e565b9250506060613f9687828801613d2e565b91505092959194509250565b600060208284031215613fb457600080fd5b6000613fc284828501613d04565b91505092915050565b600060208284031215613fdd57600080fd5b6000613feb84828501613d19565b91505092915050565b60006020828403121561400657600080fd5b600061401484828501613d2e565b91505092915050565b6000806040838503121561403057600080fd5b600061403e85828601613d19565b925050602061404f85828601613c32565b9150509250929050565b60006020828403121561406b57600080fd5b600061407984828501613d43565b91505092915050565b600061408e83836140c6565b60208301905092915050565b60006140a683836140e4565b905092915050565b60006140ba83836145c2565b60208301905092915050565b6140cf81614e05565b82525050565b6140de81614e05565b82525050565b60006140ef82614c43565b6140f98185614ca1565b935061410483614c13565b8060005b8381101561413557815161411c8882614082565b975061412783614c7a565b925050600181019050614108565b5085935050505092915050565b600061414d82614c4e565b6141578185614cb2565b93508360208202850161416985614c23565b8060005b858110156141a55784840389528151614186858261409a565b945061419183614c87565b925060208a0199505060018101905061416d565b50829750879550505050505092915050565b60006141c282614c59565b6141cc8185614cc3565b93506141d783614c33565b8060005b838110156142085781516141ef88826140ae565b97506141fa83614c94565b9250506001810190506141db565b5085935050505092915050565b61421e81614e29565b82525050565b600061422f82614c64565b6142398185614cd4565b9350614249818560208601614ea5565b80840191505092915050565b61425e81614e6f565b82525050565b600061426f82614c6f565b6142798185614cdf565b9350614289818560208601614ea5565b61429281614fdf565b840191505092915050565b60006142aa602783614cdf565b91506142b582614ff0565b604082019050919050565b60006142cd600f83614cdf565b91506142d88261503f565b602082019050919050565b60006142f0602683614cdf565b91506142fb82615068565b604082019050919050565b6000614313601d83614cdf565b915061431e826150b7565b602082019050919050565b6000614336601d83614cdf565b9150614341826150e0565b602082019050919050565b6000614359602383614cdf565b915061436482615109565b604082019050919050565b600061437c602683614cdf565b915061438782615158565b604082019050919050565b600061439f602a83614cdf565b91506143aa826151a7565b604082019050919050565b60006143c2603183614cdf565b91506143cd826151f6565b604082019050919050565b60006143e5601783614cdf565b91506143f082615245565b602082019050919050565b6000614408602e83614cdf565b91506144138261526e565b604082019050919050565b600061442b601b83614cdf565b9150614436826152bd565b602082019050919050565b600061444e602083614cdf565b9150614459826152e6565b602082019050919050565b6000614471602c83614cdf565b915061447c8261530f565b604082019050919050565b6000614494601f83614cdf565b915061449f8261535e565b602082019050919050565b60006144b7601783614cdf565b91506144c282615387565b602082019050919050565b60006144da602c83614cdf565b91506144e5826153b0565b604082019050919050565b60006144fd601d83614cdf565b9150614508826153ff565b602082019050919050565b6000614520601b83614cdf565b915061452b82615428565b602082019050919050565b6000614543602b83614cdf565b915061454e82615451565b604082019050919050565b6000614566601683614cdf565b9150614571826154a0565b602082019050919050565b6000614589602a83614cdf565b9150614594826154c9565b604082019050919050565b60006145ac601883614cdf565b91506145b782615518565b602082019050919050565b6145cb81614e55565b82525050565b6145da81614e55565b82525050565b6145e981614e93565b82525050565b6145f881614e5f565b82525050565b600061460a8284614224565b915081905092915050565b600060208201905061462a60008301846140d5565b92915050565b600060408201905061464560008301856140d5565b61465260208301846140d5565b9392505050565b600060608201905061466e60008301866140d5565b61467b60208301856140d5565b61468860408301846145d1565b949350505050565b60006040820190506146a560008301856140d5565b6146b260208301846145d1565b9392505050565b600060208201905081810360008301526146d38184614142565b905092915050565b600060408201905081810360008301526146f58185614142565b9050818103602083015261470981846141b7565b90509392505050565b6000608082019050818103600083015261472c8187614142565b9050818103602083015261474081866141b7565b9050818103604083015261475481856141b7565b905061476360608301846145d1565b95945050505050565b6000606082019050818103600083015261478681866141b7565b905061479560208301856145d1565b6147a260408301846145d1565b949350505050565b60006020820190506147bf6000830184614215565b92915050565b60006020820190506147da6000830184614255565b92915050565b600060208201905081810360008301526147fa8184614264565b905092915050565b6000602082019050818103600083015261481b8161429d565b9050919050565b6000602082019050818103600083015261483b816142c0565b9050919050565b6000602082019050818103600083015261485b816142e3565b9050919050565b6000602082019050818103600083015261487b81614306565b9050919050565b6000602082019050818103600083015261489b81614329565b9050919050565b600060208201905081810360008301526148bb8161434c565b9050919050565b600060208201905081810360008301526148db8161436f565b9050919050565b600060208201905081810360008301526148fb81614392565b9050919050565b6000602082019050818103600083015261491b816143b5565b9050919050565b6000602082019050818103600083015261493b816143d8565b9050919050565b6000602082019050818103600083015261495b816143fb565b9050919050565b6000602082019050818103600083015261497b8161441e565b9050919050565b6000602082019050818103600083015261499b81614441565b9050919050565b600060208201905081810360008301526149bb81614464565b9050919050565b600060208201905081810360008301526149db81614487565b9050919050565b600060208201905081810360008301526149fb816144aa565b9050919050565b60006020820190508181036000830152614a1b816144cd565b9050919050565b60006020820190508181036000830152614a3b816144f0565b9050919050565b60006020820190508181036000830152614a5b81614513565b9050919050565b60006020820190508181036000830152614a7b81614536565b9050919050565b60006020820190508181036000830152614a9b81614559565b9050919050565b60006020820190508181036000830152614abb8161457c565b9050919050565b60006020820190508181036000830152614adb8161459f565b9050919050565b6000602082019050614af760008301846145d1565b92915050565b6000604082019050614b1260008301856145d1565b614b1f60208301846145d1565b9392505050565b6000602082019050614b3b60008301846145ef565b92915050565b6000604082019050614b5660008301856145e0565b614b6360208301846145e0565b9392505050565b6000614b74614b85565b9050614b808282614ed8565b919050565b6000604051905090565b600067ffffffffffffffff821115614baa57614ba9614fb0565b5b602082029050602081019050919050565b600067ffffffffffffffff821115614bd657614bd5614fb0565b5b602082029050602081019050919050565b600067ffffffffffffffff821115614c0257614c01614fb0565b5b602082029050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b6000614cfb82614e55565b9150614d0683614e55565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614d3b57614d3a614f52565b5b828201905092915050565b6000614d5182614e55565b9150614d5c83614e55565b925082614d6c57614d6b614f81565b5b828204905092915050565b6000614d8282614e55565b9150614d8d83614e55565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614dc657614dc5614f52565b5b828202905092915050565b6000614ddc82614e55565b9150614de783614e55565b925082821015614dfa57614df9614f52565b5b828203905092915050565b6000614e1082614e35565b9050919050565b6000614e2282614e35565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff82169050919050565b6000614e7a82614e81565b9050919050565b6000614e8c82614e35565b9050919050565b6000614e9e82614e5f565b9050919050565b60005b83811015614ec3578082015181840152602081019050614ea8565b83811115614ed2576000848401525b50505050565b614ee182614fdf565b810181811067ffffffffffffffff82111715614f0057614eff614fb0565b5b80604052505050565b6000614f1482614e55565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614f4757614f46614f52565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f43616c6c6572206973206e6f7420616c6c6f77656420746f20636f6e7665727460008201527f20746f6b656e7300000000000000000000000000000000000000000000000000602082015250565b7f496e76616c696420616464726573730000000000000000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f496e70757420746f6b656e206973206e6f742072656769737465726564000000600082015250565b7f416d6f756e74206d7573742062652067726561746572207468616e2030000000600082015250565b7f4e6f20656e6f75676820616c6c6f77616e636520746f207370656e642078546f60008201527f6e69630000000000000000000000000000000000000000000000000000000000602082015250565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b7f43616c6c65722072657761726420726174696f206d757374206265206c65737360008201527f207468616e203130302500000000000000000000000000000000000000000000602082015250565b7f416d6f756e74206d75737420626520657175616c20746f206f7220677265617460008201527f6572207468616e2031303020544f4e4943000000000000000000000000000000602082015250565b7f78546f6e69633a205472616e73666572206661696c6564000000000000000000600082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f43616e6e6f742070756c6c20746f207a65726f20616464726573730000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f74636d496d706c656d656e746174696f6e2063616e6e6f74206265207468652060008201527f7a65726f20616464726573730000000000000000000000000000000000000000602082015250565b7f4e6f20617661696c61626c6520746f6b656e7320666f722072656c6561736500600082015250565b7f546f6b656e206973206e6f742072656769737465726564000000000000000000600082015250565b7f506174687320616e6420616d6f756e7473206d757374206265206f662074686560008201527f2073616d65206c656e6774680000000000000000000000000000000000000000602082015250565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b7f4e6f20656e6f7567682078546f6e696320746f20756e7374616b650000000000600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f546f6e69633a205472616e73666572206661696c656400000000000000000000600082015250565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b7f546f6b656e20616c726561647920726567697374657265640000000000000000600082015250565b61554a81614e05565b811461555557600080fd5b50565b61556181614e17565b811461556c57600080fd5b50565b61557881614e29565b811461558357600080fd5b50565b61558f81614e55565b811461559a57600080fd5b50565b6155a681614e5f565b81146155b157600080fd5b5056fea2646970667358221220fa4ac3966f60195db9f0a12e971c16e6921fd860e60e1bf052fe1816890635bf64736f6c63430008030033
Deployed ByteCode Sourcemap
95609:4471:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86634:12;86686:4;86664:27;;:10;:27;;;86656:36;;;;;;86708:19;86718:8;;86708:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:9;:19::i;:::-;86701:26;;86583:150;;;95609:4471;;;;;;93898:128;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;95931:686;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;93696:93;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67445:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67220:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67524:57;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97813:943;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67194:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67585:60;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97355:206;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;97567:210;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81193:29;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96623:680;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;91709:109;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87428:612;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;13675:103;;;;;;;;;;;;;:::i;:::-;;91824:113;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98762:916;;;;;;;;;;;;;:::i;:::-;;90536:309;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;13024:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91201:397;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94200:183;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;88082:541;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81108:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94032:133;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;86971:45;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93795:97;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;93584:106;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;90929:241;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94389:96;;;;;;;;;;;;;:::i;:::-;;81227:47;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91604:99;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67409:29;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;13933:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;85716:230;85776:23;85810:12;85855:17;;;;;;;;;;;:30;;85886:8;85855:40;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85831:64;;;;;;;;85912:7;85928:10;85904:36;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;85716:230;;;;:::o;93898:128::-;13255:12;:10;:12::i;:::-;13244:23;;:7;:5;:7::i;:::-;:23;;;13236:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;93979:41:::1;94001:18;93979:21;:41::i;:::-;93898:128:::0;:::o;95931:686::-;96103:24;96136:16;96154:19;95747:15;;;;;;;;;;;:40;;;;95780:7;:5;:7::i;:::-;95766:21;;:10;:21;;;95747:40;:80;;;;95791:24;:36;95816:10;95791:36;;;;;;;;;;;;;;;;;;;;;;;;;95747:80;95739:132;;;;;;;;;;;;:::i;:::-;;;;;;;;;96191:23:::1;96217:25;:23;:25::i;:::-;96191:51;;96250:25;96277:17:::0;96296:20:::1;96321:45;96349:6;96357:8;96321:27;:45::i;:::-;96249:117;;;;;;96373:22;96398:25;:23;:25::i;:::-;96373:50;;96457:18;96436:17;:39;96432:122;;96491:55;96511:17;96530:15;96491:55;;;;;;;:::i;:::-;;;;;;;;96432:122;96568:11;96581:12;96595:15;96560:51;;;;;;;;;;;95931:686:::0;;;;;:::o;93696:93::-;13255:12;:10;:12::i;:::-;13244:23;;:7;:5;:7::i;:::-;:23;;;13236:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;93761:22:::1;93776:6;93761:14;:22::i;:::-;93696:93:::0;:::o;67445:27::-;;;;;;;;;;;;;:::o;67220:21::-;;;;;;;;;;;;;:::o;67524:57::-;;;;;;;;;;;;;;;;;;;;;;:::o;97813:943::-;97973:6;97939:7;;;;;;;;;;;97932:25;;;97958:10;97932:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:47;;97924:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;98148:6;98099:7;;;;;;;;;;;98092:25;;;98118:10;98138:4;98092:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:62;;98084:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;98328:26;98347:6;98328:18;:26::i;:::-;98320:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;98485:6;98455:15;:27;98471:10;98455:27;;;;;;;;;;;;;;;;:36;;;;:::i;:::-;98425:15;:27;98441:10;98425:27;;;;;;;;;;;;;;;:66;;;;98581:15;;;;;;;;;;;98566:30;;:12;:30;;;;:::i;:::-;98534:17;:29;98552:10;98534:29;;;;;;;;;;;;;;;:62;;;;98643:25;:23;:25::i;:::-;98605:23;:35;98629:10;98605:35;;;;;;;;;;;;;;;:63;;;;98696:10;98682:64;;;98708:6;98716:17;:29;98734:10;98716:29;;;;;;;;;;;;;;;;98682:64;;;;;;;:::i;:::-;;;;;;;;97813:943;:::o;67194:21::-;;;;;;;;;;;;;:::o;67585:60::-;;;;;;;;;;;;;;;;;:::o;97355:206::-;13255:12;:10;:12::i;:::-;13244:23;;:7;:5;:7::i;:::-;:23;;;13236:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;97451:6:::1;97447:109;97467:8;:15;97463:1;:19;97447:109;;;97542:4;97502:24;:37;97527:8;97536:1;97527:11;;;;;;;;;;;;;;;;;;;;;;97502:37;;;;;;;;;;;;;;;;:44;;;;;;;;;;;;;;;;;;97484:3;;;;;:::i;:::-;;;;97447:109;;;;97355:206:::0;:::o;97567:210::-;13255:12;:10;:12::i;:::-;13244:23;;:7;:5;:7::i;:::-;:23;;;13236:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;97666:6:::1;97662:110;97682:8;:15;97678:1;:19;97662:110;;;97757:5;97717:24;:37;97742:8;97751:1;97742:11;;;;;;;;;;;;;;;;;;;;;;97717:37;;;;;;;;;;;;;;;;:45;;;;;;;;;;;;;;;;;;97699:3;;;;;:::i;:::-;;;;97662:110;;;;97567:210:::0;:::o;81193:29::-;;;;:::o;96623:680::-;96776:24;96809:16;96834:19;95747:15;;;;;;;;;;;:40;;;;95780:7;:5;:7::i;:::-;95766:21;;:10;:21;;;95747:40;:80;;;;95791:24;:36;95816:10;95791:36;;;;;;;;;;;;;;;;;;;;;;;;;95747:80;95739:132;;;;;;;;;;;;:::i;:::-;;;;;;;;;96871:23:::1;96897:25;:23;:25::i;:::-;96871:51;;96930:25;96957:17:::0;96976:20:::1;97001:46;97040:6;97001:38;:46::i;:::-;96929:118;;;;;;97054:22;97079:25;:23;:25::i;:::-;97054:50;;97142:18;97121:17;:39;97117:122;;97176:55;97196:17;97215:15;97176:55;;;;;;;:::i;:::-;;;;;;;;97117:122;97253:11;97266:12;97280:15;97245:51;;;;;;;;;;;96623:680:::0;;;;;:::o;91709:109::-;91771:4;91791:15;:21;91807:4;91791:21;;;;;;;;;;;;;;;;91784:28;;91709:109;;;:::o;87428:612::-;9715:13;;;;;;;;;;;:48;;9751:12;;;;;;;;;;9750:13;9715:48;;;9731:16;:14;:16::i;:::-;9715:48;9707:107;;;;;;;;;;;;:::i;:::-;;;;;;;;;9827:19;9850:13;;;;;;;;;;;9849:14;9827:36;;9878:14;9874:101;;;9925:4;9909:13;;:20;;;;;;;;;;;;;;;;;;9959:4;9944:12;;:19;;;;;;;;;;;;;;;;;;9874:101;87641:16:::1;:14;:16::i;:::-;87664:80;87707:17;87726;87664:42;:80::i;:::-;87798:12;87789:6;;:21;;;;;;;;;;;;;;;;;;87930:13;87913:7;;:31;;;;;;;;;;;;;;;;;;88018:14;88000:15;;:32;;;;;;;;;;;;;;;;;;10005:14:::0;10001:68;;;10052:5;10036:13;;:21;;;;;;;;;;;;;;;;;;10001:68;87428:612;;;;;;:::o;13675:103::-;13255:12;:10;:12::i;:::-;13244:23;;:7;:5;:7::i;:::-;:23;;;13236:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;13740:30:::1;13767:1;13740:18;:30::i;:::-;13675:103::o:0;91824:113::-;91888:4;91908:17;:23;91926:4;91908:23;;;;;;;;;;;;;;;;91901:30;;91824:113;;;:::o;98762:916::-;98848:1;98814:31;98834:10;98814:19;:31::i;:::-;:35;98806:79;;;;;;;;;;;;:::i;:::-;;;;;;;;;98892:19;98914:31;98934:10;98914:19;:31::i;:::-;98892:53;;98954:17;98974:37;99000:10;98974:25;:37::i;:::-;98954:57;;99020:16;99075:12;99056:16;99039:14;:33;;;;:::i;:::-;:48;;;;:::i;:::-;99020:67;;99149:1;99119:15;:27;99135:10;99119:27;;;;;;;;;;;;;;;:31;;;;99189:1;99157:17;:29;99175:10;99157:29;;;;;;;;;;;;;;;:33;;;;99226:7;;;;;;;;;;;99219:20;;;99240:14;99219:36;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99396:20;99426:6;;;;;;;;;;;99419:24;;;99452:4;99419:39;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;99396:62;;99483:15;99469:11;:29;99465:81;;;99523:15;99509:29;;99465:81;99561:6;;;;;;;;;;;99554:23;;;99578:10;99590:11;99554:48;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;99630:10;99616:54;;;99642:14;99658:11;99616:54;;;;;;;:::i;:::-;;;;;;;;98762:916;;;;:::o;90536:309::-;13255:12;:10;:12::i;:::-;13244:23;;:7;:5;:7::i;:::-;:23;;;13236:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;90635:1:::1;90626:6;:10;90618:52;;;;;;;;;;;;:::i;:::-;;;;;;;;;90707:1;90685:24;;:10;:24;;;;90677:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;90803:6;;;;;;;;;;;90796:23;;;90820:10;90832:6;90796:43;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;90536:309:::0;;:::o;13024:87::-;13070:7;13097:6;;;;;;;;;;;13090:13;;13024:87;:::o;91201:397::-;91265:4;91357:1;91332:15;:21;91348:4;91332:21;;;;;;;;;;;;;;;;:26;:58;;;;91389:1;91362:17;:23;91380:4;91362:23;;;;;;;;;;;;;;;;:28;91332:58;91328:89;;;91408:1;91401:8;;;;91328:89;91425:19;91447:15;:21;91463:4;91447:21;;;;;;;;;;;;;;;;91425:43;;91494:17;:23;91512:4;91494:23;;;;;;;;;;;;;;;;91479:12;:38;91475:118;;;91535:14;91528:21;;;;;91475:118;91584:1;91577:8;;;91201:397;;;;:::o;94200:183::-;13255:12;:10;:12::i;:::-;13244:23;;:7;:5;:7::i;:::-;:23;;;13236:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;94284:51:::1;94300:15;;;;;;;;;;;94317:17;94284:51;;;;;;;:::i;:::-;;;;;;;;94360:17;94342:15;;:35;;;;;;;;;;;;;;;;;;94200:183:::0;:::o;88082:541::-;88204:17;88224:25;:23;:25::i;:::-;88204:45;;88276:9;88266:6;:19;;88258:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;88354:25;88372:6;88354:17;:25::i;:::-;88346:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;88456:15;88498:16;88483:12;88474:6;:21;;;;:::i;:::-;:40;;;;:::i;:::-;88456:58;;88521:35;88533:10;88545;88521:11;:35::i;:::-;88586:10;88574:43;;;88598:6;88606:10;88574:43;;;;;;;:::i;:::-;;;;;;;;88082:541;;;:::o;81108:32::-;;;;;;;;;;;;;:::o;94032:133::-;13255:12;:10;:12::i;:::-;13244:23;;:7;:5;:7::i;:::-;:23;;;13236:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;94118:41:::1;94140:18;94118:21;:41::i;:::-;94032:133:::0;:::o;86971:45::-;;;:::o;93795:97::-;13255:12;:10;:12::i;:::-;13244:23;;:7;:5;:7::i;:::-;:23;;;13236:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;93862:24:::1;93879:6;93862:16;:24::i;:::-;93795:97:::0;:::o;93584:106::-;13255:12;:10;:12::i;:::-;13244:23;;:7;:5;:7::i;:::-;:23;;;13236:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;93660:24:::1;93676:7;93660:15;:24::i;:::-;93584:106:::0;:::o;90929:241::-;90986:25;91004:6;90986:17;:25::i;:::-;90978:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;91047:22;91072:25;:23;:25::i;:::-;91047:50;;91109:55;91129:17;91148:15;91109:55;;;;;;;:::i;:::-;;;;;;;;90929:241;;:::o;94389:96::-;13255:12;:10;:12::i;:::-;13244:23;;:7;:5;:7::i;:::-;:23;;;13236:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;94475:4:::1;94457:15;;:22;;;;;;;;;;;;;;;;;;94389:96::o:0;81227:47::-;81267:7;81227:47;:::o;91604:99::-;91652:4;91672:25;:23;:25::i;:::-;91665:32;;91604:99;:::o;67409:29::-;;;;;;;;;;;;;:::o;13933:201::-;13255:12;:10;:12::i;:::-;13244:23;;:7;:5;:7::i;:::-;:23;;;13236:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;14042:1:::1;14022:22;;:8;:22;;;;14014:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;14098:28;14117:8;14098:18;:28::i;:::-;13933:201:::0;:::o;11458:98::-;11511:7;11538:10;11531:17;;11458:98;:::o;84985:291::-;81267:7;85067:18;:37;85059:92;;;;;;;;;;;;:::i;:::-;;;;;;;;;85165:58;85185:17;;85204:18;85165:58;;;;;;;:::i;:::-;;;;;;;;85252:18;85232:17;:38;;;;84985:291;:::o;94518:370::-;94576:4;94589:17;94616:6;;;;;;;;;;;94609:24;;;94642:4;94609:39;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;94589:59;;94655:17;94675:7;;;;;;;;;;;:19;;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;94655:41;;94723:1;94707:12;:17;94703:120;;;94799:16;94792:23;;;;;;94703:120;94870:12;94851:16;94836:12;:31;;;;:::i;:::-;:46;;;;:::i;:::-;94829:53;;;;94518:370;;:::o;82066:754::-;82241:24;82274:16;82299:19;82202:6;81356;81352:143;81372:6;:13;81368:1;:17;81352:143;;;81412:39;81438:6;81445:1;81438:9;;;;;;;;;;;;;;;;;;;;;;81448:1;81438:12;;;;;;;;;;;;;;;;;;;;;;81412:16;:25;;:39;;;;:::i;:::-;81404:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;81387:3;;;;;:::i;:::-;;;;81352:143;;;;82360:8:::1;:15;82343:6;:13;:32;82335:89;;;;;;;;;;;;:::i;:::-;;;;;;;;;82432:21;82536:105;82623:6;82631:8;82546:94;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82536:9;:105::i;:::-;82514:175;;;;;;;;;;;;:::i;:::-;82461:228;;;;;;;;;;;;;;;;82697:42;82711:11;82724:14;82697:13;:42::i;:::-;82752:62;82773:6;82781:7;82790:10;82802:11;82752:62;;;;;;;;;:::i;:::-;;;;;;;;81503:1;82066:754:::0;;;;;;:::o;84550:209::-;84617:33;84643:6;84617:16;:25;;:33;;;;:::i;:::-;84616:34;84608:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;84688:28;84709:6;84688:16;:20;;:28;;;;:::i;:::-;;84730:23;84746:6;84730:23;;;;;;:::i;:::-;;;;;;;;84550:209;:::o;95100:148::-;95159:4;95186:7;;;;;;;;;;;95179:28;;;95208:10;95228:4;95235:6;95179:63;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;95172:70;;95100:148;;;:::o;82826:624::-;82981:24;83014:16;83039:19;82954:6;81356;81352:143;81372:6;:13;81368:1;:17;81352:143;;;81412:39;81438:6;81445:1;81438:9;;;;;;;;;;;;;;;;;;;;;;81448:1;81438:12;;;;;;;;;;;;;;;;;;;;;;81412:16;:25;;:39;;;;:::i;:::-;81404:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;81387:3;;;;;:::i;:::-;;;;81352:143;;;;83071:21:::1;83175:96;83263:6;83185:85;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83175:9;:96::i;:::-;83153:166;;;;;;;;;;;;:::i;:::-;83100:219;;;;;;;;;;;;;;;;83327:42;83341:11;83354:14;83327:13;:42::i;:::-;83382:62;83403:6;83411:7;83420:10;83432:11;83382:62;;;;;;;;;:::i;:::-;;;;;;;;81503:1;82826:624:::0;;;;;;:::o;10407:125::-;10455:4;10480:44;10518:4;10480:29;:44::i;:::-;10479:45;10472:52;;10407:125;:::o;12688:134::-;10318:13;;;;;;;;;;;10310:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;12751:26:::1;:24;:26::i;:::-;12788;:24;:26::i;:::-;12688:134::o:0;81516:195::-;81616:41;81638:18;81616:21;:41::i;:::-;81664;81686:18;81664:21;:41::i;:::-;81516:195;;:::o;14294:191::-;14368:16;14387:6;;;;;;;;;;;14368:25;;14413:8;14404:6;;:17;;;;;;;;;;;;;;;;;;14468:8;14437:40;;14458:8;14437:40;;;;;;;;;;;;14294:191;;:::o;99684:391::-;99752:17;99793:23;:30;99817:5;99793:30;;;;;;;;;;;;;;;;99778:45;;99830:27;99860:25;:23;:25::i;:::-;99830:55;;99910:19;99895:12;:34;:55;;;;99949:1;99933:12;:17;99895:55;99892:111;;;99976:19;99961:34;;99892:111;100042:1;100009:23;:30;100033:5;100009:30;;;;;;;;;;;;;;;:34;;;;100050:19;99684:391;;;:::o;94894:200::-;94952:4;95033:6;;;;;;;;;;;95026:27;;;95054:10;95074:4;95081:6;95026:62;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;95019:69;;94894:200;;;:::o;95256:151::-;95340:1;95326:16;;:2;:16;;;;95318:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;95376:7;;;;;;;;;;;95369:20;;;95390:2;95394:6;95369:32;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95256:151;;:::o;81717:341::-;81830:1;81800:32;;:18;:32;;;;81792:89;;;;;;;;;;;;:::i;:::-;;;;;;;;;81888:13;81933:1;81904:31;;:17;;;;;;;;;;;:31;;;;81888:47;;81947:60;81969:17;;;;;;;;;;;81988:18;81947:60;;;;;;;:::i;:::-;;;;;;;;82034:18;82014:17;;:38;;;;;;;;;;;;;;;;;;81717:341;;:::o;84765:214::-;84833:33;84859:6;84833:16;:25;;:33;;;;:::i;:::-;84825:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;84903:31;84927:6;84903:16;:23;;:31;;;;:::i;:::-;;84948:25;84966:6;84948:25;;;;;;:::i;:::-;;;;;;;;84765:214;:::o;84387:157::-;84458:6;84454:85;84474:7;:14;84470:1;:18;84454:85;;;84505:26;84520:7;84528:1;84520:10;;;;;;;;;;;;;;;;;;;;;;84505:14;:26::i;:::-;84490:3;;;;;:::i;:::-;;;;84454:85;;;;84387:157;:::o;58094:167::-;58174:4;58198:55;58208:3;:10;;58244:5;58228:23;;58220:32;;58198:9;:55::i;:::-;58191:62;;58094:167;;;;:::o;85373:335::-;85474:1;85458:12;:17;85455:29;;;85477:7;;85455:29;85492:17;81267:7;85548:17;;85529:15;85514:12;:30;;;;:::i;:::-;85513:52;;;;:::i;:::-;85512:73;;;;:::i;:::-;85492:93;;85594:20;85617:18;:16;:18::i;:::-;85594:41;;85644:58;85677:10;85689:12;85650;85644:32;;;;:58;;;;;:::i;:::-;85373:335;;;;;:::o;57522:152::-;57592:4;57616:50;57621:3;:10;;57657:5;57641:23;;57633:32;;57616:4;:50::i;:::-;57609:57;;57522:152;;;;:::o;955:387::-;1015:4;1223:12;1290:7;1278:20;1270:28;;1333:1;1326:4;:8;1319:15;;;955:387;;;:::o;11382:70::-;10318:13;;;;;;;;;;;10310:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;11382:70::o;12830:113::-;10318:13;;;;;;;;;;;10310:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;12903:32:::1;12922:12;:10;:12::i;:::-;12903:18;:32::i;:::-;12830:113::o:0;57850:158::-;57923:4;57947:53;57955:3;:10;;57991:5;57975:23;;57967:32;;57947:7;:53::i;:::-;57940:60;;57850:158;;;;:::o;54870:129::-;54943:4;54990:1;54967:3;:12;;:19;54980:5;54967:19;;;;;;;;;;;;:24;;54960:31;;54870:129;;;;:::o;83741:164::-;83792:7;83826:61;83842:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83826:15;:61::i;:::-;83815:84;;;;;;;;;;;;:::i;:::-;83808:91;;83741:164;:::o;76890:211::-;77007:86;77027:5;77057:23;;;77082:2;77086:5;77034:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77007:19;:86::i;:::-;76890:211;;;:::o;52774:414::-;52837:4;52859:21;52869:3;52874:5;52859:9;:21::i;:::-;52854:327;;52897:3;:11;;52914:5;52897:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53080:3;:11;;:18;;;;53058:3;:12;;:19;53071:5;53058:19;;;;;;;;;;;:40;;;;53120:4;53113:11;;;;52854:327;53164:5;53157:12;;52774:414;;;;;:::o;53364:1420::-;53430:4;53548:18;53569:3;:12;;:19;53582:5;53569:19;;;;;;;;;;;;53548:40;;53619:1;53605:10;:15;53601:1176;;53980:21;54017:1;54004:10;:14;;;;:::i;:::-;53980:38;;54033:17;54074:1;54053:3;:11;;:18;;;;:22;;;;:::i;:::-;54033:42;;54109:13;54096:9;:26;54092:405;;54143:17;54163:3;:11;;54175:9;54163:22;;;;;;;;;;;;;;;;;;;;;;;;54143:42;;54317:9;54288:3;:11;;54300:13;54288:26;;;;;;;;;;;;;;;;;;;;;;;:38;;;;54428:10;54402:3;:12;;:23;54415:9;54402:23;;;;;;;;;;;:36;;;;54092:405;;54578:3;:11;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54673:3;:12;;:19;54686:5;54673:19;;;;;;;;;;;54666:26;;;54716:4;54709:11;;;;;;;53601:1176;54760:5;54753:12;;;53364:1420;;;;;:::o;86141:235::-;86212:23;86246:12;86299:4;86291:24;;86316:8;86291:34;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86267:58;;;;;;;;86342:7;86358:10;86334:36;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;86141:235;;;;:::o;79463:716::-;79887:23;79913:69;79941:4;79913:69;;;;;;;;;;;;;;;;;79921:5;79913:27;;;;:69;;;;;:::i;:::-;79887:95;;80017:1;79997:10;:17;:21;79993:179;;;80094:10;80083:30;;;;;;;;;;;;:::i;:::-;80075:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;79993:179;79463:716;;;:::o;71939:229::-;72076:12;72108:52;72130:6;72138:4;72144:1;72147:12;72108:21;:52::i;:::-;72101:59;;71939:229;;;;;:::o;73059:511::-;73229:12;73287:5;73262:21;:30;;73254:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;73354:18;73365:6;73354:10;:18::i;:::-;73346:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;73420:12;73434:23;73461:6;:11;;73480:5;73487:4;73461:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73419:73;;;;73510:52;73528:7;73537:10;73549:12;73510:17;:52::i;:::-;73503:59;;;;73059:511;;;;;;:::o;69133:387::-;69193:4;69401:12;69468:7;69456:20;69448:28;;69511:1;69504:4;:8;69497:15;;;69133:387;;;:::o;75528:712::-;75678:12;75707:7;75703:530;;;75738:10;75731:17;;;;75703:530;75872:1;75852:10;:17;:21;75848:374;;;76050:10;76044:17;76111:15;76098:10;76094:2;76090:19;76083:44;75998:148;76193:12;76186:20;;;;;;;;;;;:::i;:::-;;;;;;;;75528:712;;;;;;:::o;24:623:1:-;;145:81;161:64;218:6;161:64;:::i;:::-;145:81;:::i;:::-;136:90;;246:5;274:6;267:5;260:21;300:4;293:5;289:16;282:23;;325:6;375:3;367:4;359:6;355:17;350:3;346:27;343:36;340:2;;;392:1;389;382:12;340:2;420:1;405:236;430:6;427:1;424:13;405:236;;;497:3;525:37;558:3;546:10;525:37;:::i;:::-;520:3;513:50;592:4;587:3;583:14;576:21;;626:4;621:3;617:14;610:21;;465:176;452:1;449;445:9;440:14;;405:236;;;409:14;126:521;;;;;;;:::o;672:661::-;;818:106;834:89;916:6;834:89;:::i;:::-;818:106;:::i;:::-;809:115;;944:5;972:6;965:5;958:21;998:4;991:5;987:16;980:23;;1023:6;1054:1;1039:288;1064:6;1061:1;1058:13;1039:288;;;1156:3;1143:17;1135:6;1131:30;1186:62;1244:3;1232:10;1186:62;:::i;:::-;1181:3;1174:75;1278:4;1273:3;1269:14;1262:21;;1312:4;1307:3;1303:14;1296:21;;1099:228;1086:1;1083;1079:9;1074:14;;1039:288;;;1043:14;799:534;;;;;;;:::o;1356:623::-;;1477:81;1493:64;1550:6;1493:64;:::i;:::-;1477:81;:::i;:::-;1468:90;;1578:5;1606:6;1599:5;1592:21;1632:4;1625:5;1621:16;1614:23;;1657:6;1707:3;1699:4;1691:6;1687:17;1682:3;1678:27;1675:36;1672:2;;;1724:1;1721;1714:12;1672:2;1752:1;1737:236;1762:6;1759:1;1756:13;1737:236;;;1829:3;1857:37;1890:3;1878:10;1857:37;:::i;:::-;1852:3;1845:50;1924:4;1919:3;1915:14;1908:21;;1958:4;1953:3;1949:14;1942:21;;1797:176;1784:1;1781;1777:9;1772:14;;1737:236;;;1741:14;1458:521;;;;;;;:::o;2002:645::-;;2134:81;2150:64;2207:6;2150:64;:::i;:::-;2134:81;:::i;:::-;2125:90;;2235:5;2263:6;2256:5;2249:21;2289:4;2282:5;2278:16;2271:23;;2314:6;2364:3;2356:4;2348:6;2344:17;2339:3;2335:27;2332:36;2329:2;;;2381:1;2378;2371:12;2329:2;2409:1;2394:247;2419:6;2416:1;2413:13;2394:247;;;2486:3;2514:48;2558:3;2546:10;2514:48;:::i;:::-;2509:3;2502:61;2592:4;2587:3;2583:14;2576:21;;2626:4;2621:3;2617:14;2610:21;;2454:187;2441:1;2438;2434:9;2429:14;;2394:247;;;2398:14;2115:532;;;;;;;:::o;2653:139::-;;2737:6;2724:20;2715:29;;2753:33;2780:5;2753:33;:::i;:::-;2705:87;;;;:::o;2798:159::-;;2894:6;2888:13;2879:22;;2910:41;2945:5;2910:41;:::i;:::-;2869:88;;;;:::o;2980:303::-;;3100:3;3093:4;3085:6;3081:17;3077:27;3067:2;;3118:1;3115;3108:12;3067:2;3158:6;3145:20;3183:94;3273:3;3265:6;3258:4;3250:6;3246:17;3183:94;:::i;:::-;3174:103;;3057:226;;;;;:::o;3308:353::-;;3453:3;3446:4;3438:6;3434:17;3430:27;3420:2;;3471:1;3468;3461:12;3420:2;3511:6;3498:20;3536:119;3651:3;3643:6;3636:4;3628:6;3624:17;3536:119;:::i;:::-;3527:128;;3410:251;;;;;:::o;3684:303::-;;3804:3;3797:4;3789:6;3785:17;3781:27;3771:2;;3822:1;3819;3812:12;3771:2;3862:6;3849:20;3887:94;3977:3;3969:6;3962:4;3954:6;3950:17;3887:94;:::i;:::-;3878:103;;3761:226;;;;;:::o;4010:318::-;;4141:3;4134:4;4126:6;4122:17;4118:27;4108:2;;4159:1;4156;4149:12;4108:2;4192:6;4186:13;4217:105;4318:3;4310:6;4303:4;4295:6;4291:17;4217:105;:::i;:::-;4208:114;;4098:230;;;;;:::o;4334:137::-;;4419:6;4413:13;4404:22;;4435:30;4459:5;4435:30;:::i;:::-;4394:77;;;;:::o;4477:139::-;;4561:6;4548:20;4539:29;;4577:33;4604:5;4577:33;:::i;:::-;4529:87;;;;:::o;4622:143::-;;4710:6;4704:13;4695:22;;4726:33;4753:5;4726:33;:::i;:::-;4685:80;;;;:::o;4771:137::-;;4854:6;4841:20;4832:29;;4870:32;4896:5;4870:32;:::i;:::-;4822:86;;;;:::o;4914:262::-;;5022:2;5010:9;5001:7;4997:23;4993:32;4990:2;;;5038:1;5035;5028:12;4990:2;5081:1;5106:53;5151:7;5142:6;5131:9;5127:22;5106:53;:::i;:::-;5096:63;;5052:117;4980:196;;;;:::o;5182:300::-;;5309:2;5297:9;5288:7;5284:23;5280:32;5277:2;;;5325:1;5322;5315:12;5277:2;5368:1;5393:72;5457:7;5448:6;5437:9;5433:22;5393:72;:::i;:::-;5383:82;;5339:136;5267:215;;;;:::o;5488:842::-;;;;;;5663:3;5651:9;5642:7;5638:23;5634:33;5631:2;;;5680:1;5677;5670:12;5631:2;5723:1;5748:53;5793:7;5784:6;5773:9;5769:22;5748:53;:::i;:::-;5738:63;;5694:117;5850:2;5876:53;5921:7;5912:6;5901:9;5897:22;5876:53;:::i;:::-;5866:63;;5821:118;5978:2;6004:52;6048:7;6039:6;6028:9;6024:22;6004:52;:::i;:::-;5994:62;;5949:117;6105:2;6131:53;6176:7;6167:6;6156:9;6152:22;6131:53;:::i;:::-;6121:63;;6076:118;6233:3;6260:53;6305:7;6296:6;6285:9;6281:22;6260:53;:::i;:::-;6250:63;;6204:119;5621:709;;;;;;;;:::o;6336:405::-;;6469:2;6457:9;6448:7;6444:23;6440:32;6437:2;;;6485:1;6482;6475:12;6437:2;6556:1;6545:9;6541:17;6528:31;6586:18;6578:6;6575:30;6572:2;;;6618:1;6615;6608:12;6572:2;6646:78;6716:7;6707:6;6696:9;6692:22;6646:78;:::i;:::-;6636:88;;6499:235;6427:314;;;;:::o;6747:455::-;;6905:2;6893:9;6884:7;6880:23;6876:32;6873:2;;;6921:1;6918;6911:12;6873:2;6992:1;6981:9;6977:17;6964:31;7022:18;7014:6;7011:30;7008:2;;;7054:1;7051;7044:12;7008:2;7082:103;7177:7;7168:6;7157:9;7153:22;7082:103;:::i;:::-;7072:113;;6935:260;6863:339;;;;:::o;7208:743::-;;;7408:2;7396:9;7387:7;7383:23;7379:32;7376:2;;;7424:1;7421;7414:12;7376:2;7495:1;7484:9;7480:17;7467:31;7525:18;7517:6;7514:30;7511:2;;;7557:1;7554;7547:12;7511:2;7585:103;7680:7;7671:6;7660:9;7656:22;7585:103;:::i;:::-;7575:113;;7438:260;7765:2;7754:9;7750:18;7737:32;7796:18;7788:6;7785:30;7782:2;;;7828:1;7825;7818:12;7782:2;7856:78;7926:7;7917:6;7906:9;7902:22;7856:78;:::i;:::-;7846:88;;7708:236;7366:585;;;;;:::o;7957:1025::-;;;;;8177:3;8165:9;8156:7;8152:23;8148:33;8145:2;;;8194:1;8191;8184:12;8145:2;8258:1;8247:9;8243:17;8237:24;8288:18;8280:6;8277:30;8274:2;;;8320:1;8317;8310:12;8274:2;8348:89;8429:7;8420:6;8409:9;8405:22;8348:89;:::i;:::-;8338:99;;8208:239;8507:2;8496:9;8492:18;8486:25;8538:18;8530:6;8527:30;8524:2;;;8570:1;8567;8560:12;8524:2;8598:89;8679:7;8670:6;8659:9;8655:22;8598:89;:::i;:::-;8588:99;;8457:240;8736:2;8762:64;8818:7;8809:6;8798:9;8794:22;8762:64;:::i;:::-;8752:74;;8707:129;8875:2;8901:64;8957:7;8948:6;8937:9;8933:22;8901:64;:::i;:::-;8891:74;;8846:129;8135:847;;;;;;;:::o;8988:278::-;;9104:2;9092:9;9083:7;9079:23;9075:32;9072:2;;;9120:1;9117;9110:12;9072:2;9163:1;9188:61;9241:7;9232:6;9221:9;9217:22;9188:61;:::i;:::-;9178:71;;9134:125;9062:204;;;;:::o;9272:262::-;;9380:2;9368:9;9359:7;9355:23;9351:32;9348:2;;;9396:1;9393;9386:12;9348:2;9439:1;9464:53;9509:7;9500:6;9489:9;9485:22;9464:53;:::i;:::-;9454:63;;9410:117;9338:196;;;;:::o;9540:284::-;;9659:2;9647:9;9638:7;9634:23;9630:32;9627:2;;;9675:1;9672;9665:12;9627:2;9718:1;9743:64;9799:7;9790:6;9779:9;9775:22;9743:64;:::i;:::-;9733:74;;9689:128;9617:207;;;;:::o;9830:407::-;;;9955:2;9943:9;9934:7;9930:23;9926:32;9923:2;;;9971:1;9968;9961:12;9923:2;10014:1;10039:53;10084:7;10075:6;10064:9;10060:22;10039:53;:::i;:::-;10029:63;;9985:117;10141:2;10167:53;10212:7;10203:6;10192:9;10188:22;10167:53;:::i;:::-;10157:63;;10112:118;9913:324;;;;;:::o;10243:260::-;;10350:2;10338:9;10329:7;10325:23;10321:32;10318:2;;;10366:1;10363;10356:12;10318:2;10409:1;10434:52;10478:7;10469:6;10458:9;10454:22;10434:52;:::i;:::-;10424:62;;10380:116;10308:195;;;;:::o;10509:179::-;;10599:46;10641:3;10633:6;10599:46;:::i;:::-;10677:4;10672:3;10668:14;10654:28;;10589:99;;;;:::o;10694:256::-;;10848:96;10940:3;10932:6;10848:96;:::i;:::-;10834:110;;10824:126;;;;:::o;10956:179::-;;11046:46;11088:3;11080:6;11046:46;:::i;:::-;11124:4;11119:3;11115:14;11101:28;;11036:99;;;;:::o;11141:108::-;11218:24;11236:5;11218:24;:::i;:::-;11213:3;11206:37;11196:53;;:::o;11255:118::-;11342:24;11360:5;11342:24;:::i;:::-;11337:3;11330:37;11320:53;;:::o;11409:712::-;;11547:54;11595:5;11547:54;:::i;:::-;11617:76;11686:6;11681:3;11617:76;:::i;:::-;11610:83;;11717:56;11767:5;11717:56;:::i;:::-;11796:7;11827:1;11812:284;11837:6;11834:1;11831:13;11812:284;;;11913:6;11907:13;11940:63;11999:3;11984:13;11940:63;:::i;:::-;11933:70;;12026:60;12079:6;12026:60;:::i;:::-;12016:70;;11872:224;11859:1;11856;11852:9;11847:14;;11812:284;;;11816:14;12112:3;12105:10;;11523:598;;;;;;;:::o;12161:1111::-;;12359:79;12432:5;12359:79;:::i;:::-;12454:111;12558:6;12553:3;12454:111;:::i;:::-;12447:118;;12591:3;12636:4;12628:6;12624:17;12619:3;12615:27;12666:81;12741:5;12666:81;:::i;:::-;12770:7;12801:1;12786:441;12811:6;12808:1;12805:13;12786:441;;;12882:9;12876:4;12872:20;12867:3;12860:33;12933:6;12927:13;12961:114;13070:4;13055:13;12961:114;:::i;:::-;12953:122;;13098:85;13176:6;13098:85;:::i;:::-;13088:95;;13212:4;13207:3;13203:14;13196:21;;12846:381;12833:1;12830;12826:9;12821:14;;12786:441;;;12790:14;13243:4;13236:11;;13263:3;13256:10;;12335:937;;;;;;;;;:::o;13308:732::-;;13456:54;13504:5;13456:54;:::i;:::-;13526:86;13605:6;13600:3;13526:86;:::i;:::-;13519:93;;13636:56;13686:5;13636:56;:::i;:::-;13715:7;13746:1;13731:284;13756:6;13753:1;13750:13;13731:284;;;13832:6;13826:13;13859:63;13918:3;13903:13;13859:63;:::i;:::-;13852:70;;13945:60;13998:6;13945:60;:::i;:::-;13935:70;;13791:224;13778:1;13775;13771:9;13766:14;;13731:284;;;13735:14;14031:3;14024:10;;13432:608;;;;;;;:::o;14046:109::-;14127:21;14142:5;14127:21;:::i;:::-;14122:3;14115:34;14105:50;;:::o;14161:373::-;;14293:38;14325:5;14293:38;:::i;:::-;14347:88;14428:6;14423:3;14347:88;:::i;:::-;14340:95;;14444:52;14489:6;14484:3;14477:4;14470:5;14466:16;14444:52;:::i;:::-;14521:6;14516:3;14512:16;14505:23;;14269:265;;;;;:::o;14540:161::-;14642:52;14688:5;14642:52;:::i;:::-;14637:3;14630:65;14620:81;;:::o;14707:364::-;;14823:39;14856:5;14823:39;:::i;:::-;14878:71;14942:6;14937:3;14878:71;:::i;:::-;14871:78;;14958:52;15003:6;14998:3;14991:4;14984:5;14980:16;14958:52;:::i;:::-;15035:29;15057:6;15035:29;:::i;:::-;15030:3;15026:39;15019:46;;14799:272;;;;;:::o;15077:366::-;;15240:67;15304:2;15299:3;15240:67;:::i;:::-;15233:74;;15316:93;15405:3;15316:93;:::i;:::-;15434:2;15429:3;15425:12;15418:19;;15223:220;;;:::o;15449:366::-;;15612:67;15676:2;15671:3;15612:67;:::i;:::-;15605:74;;15688:93;15777:3;15688:93;:::i;:::-;15806:2;15801:3;15797:12;15790:19;;15595:220;;;:::o;15821:366::-;;15984:67;16048:2;16043:3;15984:67;:::i;:::-;15977:74;;16060:93;16149:3;16060:93;:::i;:::-;16178:2;16173:3;16169:12;16162:19;;15967:220;;;:::o;16193:366::-;;16356:67;16420:2;16415:3;16356:67;:::i;:::-;16349:74;;16432:93;16521:3;16432:93;:::i;:::-;16550:2;16545:3;16541:12;16534:19;;16339:220;;;:::o;16565:366::-;;16728:67;16792:2;16787:3;16728:67;:::i;:::-;16721:74;;16804:93;16893:3;16804:93;:::i;:::-;16922:2;16917:3;16913:12;16906:19;;16711:220;;;:::o;16937:366::-;;17100:67;17164:2;17159:3;17100:67;:::i;:::-;17093:74;;17176:93;17265:3;17176:93;:::i;:::-;17294:2;17289:3;17285:12;17278:19;;17083:220;;;:::o;17309:366::-;;17472:67;17536:2;17531:3;17472:67;:::i;:::-;17465:74;;17548:93;17637:3;17548:93;:::i;:::-;17666:2;17661:3;17657:12;17650:19;;17455:220;;;:::o;17681:366::-;;17844:67;17908:2;17903:3;17844:67;:::i;:::-;17837:74;;17920:93;18009:3;17920:93;:::i;:::-;18038:2;18033:3;18029:12;18022:19;;17827:220;;;:::o;18053:366::-;;18216:67;18280:2;18275:3;18216:67;:::i;:::-;18209:74;;18292:93;18381:3;18292:93;:::i;:::-;18410:2;18405:3;18401:12;18394:19;;18199:220;;;:::o;18425:366::-;;18588:67;18652:2;18647:3;18588:67;:::i;:::-;18581:74;;18664:93;18753:3;18664:93;:::i;:::-;18782:2;18777:3;18773:12;18766:19;;18571:220;;;:::o;18797:366::-;;18960:67;19024:2;19019:3;18960:67;:::i;:::-;18953:74;;19036:93;19125:3;19036:93;:::i;:::-;19154:2;19149:3;19145:12;19138:19;;18943:220;;;:::o;19169:366::-;;19332:67;19396:2;19391:3;19332:67;:::i;:::-;19325:74;;19408:93;19497:3;19408:93;:::i;:::-;19526:2;19521:3;19517:12;19510:19;;19315:220;;;:::o;19541:366::-;;19704:67;19768:2;19763:3;19704:67;:::i;:::-;19697:74;;19780:93;19869:3;19780:93;:::i;:::-;19898:2;19893:3;19889:12;19882:19;;19687:220;;;:::o;19913:366::-;;20076:67;20140:2;20135:3;20076:67;:::i;:::-;20069:74;;20152:93;20241:3;20152:93;:::i;:::-;20270:2;20265:3;20261:12;20254:19;;20059:220;;;:::o;20285:366::-;;20448:67;20512:2;20507:3;20448:67;:::i;:::-;20441:74;;20524:93;20613:3;20524:93;:::i;:::-;20642:2;20637:3;20633:12;20626:19;;20431:220;;;:::o;20657:366::-;;20820:67;20884:2;20879:3;20820:67;:::i;:::-;20813:74;;20896:93;20985:3;20896:93;:::i;:::-;21014:2;21009:3;21005:12;20998:19;;20803:220;;;:::o;21029:366::-;;21192:67;21256:2;21251:3;21192:67;:::i;:::-;21185:74;;21268:93;21357:3;21268:93;:::i;:::-;21386:2;21381:3;21377:12;21370:19;;21175:220;;;:::o;21401:366::-;;21564:67;21628:2;21623:3;21564:67;:::i;:::-;21557:74;;21640:93;21729:3;21640:93;:::i;:::-;21758:2;21753:3;21749:12;21742:19;;21547:220;;;:::o;21773:366::-;;21936:67;22000:2;21995:3;21936:67;:::i;:::-;21929:74;;22012:93;22101:3;22012:93;:::i;:::-;22130:2;22125:3;22121:12;22114:19;;21919:220;;;:::o;22145:366::-;;22308:67;22372:2;22367:3;22308:67;:::i;:::-;22301:74;;22384:93;22473:3;22384:93;:::i;:::-;22502:2;22497:3;22493:12;22486:19;;22291:220;;;:::o;22517:366::-;;22680:67;22744:2;22739:3;22680:67;:::i;:::-;22673:74;;22756:93;22845:3;22756:93;:::i;:::-;22874:2;22869:3;22865:12;22858:19;;22663:220;;;:::o;22889:366::-;;23052:67;23116:2;23111:3;23052:67;:::i;:::-;23045:74;;23128:93;23217:3;23128:93;:::i;:::-;23246:2;23241:3;23237:12;23230:19;;23035:220;;;:::o;23261:366::-;;23424:67;23488:2;23483:3;23424:67;:::i;:::-;23417:74;;23500:93;23589:3;23500:93;:::i;:::-;23618:2;23613:3;23609:12;23602:19;;23407:220;;;:::o;23633:108::-;23710:24;23728:5;23710:24;:::i;:::-;23705:3;23698:37;23688:53;;:::o;23747:118::-;23834:24;23852:5;23834:24;:::i;:::-;23829:3;23822:37;23812:53;;:::o;23871:129::-;23957:36;23987:5;23957:36;:::i;:::-;23952:3;23945:49;23935:65;;:::o;24006:115::-;24091:23;24108:5;24091:23;:::i;:::-;24086:3;24079:36;24069:52;;:::o;24127:271::-;;24279:93;24368:3;24359:6;24279:93;:::i;:::-;24272:100;;24389:3;24382:10;;24261:137;;;;:::o;24404:222::-;;24535:2;24524:9;24520:18;24512:26;;24548:71;24616:1;24605:9;24601:17;24592:6;24548:71;:::i;:::-;24502:124;;;;:::o;24632:332::-;;24791:2;24780:9;24776:18;24768:26;;24804:71;24872:1;24861:9;24857:17;24848:6;24804:71;:::i;:::-;24885:72;24953:2;24942:9;24938:18;24929:6;24885:72;:::i;:::-;24758:206;;;;;:::o;24970:442::-;;25157:2;25146:9;25142:18;25134:26;;25170:71;25238:1;25227:9;25223:17;25214:6;25170:71;:::i;:::-;25251:72;25319:2;25308:9;25304:18;25295:6;25251:72;:::i;:::-;25333;25401:2;25390:9;25386:18;25377:6;25333:72;:::i;:::-;25124:288;;;;;;:::o;25418:332::-;;25577:2;25566:9;25562:18;25554:26;;25590:71;25658:1;25647:9;25643:17;25634:6;25590:71;:::i;:::-;25671:72;25739:2;25728:9;25724:18;25715:6;25671:72;:::i;:::-;25544:206;;;;;:::o;25756:473::-;;25987:2;25976:9;25972:18;25964:26;;26036:9;26030:4;26026:20;26022:1;26011:9;26007:17;26000:47;26064:158;26217:4;26208:6;26064:158;:::i;:::-;26056:166;;25954:275;;;;:::o;26235:734::-;;26544:2;26533:9;26529:18;26521:26;;26593:9;26587:4;26583:20;26579:1;26568:9;26564:17;26557:47;26621:158;26774:4;26765:6;26621:158;:::i;:::-;26613:166;;26826:9;26820:4;26816:20;26811:2;26800:9;26796:18;26789:48;26854:108;26957:4;26948:6;26854:108;:::i;:::-;26846:116;;26511:458;;;;;:::o;26975:1106::-;;27390:3;27379:9;27375:19;27367:27;;27440:9;27434:4;27430:20;27426:1;27415:9;27411:17;27404:47;27468:158;27621:4;27612:6;27468:158;:::i;:::-;27460:166;;27673:9;27667:4;27663:20;27658:2;27647:9;27643:18;27636:48;27701:108;27804:4;27795:6;27701:108;:::i;:::-;27693:116;;27856:9;27850:4;27846:20;27841:2;27830:9;27826:18;27819:48;27884:108;27987:4;27978:6;27884:108;:::i;:::-;27876:116;;28002:72;28070:2;28059:9;28055:18;28046:6;28002:72;:::i;:::-;27357:724;;;;;;;:::o;28087:593::-;;28324:2;28313:9;28309:18;28301:26;;28373:9;28367:4;28363:20;28359:1;28348:9;28344:17;28337:47;28401:108;28504:4;28495:6;28401:108;:::i;:::-;28393:116;;28519:72;28587:2;28576:9;28572:18;28563:6;28519:72;:::i;:::-;28601;28669:2;28658:9;28654:18;28645:6;28601:72;:::i;:::-;28291:389;;;;;;:::o;28686:210::-;;28811:2;28800:9;28796:18;28788:26;;28824:65;28886:1;28875:9;28871:17;28862:6;28824:65;:::i;:::-;28778:118;;;;:::o;28902:252::-;;29048:2;29037:9;29033:18;29025:26;;29061:86;29144:1;29133:9;29129:17;29120:6;29061:86;:::i;:::-;29015:139;;;;:::o;29160:313::-;;29311:2;29300:9;29296:18;29288:26;;29360:9;29354:4;29350:20;29346:1;29335:9;29331:17;29324:47;29388:78;29461:4;29452:6;29388:78;:::i;:::-;29380:86;;29278:195;;;;:::o;29479:419::-;;29683:2;29672:9;29668:18;29660:26;;29732:9;29726:4;29722:20;29718:1;29707:9;29703:17;29696:47;29760:131;29886:4;29760:131;:::i;:::-;29752:139;;29650:248;;;:::o;29904:419::-;;30108:2;30097:9;30093:18;30085:26;;30157:9;30151:4;30147:20;30143:1;30132:9;30128:17;30121:47;30185:131;30311:4;30185:131;:::i;:::-;30177:139;;30075:248;;;:::o;30329:419::-;;30533:2;30522:9;30518:18;30510:26;;30582:9;30576:4;30572:20;30568:1;30557:9;30553:17;30546:47;30610:131;30736:4;30610:131;:::i;:::-;30602:139;;30500:248;;;:::o;30754:419::-;;30958:2;30947:9;30943:18;30935:26;;31007:9;31001:4;30997:20;30993:1;30982:9;30978:17;30971:47;31035:131;31161:4;31035:131;:::i;:::-;31027:139;;30925:248;;;:::o;31179:419::-;;31383:2;31372:9;31368:18;31360:26;;31432:9;31426:4;31422:20;31418:1;31407:9;31403:17;31396:47;31460:131;31586:4;31460:131;:::i;:::-;31452:139;;31350:248;;;:::o;31604:419::-;;31808:2;31797:9;31793:18;31785:26;;31857:9;31851:4;31847:20;31843:1;31832:9;31828:17;31821:47;31885:131;32011:4;31885:131;:::i;:::-;31877:139;;31775:248;;;:::o;32029:419::-;;32233:2;32222:9;32218:18;32210:26;;32282:9;32276:4;32272:20;32268:1;32257:9;32253:17;32246:47;32310:131;32436:4;32310:131;:::i;:::-;32302:139;;32200:248;;;:::o;32454:419::-;;32658:2;32647:9;32643:18;32635:26;;32707:9;32701:4;32697:20;32693:1;32682:9;32678:17;32671:47;32735:131;32861:4;32735:131;:::i;:::-;32727:139;;32625:248;;;:::o;32879:419::-;;33083:2;33072:9;33068:18;33060:26;;33132:9;33126:4;33122:20;33118:1;33107:9;33103:17;33096:47;33160:131;33286:4;33160:131;:::i;:::-;33152:139;;33050:248;;;:::o;33304:419::-;;33508:2;33497:9;33493:18;33485:26;;33557:9;33551:4;33547:20;33543:1;33532:9;33528:17;33521:47;33585:131;33711:4;33585:131;:::i;:::-;33577:139;;33475:248;;;:::o;33729:419::-;;33933:2;33922:9;33918:18;33910:26;;33982:9;33976:4;33972:20;33968:1;33957:9;33953:17;33946:47;34010:131;34136:4;34010:131;:::i;:::-;34002:139;;33900:248;;;:::o;34154:419::-;;34358:2;34347:9;34343:18;34335:26;;34407:9;34401:4;34397:20;34393:1;34382:9;34378:17;34371:47;34435:131;34561:4;34435:131;:::i;:::-;34427:139;;34325:248;;;:::o;34579:419::-;;34783:2;34772:9;34768:18;34760:26;;34832:9;34826:4;34822:20;34818:1;34807:9;34803:17;34796:47;34860:131;34986:4;34860:131;:::i;:::-;34852:139;;34750:248;;;:::o;35004:419::-;;35208:2;35197:9;35193:18;35185:26;;35257:9;35251:4;35247:20;35243:1;35232:9;35228:17;35221:47;35285:131;35411:4;35285:131;:::i;:::-;35277:139;;35175:248;;;:::o;35429:419::-;;35633:2;35622:9;35618:18;35610:26;;35682:9;35676:4;35672:20;35668:1;35657:9;35653:17;35646:47;35710:131;35836:4;35710:131;:::i;:::-;35702:139;;35600:248;;;:::o;35854:419::-;;36058:2;36047:9;36043:18;36035:26;;36107:9;36101:4;36097:20;36093:1;36082:9;36078:17;36071:47;36135:131;36261:4;36135:131;:::i;:::-;36127:139;;36025:248;;;:::o;36279:419::-;;36483:2;36472:9;36468:18;36460:26;;36532:9;36526:4;36522:20;36518:1;36507:9;36503:17;36496:47;36560:131;36686:4;36560:131;:::i;:::-;36552:139;;36450:248;;;:::o;36704:419::-;;36908:2;36897:9;36893:18;36885:26;;36957:9;36951:4;36947:20;36943:1;36932:9;36928:17;36921:47;36985:131;37111:4;36985:131;:::i;:::-;36977:139;;36875:248;;;:::o;37129:419::-;;37333:2;37322:9;37318:18;37310:26;;37382:9;37376:4;37372:20;37368:1;37357:9;37353:17;37346:47;37410:131;37536:4;37410:131;:::i;:::-;37402:139;;37300:248;;;:::o;37554:419::-;;37758:2;37747:9;37743:18;37735:26;;37807:9;37801:4;37797:20;37793:1;37782:9;37778:17;37771:47;37835:131;37961:4;37835:131;:::i;:::-;37827:139;;37725:248;;;:::o;37979:419::-;;38183:2;38172:9;38168:18;38160:26;;38232:9;38226:4;38222:20;38218:1;38207:9;38203:17;38196:47;38260:131;38386:4;38260:131;:::i;:::-;38252:139;;38150:248;;;:::o;38404:419::-;;38608:2;38597:9;38593:18;38585:26;;38657:9;38651:4;38647:20;38643:1;38632:9;38628:17;38621:47;38685:131;38811:4;38685:131;:::i;:::-;38677:139;;38575:248;;;:::o;38829:419::-;;39033:2;39022:9;39018:18;39010:26;;39082:9;39076:4;39072:20;39068:1;39057:9;39053:17;39046:47;39110:131;39236:4;39110:131;:::i;:::-;39102:139;;39000:248;;;:::o;39254:222::-;;39385:2;39374:9;39370:18;39362:26;;39398:71;39466:1;39455:9;39451:17;39442:6;39398:71;:::i;:::-;39352:124;;;;:::o;39482:332::-;;39641:2;39630:9;39626:18;39618:26;;39654:71;39722:1;39711:9;39707:17;39698:6;39654:71;:::i;:::-;39735:72;39803:2;39792:9;39788:18;39779:6;39735:72;:::i;:::-;39608:206;;;;;:::o;39820:218::-;;39949:2;39938:9;39934:18;39926:26;;39962:69;40028:1;40017:9;40013:17;40004:6;39962:69;:::i;:::-;39916:122;;;;:::o;40044:328::-;;40201:2;40190:9;40186:18;40178:26;;40214:70;40281:1;40270:9;40266:17;40257:6;40214:70;:::i;:::-;40294:71;40361:2;40350:9;40346:18;40337:6;40294:71;:::i;:::-;40168:204;;;;;:::o;40378:129::-;;40439:20;;:::i;:::-;40429:30;;40468:33;40496:4;40488:6;40468:33;:::i;:::-;40419:88;;;:::o;40513:75::-;;40579:2;40573:9;40563:19;;40553:35;:::o;40594:311::-;;40761:18;40753:6;40750:30;40747:2;;;40783:18;;:::i;:::-;40747:2;40833:4;40825:6;40821:17;40813:25;;40893:4;40887;40883:15;40875:23;;40676:229;;;:::o;40911:336::-;;41103:18;41095:6;41092:30;41089:2;;;41125:18;;:::i;:::-;41089:2;41175:4;41167:6;41163:17;41155:25;;41235:4;41229;41225:15;41217:23;;41018:229;;;:::o;41253:311::-;;41420:18;41412:6;41409:30;41406:2;;;41442:18;;:::i;:::-;41406:2;41492:4;41484:6;41480:17;41472:25;;41552:4;41546;41542:15;41534:23;;41335:229;;;:::o;41570:132::-;;41660:3;41652:11;;41690:4;41685:3;41681:14;41673:22;;41642:60;;;:::o;41708:157::-;;41823:3;41815:11;;41853:4;41848:3;41844:14;41836:22;;41805:60;;;:::o;41871:132::-;;41961:3;41953:11;;41991:4;41986:3;41982:14;41974:22;;41943:60;;;:::o;42009:114::-;;42110:5;42104:12;42094:22;;42083:40;;;:::o;42129:139::-;;42255:5;42249:12;42239:22;;42228:40;;;:::o;42274:114::-;;42375:5;42369:12;42359:22;;42348:40;;;:::o;42394:98::-;;42479:5;42473:12;42463:22;;42452:40;;;:::o;42498:99::-;;42584:5;42578:12;42568:22;;42557:40;;;:::o;42603:113::-;;42705:4;42700:3;42696:14;42688:22;;42678:38;;;:::o;42722:138::-;;42849:4;42844:3;42840:14;42832:22;;42822:38;;;:::o;42866:113::-;;42968:4;42963:3;42959:14;42951:22;;42941:38;;;:::o;42985:174::-;;43108:6;43103:3;43096:19;43148:4;43143:3;43139:14;43124:29;;43086:73;;;;:::o;43165:209::-;;43323:6;43318:3;43311:19;43363:4;43358:3;43354:14;43339:29;;43301:73;;;;:::o;43380:184::-;;43513:6;43508:3;43501:19;43553:4;43548:3;43544:14;43529:29;;43491:73;;;;:::o;43570:147::-;;43708:3;43693:18;;43683:34;;;;:::o;43723:169::-;;43841:6;43836:3;43829:19;43881:4;43876:3;43872:14;43857:29;;43819:73;;;;:::o;43898:305::-;;43957:20;43975:1;43957:20;:::i;:::-;43952:25;;43991:20;44009:1;43991:20;:::i;:::-;43986:25;;44145:1;44077:66;44073:74;44070:1;44067:81;44064:2;;;44151:18;;:::i;:::-;44064:2;44195:1;44192;44188:9;44181:16;;43942:261;;;;:::o;44209:185::-;;44266:20;44284:1;44266:20;:::i;:::-;44261:25;;44300:20;44318:1;44300:20;:::i;:::-;44295:25;;44339:1;44329:2;;44344:18;;:::i;:::-;44329:2;44386:1;44383;44379:9;44374:14;;44251:143;;;;:::o;44400:348::-;;44463:20;44481:1;44463:20;:::i;:::-;44458:25;;44497:20;44515:1;44497:20;:::i;:::-;44492:25;;44685:1;44617:66;44613:74;44610:1;44607:81;44602:1;44595:9;44588:17;44584:105;44581:2;;;44692:18;;:::i;:::-;44581:2;44740:1;44737;44733:9;44722:20;;44448:300;;;;:::o;44754:191::-;;44814:20;44832:1;44814:20;:::i;:::-;44809:25;;44848:20;44866:1;44848:20;:::i;:::-;44843:25;;44887:1;44884;44881:8;44878:2;;;44892:18;;:::i;:::-;44878:2;44937:1;44934;44930:9;44922:17;;44799:146;;;;:::o;44951:96::-;;45017:24;45035:5;45017:24;:::i;:::-;45006:35;;44996:51;;;:::o;45053:104::-;;45127:24;45145:5;45127:24;:::i;:::-;45116:35;;45106:51;;;:::o;45163:90::-;;45240:5;45233:13;45226:21;45215:32;;45205:48;;;:::o;45259:126::-;;45336:42;45329:5;45325:54;45314:65;;45304:81;;;:::o;45391:77::-;;45457:5;45446:16;;45436:32;;;:::o;45474:93::-;;45550:10;45543:5;45539:22;45528:33;;45518:49;;;:::o;45573:156::-;;45671:52;45717:5;45671:52;:::i;:::-;45658:65;;45648:81;;;:::o;45735:128::-;;45833:24;45851:5;45833:24;:::i;:::-;45820:37;;45810:53;;;:::o;45869:111::-;;45951:23;45968:5;45951:23;:::i;:::-;45938:36;;45928:52;;;:::o;45986:307::-;46054:1;46064:113;46078:6;46075:1;46072:13;46064:113;;;46163:1;46158:3;46154:11;46148:18;46144:1;46139:3;46135:11;46128:39;46100:2;46097:1;46093:10;46088:15;;46064:113;;;46195:6;46192:1;46189:13;46186:2;;;46275:1;46266:6;46261:3;46257:16;46250:27;46186:2;46035:258;;;;:::o;46299:281::-;46382:27;46404:4;46382:27;:::i;:::-;46374:6;46370:40;46512:6;46500:10;46497:22;46476:18;46464:10;46461:34;46458:62;46455:2;;;46523:18;;:::i;:::-;46455:2;46563:10;46559:2;46552:22;46342:238;;;:::o;46586:233::-;;46648:24;46666:5;46648:24;:::i;:::-;46639:33;;46694:66;46687:5;46684:77;46681:2;;;46764:18;;:::i;:::-;46681:2;46811:1;46804:5;46800:13;46793:20;;46629:190;;;:::o;46825:180::-;46873:77;46870:1;46863:88;46970:4;46967:1;46960:15;46994:4;46991:1;46984:15;47011:180;47059:77;47056:1;47049:88;47156:4;47153:1;47146:15;47180:4;47177:1;47170:15;47197:180;47245:77;47242:1;47235:88;47342:4;47339:1;47332:15;47366:4;47363:1;47356:15;47383:102;;47475:2;47471:7;47466:2;47459:5;47455:14;47451:28;47441:38;;47431:54;;;:::o;47491:226::-;47631:34;47627:1;47619:6;47615:14;47608:58;47700:9;47695:2;47687:6;47683:15;47676:34;47597:120;:::o;47723:165::-;47863:17;47859:1;47851:6;47847:14;47840:41;47829:59;:::o;47894:225::-;48034:34;48030:1;48022:6;48018:14;48011:58;48103:8;48098:2;48090:6;48086:15;48079:33;48000:119;:::o;48125:179::-;48265:31;48261:1;48253:6;48249:14;48242:55;48231:73;:::o;48310:179::-;48450:31;48446:1;48438:6;48434:14;48427:55;48416:73;:::o;48495:222::-;48635:34;48631:1;48623:6;48619:14;48612:58;48704:5;48699:2;48691:6;48687:15;48680:30;48601:116;:::o;48723:225::-;48863:34;48859:1;48851:6;48847:14;48840:58;48932:8;48927:2;48919:6;48915:15;48908:33;48829:119;:::o;48954:229::-;49094:34;49090:1;49082:6;49078:14;49071:58;49163:12;49158:2;49150:6;49146:15;49139:37;49060:123;:::o;49189:236::-;49329:34;49325:1;49317:6;49313:14;49306:58;49398:19;49393:2;49385:6;49381:15;49374:44;49295:130;:::o;49431:173::-;49571:25;49567:1;49559:6;49555:14;49548:49;49537:67;:::o;49610:233::-;49750:34;49746:1;49738:6;49734:14;49727:58;49819:16;49814:2;49806:6;49802:15;49795:41;49716:127;:::o;49849:177::-;49989:29;49985:1;49977:6;49973:14;49966:53;49955:71;:::o;50032:182::-;50172:34;50168:1;50160:6;50156:14;50149:58;50138:76;:::o;50220:231::-;50360:34;50356:1;50348:6;50344:14;50337:58;50429:14;50424:2;50416:6;50412:15;50405:39;50326:125;:::o;50457:181::-;50597:33;50593:1;50585:6;50581:14;50574:57;50563:75;:::o;50644:173::-;50784:25;50780:1;50772:6;50768:14;50761:49;50750:67;:::o;50823:231::-;50963:34;50959:1;50951:6;50947:14;50940:58;51032:14;51027:2;51019:6;51015:15;51008:39;50929:125;:::o;51060:179::-;51200:31;51196:1;51188:6;51184:14;51177:55;51166:73;:::o;51245:177::-;51385:29;51381:1;51373:6;51369:14;51362:53;51351:71;:::o;51428:230::-;51568:34;51564:1;51556:6;51552:14;51545:58;51637:13;51632:2;51624:6;51620:15;51613:38;51534:124;:::o;51664:172::-;51804:24;51800:1;51792:6;51788:14;51781:48;51770:66;:::o;51842:229::-;51982:34;51978:1;51970:6;51966:14;51959:58;52051:12;52046:2;52038:6;52034:15;52027:37;51948:123;:::o;52077:174::-;52217:26;52213:1;52205:6;52201:14;52194:50;52183:68;:::o;52257:122::-;52330:24;52348:5;52330:24;:::i;:::-;52323:5;52320:35;52310:2;;52369:1;52366;52359:12;52310:2;52300:79;:::o;52385:138::-;52466:32;52492:5;52466:32;:::i;:::-;52459:5;52456:43;52446:2;;52513:1;52510;52503:12;52446:2;52436:87;:::o;52529:116::-;52599:21;52614:5;52599:21;:::i;:::-;52592:5;52589:32;52579:2;;52635:1;52632;52625:12;52579:2;52569:76;:::o;52651:122::-;52724:24;52742:5;52724:24;:::i;:::-;52717:5;52714:35;52704:2;;52763:1;52760;52753:12;52704:2;52694:79;:::o;52779:120::-;52851:23;52868:5;52851:23;:::i;:::-;52844:5;52841:34;52831:2;;52889:1;52886;52879:12;52831:2;52821:78;:::o
Swarm Source
ipfs://fa4ac3966f60195db9f0a12e971c16e6921fd860e60e1bf052fe1816890635bf
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.