Source Code
Overview
MON Balance
MON Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0x8Bb5026f...7909b2A20 The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
TokenizedVault
Compiler Version
v0.8.26+commit.8a97fa7a
Contract Source Code (Solidity)
/**
*Submitted for verification at monadscan.com on 2025-12-10
*/
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0 ^0.8.1 ^0.8.2 ^0.8.20;
// lib/openzeppelin-contracts-upgradeable/utils/AddressUpgradeable.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
// src/core/DateUtils.sol
library DateUtils {
// The number of seconds per day
uint256 internal constant SECONDS_PER_DAY = 24 * 60 * 60;
// The number of seconds per hour
uint256 internal constant SECONDS_PER_HOUR = 60 * 60;
// The number of seconds per minute
uint256 internal constant SECONDS_PER_MINUTE = 60;
// The offset from 01/01/1970
int256 internal constant OFFSET19700101 = 2440588;
function timestampToDate(uint256 ts) internal pure returns (uint256 year, uint256 month, uint256 day) {
(year, month, day) = _daysToDate(ts / SECONDS_PER_DAY);
}
function timestampToDateTime(uint256 timestamp) internal pure returns (uint256 year, uint256 month, uint256 day, uint256 hour, uint256 minute, uint256 second) {
(year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
uint256 secs = timestamp % SECONDS_PER_DAY;
hour = secs / SECONDS_PER_HOUR;
secs = secs % SECONDS_PER_HOUR;
minute = secs / SECONDS_PER_MINUTE;
second = secs % SECONDS_PER_MINUTE;
}
function timestampFromDateTime(uint256 year, uint256 month, uint256 day, uint256 hour, uint256 minute, uint256 second) internal pure returns (uint256 timestamp) {
timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + hour * SECONDS_PER_HOUR + minute * SECONDS_PER_MINUTE + second;
}
/**
* @notice Calculate year/month/day from the number of days since 1970/01/01 using the date conversion algorithm from http://aa.usno.navy.mil/faq/docs/JD_Formula.php and adding the offset 2440588 so that 1970/01/01 is day 0
* @dev Taken from https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary/blob/master/contracts/BokkyPooBahsDateTimeLibrary.sol
* @param _days The year
* @return year The year
* @return month The month
* @return day The day
*/
function _daysToDate (uint256 _days) internal pure returns (uint256 year, uint256 month, uint256 day) {
int256 __days = int256(_days);
int256 x = __days + 68569 + OFFSET19700101;
int256 n = 4 * x / 146097;
x = x - (146097 * n + 3) / 4;
int256 _year = 4000 * (x + 1) / 1461001;
x = x - 1461 * _year / 4 + 31;
int256 _month = 80 * x / 2447;
int256 _day = x - 2447 * _month / 80;
x = _month / 11;
_month = _month + 2 - 12 * x;
_year = 100 * (n - 49) + _year + x;
year = uint256(_year);
month = uint256(_month);
day = uint256(_day);
}
/**
* @notice Calculates the number of days from 1970/01/01 to year/month/day using the date conversion algorithm from http://aa.usno.navy.mil/faq/docs/JD_Formula.php and subtracting the offset 2440588 so that 1970/01/01 is day 0
* @dev Taken from https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary/blob/master/contracts/BokkyPooBahsDateTimeLibrary.sol
* @param year The year
* @param month The month
* @param day The day
* @return _days Returns the number of days
*/
function _daysFromDate (uint256 year, uint256 month, uint256 day) internal pure returns (uint256 _days) {
require(year >= 1970, "Error");
int256 _year = int256(year);
int256 _month = int256(month);
int256 _day = int256(day);
int256 __days = _day
- 32075
+ 1461 * (_year + 4800 + (_month - 14) / 12) / 4
+ 367 * (_month - 2 - (_month - 14) / 12 * 12) / 12
- 3 * ((_year + 4900 + (_month - 14) / 12) / 100) / 4
- OFFSET19700101;
_days = uint256(__days);
}
}
// src/core/interfaces/IAllocableSubAccount.sol
interface IAllocableSubAccount {
function deposit(address tokenAddr, uint256 amount) external;
function withdraw(address tokenAddr, uint256 amount, address payable receivingAddr) external;
}
// lib/openzeppelin-contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20PermitUpgradeable {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
// lib/openzeppelin-contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20Upgradeable {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
// src/core/interfaces/IEnableOnlyAssetsWhitelist.sol
interface IEnableOnlyAssetsWhitelist {
error ZeroAddressError();
error WhitelistLimitReached();
error InvalidOraclePrice();
error InvalidAddress();
error ReferenceAssetNotPermitted();
error InvalidDecimalPlaces();
error AssetAlreadyEnabled();
error StalePrice();
error RoundNotComplete();
error InvalidTimePeriod();
error InvalidOracleTimestamp();
struct OracleInfo {
address oracleAddress;
address tokenAddress;
uint8 oracleDecimals;
uint8 tokenDecimals;
}
function enableAsset(
address depositableAssetAddr,
address oracleAddr,
uint256 newOracleDuration
) external;
function getWhitelistedAssets() external view returns (address[] memory);
function isWhitelisted(address addr) external view returns (bool);
function getOracleAddress(address assetAddr) external view returns (address);
function fromInputAssetToReferenceAsset(address assetAddr, uint256 amount) external view returns (uint256);
function getTotalAssetsValuation(uint256 externalAssets) external view returns (uint256);
function convertToShares(
address lpTokenAddress,
address assetInAddr,
address vaultAddr,
uint256 assetInAmount,
uint256 externalAssets
) external view returns (uint256 shares, uint256 amountInReferenceTokens);
function REFERENCE_ASSET() external view returns (address);
function REFERENCE_ASSET_DECIMALS() external view returns (uint8);
}
// src/core/interfaces/IFeeCollectorsAware.sol
interface IFeeCollectorsAware {
struct CollectorDefinition {
address collectorAddress;
uint256 percentage;
}
function updateFeeCollectors(CollectorDefinition[] calldata collectors) external;
function updatePerformanceFeeCollectors(CollectorDefinition[] calldata collectors) external;
}
// src/core/interfaces/IMintableBurnable.sol
interface IMintableBurnable {
/**
* @notice Issues a given amount of tokens to the address specified.
* @param addr The address of the receiver.
* @param amount The number of tokens to issue.
*/
function mint(address addr, uint256 amount) external;
/**
* @notice Burns tokens from the address specified.
* @param addr The token holder.
* @param amount The number of tokens to burn.
*/
function burn(address addr, uint256 amount) external;
}
// src/core/interfaces/IResourceBasedTimelockedCall.sol
interface IResourceBasedTimelockedCall {
error Unauthorized();
error HashRequired();
error HashAlreadyEnqueued();
error HashNotEnqueued();
error TimelockInPlace();
error InvalidTimelockDuration();
error InvalidResourceAddress();
struct TimelockedCallInfo {
uint256 targetEpoch; // The unix epoch at which the hash can be consumed
address createdBy; // The address of the scheduler
}
/// @notice Triggers when a hash is scheduled for further execution
event HashScheduled(bytes32 h, address postedBy);
/// @notice Triggers when a hash is consumed by the address specified.
event HashConsumed(bytes32 h, address consumerAddress);
/// @notice Triggers when a hash is cancelled.
event HashCancelled(bytes32 h, address consumerAddress);
function schedule(bytes32 h) external;
function cancel(bytes32 h) external;
function consume(bytes32 h) external;
function hashExists(bytes32 h) external view returns (bool);
function getInfo(bytes32 h) external view returns (TimelockedCallInfo memory);
}
// src/core/interfaces/ISendersWhitelist.sol
interface ISendersWhitelist {
function enableSender(address addr) external;
function disableSender(address addr) external;
function isWhitelisted(address addr) external view returns (bool);
}
// src/tokenized-vaults/ITokenizedVault.sol
interface ITokenizedVault {
error HighWatermarkViolation();
error HighWatermarkDurationError();
error TokenDecimalsMismatch();
error InvalidLagDuration();
struct ConfigInfo {
uint256 maxDepositAmount;
uint256 maxWithdrawalAmount;
uint256 instantRedemptionFee;
uint256 lagDuration;
uint256 withdrawalFee;
uint256 watermarkTimeWindow;
uint256 maxChangePercent;
uint256 managementFeePercent;
uint256 performanceFeeRate;
address sendersWhitelistAddress;
address operatorAddress;
address scheduledCallerAddress;
address lpTokenAddress;
address referenceAsset;
address futureOwnerAddress;
address assetsWhitelistAddress;
}
/// @notice Triggers when the resource is configured.
event ContractConfigured();
/// @notice Triggers during an emergency withdrawal.
event OnEmergencyWithdraw(address receiverAddr);
function configure(ConfigInfo calldata newConfig) external;
function asset() external view returns (address);
}
// lib/openzeppelin-contracts-upgradeable/utils/math/MathUpgradeable.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library MathUpgradeable {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1, "Math: mulDiv overflow");
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}
// src/core/OwnableGuarded.sol
abstract contract OwnableGuarded {
// ----------------------------------------------------------------------------------------------------
// Constants
// ----------------------------------------------------------------------------------------------------
// 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;
// ----------------------------------------------------------------------------------------------------
// Errors
// ----------------------------------------------------------------------------------------------------
error OwnerOnly();
error OwnerAddressRequired();
error ReentrancyGuardReentrantCall();
// ----------------------------------------------------------------------------------------------------
// Storage layout
// ----------------------------------------------------------------------------------------------------
uint256 private _status;
address internal _owner;
// ----------------------------------------------------------------------------------------------------
// Events
// ----------------------------------------------------------------------------------------------------
/**
* @notice Triggers when contract ownership changes.
* @param previousOwner The previous owner of the contract.
* @param newOwner The new owner of the contract.
*/
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
// ----------------------------------------------------------------------------------------------------
// Modifiers
// ----------------------------------------------------------------------------------------------------
/**
* @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, _status will be NOT_ENTERED
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// 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;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
if (msg.sender != _owner) revert OwnerOnly();
_;
}
// ----------------------------------------------------------------------------------------------------
// Functions
// ----------------------------------------------------------------------------------------------------
/**
* @notice Transfers ownership of the contract to the account specified.
* @param newOwner The address of the new owner.
*/
function transferOwnership(address newOwner) external virtual nonReentrant onlyOwner {
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
if (newOwner == address(0)) revert OwnerAddressRequired();
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
/**
* @notice Gets the owner of the contract.
* @return address The address who owns the contract.
*/
function owner() external view virtual returns (address) {
return _owner;
}
}
// lib/openzeppelin-contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20MetadataUpgradeable is IERC20Upgradeable {
/**
* @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);
}
// lib/openzeppelin-contracts-upgradeable/proxy/utils/Initializable.sol
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
* @custom:oz-retyped-from bool
*/
uint8 private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint8 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
* constructor.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
"Initializable: contract is already initialized"
);
_initialized = 1;
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: setting the version to 255 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint8 version) {
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
_initialized = version;
_initializing = true;
_;
_initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized != type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}
// src/core/GuardedProxyOwnable2Steps.sol
abstract contract GuardedProxyOwnable2Steps is Initializable, OwnableGuarded {
error NotConfigured();
error AlreadyConfigured();
error InvalidAddress();
error Unauthorized();
/// @dev The address of the pending owner, if any.
address internal _pendingOwner;
/// @dev Indicates if the contract was configured
bool internal _configured;
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
/// @dev Throws if the contract is not configured
modifier ifConfigured() {
if (!_configured) revert NotConfigured();
_;
}
/// @dev Throws if the contract was configured already
modifier ifNotConfigured() {
if (_configured) revert AlreadyConfigured();
_;
}
/**
* @notice Starts the ownership transfer of this contract to the address specified.
* @dev The ownership transfer is time-locked. Calling this function cancels any previous scheduled requests.
* @param newOwner The address of the new owner.
*/
function transferOwnership(address newOwner) public virtual override nonReentrant ifConfigured onlyOwner {
_proposeOwnershipTransfer(newOwner);
}
/**
* @notice Accepts the ownership transfer initiated by the current owner of this contract.
*/
function acceptOwnership() public virtual nonReentrant ifConfigured {
if (_pendingOwner != msg.sender) revert Unauthorized();
_transferOwnership(msg.sender);
}
function _proposeOwnershipTransfer(address newOwner) internal {
if ((newOwner == address(0)) || (newOwner == address(this))) revert InvalidAddress();
_pendingOwner = newOwner;
emit OwnershipTransferStarted(_owner, newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual override {
delete _pendingOwner;
super._transferOwnership(newOwner);
}
/**
* @notice Gets the address of the pending owner, if any.
* @return Returns the address of the pending owner. Returns the zero address if there is no pending owner at all.
*/
function pendingOwner() external view returns (address) {
return _pendingOwner;
}
}
// lib/openzeppelin-contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20Upgradeable {
using AddressUpgradeable for address;
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20Upgradeable token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
* Revert on invalid signature.
*/
function safePermit(
IERC20PermitUpgradeable token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));
}
}
// src/tokenized-vaults/base/OperableVault.sol
abstract contract OperableVault is IFeeCollectorsAware, GuardedProxyOwnable2Steps {
error OperatorOnly();
error OnlyOwnerOrOperator();
error InvalidAccountType();
error InvalidAmount();
error FeesMustSum100();
error SenderNotWhitelisted();
error MissingFeeCollectors();
uint8 constant internal ACCOUNT_TYPE_SUBACCOUNT = 1;
uint8 constant internal ACCOUNT_TYPE_WALLET = 2;
// --------------------------------------------------------------------------
// Storage layout
// --------------------------------------------------------------------------
/// @notice The fee collectors of the vault.
IFeeCollectorsAware.CollectorDefinition[] public feeCollectors;
/// @notice The receipients of performance fees
IFeeCollectorsAware.CollectorDefinition[] public performanceFeeRecipients;
/// @notice The address of the operator.
address public operatorAddress;
/// @notice Indicates whether deposits are paused or not.
bool public depositsPaused;
/// @notice Indicates whether withdrawals are paused or not.
bool public withdrawalsPaused;
/// @notice The contract address for scheduled calls.
address public scheduledCallerAddress;
/// @notice The whitelist of senders, if any.
address public sendersWhitelistAddress;
/// @notice The sub accounts whitelisted
mapping (address => uint8) public whitelistedSubAccounts;
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[10] private __gap;
// --------------------------------------------------------------------------
// Events
// --------------------------------------------------------------------------
event SendersWhitelistUpdated(address newWhitelistAddr);
event SubAccountEnabled(address subAccountAddr);
event SubAccountDisabled(address subAccountAddr);
/**
* @notice Triggers when deposits/withdrawals are paused or resumed.
* @param bDepositsPaused The new state for deposits
* @param bWithdrawalsPaused The new state for withdrawals
*/
event DepositWithdrawalStatusChanged(bool bDepositsPaused, bool bWithdrawalsPaused);
// --------------------------------------------------------------------------
// Modifiers
// --------------------------------------------------------------------------
/// @dev Throws if the sender is not the current operator
modifier onlyOperator() {
if (msg.sender != operatorAddress) revert OperatorOnly();
_;
}
/// @dev Throws if the sender is not the current owner or operator
modifier onlyOwnerOrOperator() {
if ((msg.sender != operatorAddress) && (msg.sender != _owner)) revert OnlyOwnerOrOperator();
_;
}
/// @dev Throws if the message sender is not whitelisted, unless there is no whitelist defined.
modifier ifSenderWhitelisted() {
if (
(msg.sender != _owner) &&
(msg.sender != operatorAddress) &&
(sendersWhitelistAddress != address(0)) &&
(!ISendersWhitelist(sendersWhitelistAddress).isWhitelisted(msg.sender))
) revert SenderNotWhitelisted();
_;
}
// --------------------------------------------------------------------------
// Functions
// --------------------------------------------------------------------------
/**
* @notice Pauses and/or resumes deposits and/or withdrawals.
* @param bPauseDeposits Pass "true" to pause deposits. Pass "false" to resume deposits.
* @param bPauseWithdrawals Pass "true" to pause withdrawals. Pass "false" to resume withdrawals.
*/
function pauseDepositsAndWithdrawals(bool bPauseDeposits, bool bPauseWithdrawals) external nonReentrant ifConfigured onlyOwner {
depositsPaused = bPauseDeposits;
withdrawalsPaused = bPauseWithdrawals;
emit DepositWithdrawalStatusChanged(depositsPaused, withdrawalsPaused);
}
/**
* @notice Updates the address of whitelisted message senders.
* @dev The whitelist address specified can be the zero address in order to represent that the vault does not require a whitelist for message senders.
* @param newWhitelistAddr The address of the new whitelist, which can be the zero address.
*/
function updateSendersWhitelist(address newWhitelistAddr) external nonReentrant ifConfigured onlyOwner {
sendersWhitelistAddress = newWhitelistAddr;
emit SendersWhitelistUpdated(newWhitelistAddr);
}
/**
* @notice Enables the sub account specified.
* @param addr The address to enable.
* @param accountType The type of account: 1 = Sub Account, 2 = EOA or Wallet.
*/
function enableSubAccount(
address addr,
uint8 accountType
) external nonReentrant onlyOwner {
if ((addr == address(0)) || (addr == address(this))) revert InvalidAddress();
if ((accountType != ACCOUNT_TYPE_SUBACCOUNT) && (accountType != ACCOUNT_TYPE_WALLET)) revert InvalidAccountType();
whitelistedSubAccounts[addr] = accountType;
emit SubAccountEnabled(addr);
}
/**
* @notice Disables the sub account specified.
* @param addr The address to disable.
*/
function disableSubAccount(address addr) external nonReentrant onlyOwner {
delete whitelistedSubAccounts[addr];
emit SubAccountDisabled(addr);
}
/**
* @notice Updates the fee collectors of this vault.
* @param collectors Specifies the new fee collectors.
*/
function updateFeeCollectors(
IFeeCollectorsAware.CollectorDefinition[] calldata collectors
) external virtual override nonReentrant onlyOwner {
uint256 acum;
uint256 t = collectors.length;
if (t < 1) revert MissingFeeCollectors();
delete feeCollectors;
for (uint256 i; i < t; i++) {
if (collectors[i].percentage < 1) revert InvalidAmount();
if (collectors[i].collectorAddress == address(0)) revert InvalidAddress();
acum += collectors[i].percentage;
feeCollectors.push(collectors[i]);
}
if (acum != 100_0000) revert FeesMustSum100();
}
/**
* @notice Updates the recipients of performance fees.
* @param collectors Specifies the new fee collectors.
*/
function updatePerformanceFeeCollectors(
IFeeCollectorsAware.CollectorDefinition[] calldata collectors
) external override nonReentrant onlyOwner {
uint256 acum;
uint256 t = collectors.length;
if (t < 1) revert MissingFeeCollectors();
delete performanceFeeRecipients;
for (uint256 i; i < t; i++) {
if (collectors[i].percentage < 1) revert InvalidAmount();
if (collectors[i].collectorAddress == address(0)) revert InvalidAddress();
acum += collectors[i].percentage;
performanceFeeRecipients.push(collectors[i]);
}
if (acum != 100_0000) revert FeesMustSum100();
}
/**
* @notice Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
* @dev Can only be called by the current owner.
* @param newOwner The address of the new owner.
*/
function transferOwnership(address newOwner) public virtual override nonReentrant ifConfigured onlyOwner {
_scheduleOwnershipTransfer(newOwner);
}
/**
* @notice Accepts the ownership transfer initiated by the current owner of this contract.
*/
function acceptOwnership() public virtual override ifConfigured {
bytes32 h = keccak256(abi.encode(
abi.encodeWithSignature(
"transferOwnership(address)",
msg.sender
)
));
super.acceptOwnership();
IResourceBasedTimelockedCall(scheduledCallerAddress).consume(h);
}
function _scheduleOwnershipTransfer(address newOwner) internal {
bytes32 prevOwnershipHash = (_pendingOwner == address(0)) ? bytes32(0) : keccak256(abi.encode(
abi.encodeWithSignature(
"transferOwnership(address)",
_pendingOwner
)
));
// Schedule the ownership transfer of the future owner specified
bytes32 futureOwnershipHash = keccak256(abi.encode(
abi.encodeWithSignature(
"transferOwnership(address)",
newOwner
)
));
_proposeOwnershipTransfer(newOwner);
if (prevOwnershipHash != bytes32(0)) IResourceBasedTimelockedCall(scheduledCallerAddress).cancel(prevOwnershipHash);
IResourceBasedTimelockedCall(scheduledCallerAddress).schedule(futureOwnershipHash);
}
function getFeeCollectors() external view returns (IFeeCollectorsAware.CollectorDefinition[] memory) {
return feeCollectors;
}
function getPerformanceFeeRecipients() external view returns (IFeeCollectorsAware.CollectorDefinition[] memory) {
return performanceFeeRecipients;
}
}
// src/tokenized-vaults/base/OraclizedMultiAssetVault.sol
/**
* @title Represents an oraclized vault. The vault is a guarded proxy, ownable in 2 steps. The oracle is ChainLink by default.
*/
abstract contract OraclizedMultiAssetVault is OperableVault {
using MathUpgradeable for uint256;
error ZeroAddressError();
error WhitelistLimitReached();
error AssetNotWhitelisted();
error CollectableFeesExceeded(uint256 fee, uint256 remaining);
error InvalidTimestamp();
error DepositsPaused();
error InvalidReceiver();
error MaxDepositAmountReached();
error InsufficientShares();
error MaxAllowedChangeReached();
error AccountNotWhitelisted();
error InvalidExternalAssets();
error ReferenceAssetMismatch();
error FeeAmountTooLow();
error DepositCapReached();
// --------------------------------------------------------------------------
// Constants
// --------------------------------------------------------------------------
/// @dev A reasonable time-window for manipulating the block timestamp as a miner.
uint256 constant internal _TIMESTAMP_MANIPULATION_WINDOW = 5 minutes;
/// @dev The number of seconds per year.
uint256 constant internal _SECONDS_PER_YEAR = 60 * 60 * 24 * 365;
// --------------------------------------------------------------------------
// Storage layout
// --------------------------------------------------------------------------
/// @notice The amount of assets available on other chains, as reported by the accountant.
uint256 public externalAssets;
/// @notice The total amount of collectable fees, at any point in time.
uint256 public totalCollectableFees;
/// @notice The maximum allowed change, expressed in bps.
uint256 public maxChangePercent;
/// @notice The last time external assets were updated.
uint256 public assetsUpdatedOn;
/// @notice The last time fees were charged.
uint256 public feesTimestamp;
/// @notice The management fee, expressed in bps.
uint256 public managementFeePercent;
/// @notice The maximum deposit amount, expressed in reference assets.
uint256 public maxDepositAmount;
/// @notice The address of the reference asset.
address internal _referenceAsset;
/// @notice The address of the LP token.
address public lpTokenAddress;
/// @notice The whitelisted assets
address public assetsWhitelistAddress;
/// @notice The deposit cap. It is the valuation of the total assets expressed in reference tokens.
uint256 public depositCap;
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[9] private __gap;
// --------------------------------------------------------------------------
// Events
// --------------------------------------------------------------------------
event FeesCollected();
event MaxChangePercentUpdated(uint256 newValue);
/// @notice Triggers when you change the management fee.
event ManagementFeeUpdated(uint256 newManagementFeePercent);
/**
* @notice Triggers when the management fee gets charged.
* @param managementFeeAmount The amount charged as management fee.
*/
event ManagementFeeCharged(uint256 managementFeeAmount);
event Deposit(address assetIn, uint256 amountIn, uint256 shares, address indexed senderAddr, address indexed receiverAddr);
// --------------------------------------------------------------------------
// Modifiers
// --------------------------------------------------------------------------
/// @dev Throws if the asset specified is not whitelisted.
modifier ifAssetWhitelisted(address assetAddr) {
if ((assetAddr != _referenceAsset) && (!IEnableOnlyAssetsWhitelist(assetsWhitelistAddress).isWhitelisted(assetAddr))) revert AssetNotWhitelisted();
_;
}
/// @dev Throws if deposits are paused.
modifier ifDepositsNotPaused() {
if (depositsPaused) revert DepositsPaused();
_;
}
// --------------------------------------------------------------------------
// Functions
// --------------------------------------------------------------------------
/**
* @notice Updates the assets whitelist of this vault.
* @param newWhitelistAddr The address of the new whitelist.
*/
function updateAssetsWhitelist(address newWhitelistAddr) external nonReentrant ifConfigured onlyOwner {
if (newWhitelistAddr == address(0)) revert InvalidAddress();
assetsWhitelistAddress = newWhitelistAddr;
if (_referenceAsset != IEnableOnlyAssetsWhitelist(newWhitelistAddr).REFERENCE_ASSET()) revert ReferenceAssetMismatch();
}
/**
* @notice Updates the total amount of external assets.
* @param externalAssetsAmount The amount of external assets. The amount must be expressed in reference tokens.
*/
function updateTotalAssets(uint256 externalAssetsAmount) external nonReentrant ifConfigured onlyOwnerOrOperator {
uint256 perChange = getChangePercentage(externalAssetsAmount);
uint256 maxAllowedChangePerc = getMaxAllowedChange();
// slither-disable-next-line timestamp
if (perChange > maxAllowedChangePerc) revert MaxAllowedChangeReached();
externalAssets = externalAssetsAmount;
assetsUpdatedOn = block.timestamp;
}
/**
* @notice Deposits a given amount of input tokens in the vault.
* @param assetIn The input token. Reverts if the token is not whitelisted.
* @param amountIn The deposit amount.
* @param receiverAddr The address that will receive the shares.
* @return shares Returns the number of shares
*/
function deposit(
address assetIn,
uint256 amountIn,
address receiverAddr
) external nonReentrant ifConfigured ifDepositsNotPaused ifSenderWhitelisted ifAssetWhitelisted(assetIn) returns (uint256 shares) {
shares = _beforeDeposit(assetIn, amountIn, receiverAddr);
_afterPermit(assetIn, amountIn, receiverAddr, shares);
}
/**
* @notice Deposits a given amount of input tokens in the vault through an ERC20 Permit.
* @param assetIn The input token. Reverts if the token is not whitelisted.
* @param amountIn The deposit amount.
* @param receiverAddr The address that will receive the shares.
* @param deadline The deadline of the permit.
* @param r The signature component "R"
* @param s The signature component "S"
* @param v The signature component "V"
* @return shares Returns the number of shares
*/
function depositWithPermit(
address assetIn,
uint256 amountIn,
address receiverAddr,
uint256 deadline,
bytes32 r,
bytes32 s,
uint8 v
) external nonReentrant ifConfigured ifDepositsNotPaused ifSenderWhitelisted ifAssetWhitelisted(assetIn) returns (uint256 shares) {
shares = _beforeDeposit(assetIn, amountIn, receiverAddr);
IERC20PermitUpgradeable(assetIn).permit(msg.sender, address(this), amountIn, deadline, v, r, s);
_afterPermit(assetIn, amountIn, receiverAddr, shares);
}
/**
* @notice Deposits a given amount of reference assets in the account specified.
* @dev The account must be whitelisted. It can be a sub account or a wallet.
* @param inputAssetAddr The address of the asset to move.
* @param depositAmount The assets amount to deposit.
* @param subAccountAddr The address of the sub account.
*/
function depositToSubaccount(
address inputAssetAddr,
uint256 depositAmount,
address subAccountAddr
) external nonReentrant ifConfigured onlyOwnerOrOperator {
if (depositAmount < 1) revert InvalidAmount();
uint8 accountType = whitelistedSubAccounts[subAccountAddr];
if (accountType < 1) revert AccountNotWhitelisted();
// Convert the input amount to the respective amount in reference tokens
uint256 amountInReferenceAssets = (inputAssetAddr == _referenceAsset) ? depositAmount : _fromInputAssetToReferenceAsset(inputAssetAddr, depositAmount);
externalAssets += amountInReferenceAssets;
if (accountType == ACCOUNT_TYPE_SUBACCOUNT) {
// Deposit funds in the sub account
SafeERC20Upgradeable.safeApprove(IERC20Upgradeable(inputAssetAddr), subAccountAddr, depositAmount);
IAllocableSubAccount(subAccountAddr).deposit(inputAssetAddr, depositAmount);
SafeERC20Upgradeable.safeApprove(IERC20Upgradeable(inputAssetAddr), subAccountAddr, 0);
} else {
// Transfer the funds to a whitelisted wallet or EOA
SafeERC20Upgradeable.safeTransfer(IERC20Upgradeable(inputAssetAddr), subAccountAddr, depositAmount);
}
}
/**
* @notice Withdraws a given amount of reference assets from the sub account specified.
* @param inputAssetAddr The address of the asset to move.
* @param amount The amount of reference assets to withdraw.
* @param subAccountAddr The address of the sub account.
*/
function withdrawFromSubaccount(
address inputAssetAddr,
uint256 amount,
address subAccountAddr
) external nonReentrant ifConfigured onlyOwnerOrOperator {
if (amount < 1) revert InvalidAmount();
uint8 accountType = whitelistedSubAccounts[subAccountAddr];
if (accountType < 1) revert AccountNotWhitelisted();
// Convert the input amount to the respective amount in reference tokens
uint256 amountInReferenceAssets = (inputAssetAddr == _referenceAsset) ? amount : _fromInputAssetToReferenceAsset(inputAssetAddr, amount);
if (amountInReferenceAssets > externalAssets) revert InvalidExternalAssets();
externalAssets -= amountInReferenceAssets;
if (accountType == ACCOUNT_TYPE_SUBACCOUNT) {
IAllocableSubAccount(subAccountAddr).withdraw(inputAssetAddr, amount, payable(address(this)));
} else {
// slither-disable-next-line arbitrary-send-erc20
SafeERC20Upgradeable.safeTransferFrom(IERC20Upgradeable(inputAssetAddr), subAccountAddr, address(this), amount);
}
}
/**
* @notice Updates the maximum allowed change.
* @param newValue The new value, expressed as a percentage with 2 decimal places.
*/
function updateMaxChangePercent(uint256 newValue) external nonReentrant ifConfigured onlyOwner {
// Build the hash of this call and attempt to consume it. The call reverts if the hash can't be consumed.
bytes32 h = keccak256(abi.encode(
abi.encodeWithSignature(
"updateMaxChangePercent(uint256)",
newValue
)
));
maxChangePercent = newValue;
emit MaxChangePercentUpdated(newValue);
IResourceBasedTimelockedCall(scheduledCallerAddress).consume(h);
}
/**
* @notice Updates the management fee.
* @param newManagementFeePercent The management fee. This is a percentage with 2 decimal places.
*/
function updateManagementFee(
uint256 newManagementFeePercent
) external nonReentrant ifConfigured onlyOwner {
// Build the hash of this call and attempt to consume it. The call reverts if the hash can't be consumed.
bytes32 h = keccak256(abi.encode(
abi.encodeWithSignature(
"updateManagementFee(uint256)",
newManagementFeePercent
)
));
managementFeePercent = newManagementFeePercent;
emit ManagementFeeUpdated(newManagementFeePercent);
IResourceBasedTimelockedCall(scheduledCallerAddress).consume(h);
}
/**
* @notice Charges the management fee.
*/
function chargeManagementFee() external virtual nonReentrant ifConfigured {
uint256 totalAssetsAmount = _getTotalAssets();
uint256 applicableManagementFee = (totalAssetsAmount * managementFeePercent * (block.timestamp - feesTimestamp)) / _SECONDS_PER_YEAR / 1e4;
feesTimestamp = block.timestamp;
totalCollectableFees += applicableManagementFee;
emit ManagementFeeCharged(applicableManagementFee);
}
/**
* @notice Collects the fees available in the vault.
* @dev This endpoint can be called by any address.
*/
function collectFees() external nonReentrant ifConfigured {
uint256 t = feeCollectors.length;
if (t < 1) revert MissingFeeCollectors();
uint256 x = totalCollectableFees;
if (x > 0) {
uint256[] memory amounts = new uint256[](t);
for (uint256 i; i < t; i++) {
uint256 collectableFee = (feeCollectors[i].percentage * x) / 1e6;
// slither-disable-next-line timestamp
if (collectableFee > totalCollectableFees) revert CollectableFeesExceeded(collectableFee, totalCollectableFees);
amounts[i] = collectableFee;
totalCollectableFees -= collectableFee;
}
emit FeesCollected();
// Untrusted changes
for (uint256 i; i < t; i++) {
SafeERC20Upgradeable.safeTransfer(IERC20Upgradeable(_referenceAsset), feeCollectors[i].collectorAddress, amounts[i]);
}
}
}
function _afterPermit(
address assetIn,
uint256 amountIn,
address receiverAddr,
uint256 shares
) private {
// Log the event
emit Deposit(assetIn, amountIn, shares, msg.sender, receiverAddr);
// Transfer the input tokens
SafeERC20Upgradeable.safeTransferFrom(IERC20Upgradeable(assetIn), msg.sender, address(this), amountIn);
// Issue (mint) LP tokens to the receiver
IMintableBurnable(lpTokenAddress).mint(receiverAddr, shares);
}
function _beforeDeposit(
address assetIn,
uint256 amountIn,
address receiverAddr
) private view returns (uint256) {
if (amountIn < 1) revert InvalidAmount();
if (receiverAddr == address(0) || receiverAddr == address(this)) revert InvalidReceiver();
(uint256 shares, uint256 depositAmountInReferenceTokens) = previewDeposit(assetIn, amountIn);
if (shares < 1) revert InsufficientShares();
if (depositAmountInReferenceTokens > maxDepositAmount) revert MaxDepositAmountReached();
uint256 totalAssetsValuationInRefTokens = depositAmountInReferenceTokens + _getTotalAssets();
if (totalAssetsValuationInRefTokens > depositCap) revert DepositCapReached();
return shares;
}
/**
* @notice Previews the deposit of a whitelisted asset.
* @param assetIn The asset to deposit
* @param amountIn The deposit amount
* @return uint256 The equivalent number of shares
* @return uint256 The deposit amount expressed in reference tokens
*/
function previewDeposit(
address assetIn,
uint256 amountIn
) public view returns (uint256, uint256) {
return IEnableOnlyAssetsWhitelist(assetsWhitelistAddress).convertToShares(lpTokenAddress, assetIn, address(this), amountIn, externalAssets);
}
/**
* @notice Gets the change percentage of the amount specified.
* @param externalAssetsAmount The amount of external assets.
* @return uint256 The change percentage.
*/
function getChangePercentage(uint256 externalAssetsAmount) public view returns (uint256) {
if (externalAssets < 1) return uint256(0);
if (externalAssetsAmount < 1) return uint256(10000);
return (externalAssetsAmount > externalAssets)
? ((externalAssetsAmount * 10000) / externalAssets) - 10000
: ((externalAssets * 10000) / externalAssetsAmount) - 10000;
}
/**
* @notice Gets the maximum allowed change since the last update.
* @return uint256 The maximum allowed change, as a percentage.
*/
function getMaxAllowedChange() public view returns (uint256) {
// slither-disable-next-line timestamp
if (block.timestamp + _TIMESTAMP_MANIPULATION_WINDOW < assetsUpdatedOn) revert InvalidTimestamp();
// (Max change per day * Time interval in seconds since last update) / (60 * 60 * 24)
return (maxChangePercent * (block.timestamp - assetsUpdatedOn)) / uint256(86400);
}
function _fromInputAssetToReferenceAsset(
address depositableAssetAddr,
uint256 amountIn
) internal virtual view returns (uint256) {
return IEnableOnlyAssetsWhitelist(assetsWhitelistAddress).fromInputAssetToReferenceAsset(depositableAssetAddr, amountIn);
}
/// @dev Internal conversion function (from shares to assets) with support for rounding direction.
function _convertToAssets(uint256 shares, MathUpgradeable.Rounding rounding) internal view returns (uint256) {
uint256 tSupply = IERC20Upgradeable(lpTokenAddress).totalSupply();
return (tSupply < 1) ? shares : shares.mulDiv(_getTotalAssets(), tSupply, rounding);
}
/// @dev Gets the amount of assets managed by the vault. The amount is expressed in reference tokens.
function _getTotalAssets() internal virtual view returns (uint256) {
return IEnableOnlyAssetsWhitelist(assetsWhitelistAddress).getTotalAssetsValuation(externalAssets);
}
/**
* @notice Gets the amount of total assets managed by the vault.
* @return uint256 The amount of total assets managed by the vault.
*/
function getTotalAssets() external virtual view returns (uint256) {
return _getTotalAssets();
}
}
// src/tokenized-vaults/base/TimelockedVault.sol
abstract contract TimelockedVault is OraclizedMultiAssetVault {
error WithdrawalsPaused();
error WithdrawalLimitReached();
error AmountTooLow();
error NoSharesForReceiver();
error TooEarly();
error NothingToProcess();
error LimitRequired();
error VaultNotTimelocked();
error InvalidDepositLimit();
error InvalidWithdrawalLimit();
/// @dev The liquidation hour defaults to 0:00 UTC
uint8 constant internal _DEFAULT_LIQUIDATION_HOUR = 0;
// --------------------------------------------------------------------------
// Storage layout
// --------------------------------------------------------------------------
/// @notice The maximum withdrawal amount.
uint256 public maxWithdrawalAmount;
/// @notice The fee applicable to instant redemptions, expressed in bps.
uint256 public instantRedemptionFee;
/// @notice The duration of lagged redemptions.
uint256 public lagDuration;
/// @notice The fee applicable to lagged redemptions.
uint256 public withdrawalFee;
/// @notice The total number of shares that need to be burned at the current point in time.
uint256 public globalLiabilityShares;
/// @dev The number of shares (LP tokens) that need to be burned on a given point in time.
mapping (bytes32 => uint256) internal _dailyRequirement;
/// @dev The number of shares that can be burned by a given address at a specific point in time
mapping (bytes32 => mapping(address => uint256)) internal _burnableAmounts;
/// @dev The list of addresses that can claim funds at a given point in time.
mapping (bytes32 => address[]) internal _uniqueReceiversPerCluster;
/// @dev The index of each unique receiver per cluster
mapping (bytes32 => mapping(address => uint256)) internal _receiverIndexes;
/// @notice Indicates if the redemption fee stays in the vault, giving a PnL boost.
bool public keepFeeInVault;
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[9] private __gap;
// --------------------------------------------------------------------------
// Events
// --------------------------------------------------------------------------
/**
* @notice This event is triggered when the holder of LP tokens requests a redemption.
* @dev This event is triggered if the redemptions are lagged.
* @param shares The number of shares (LP tokens) to burn.
* @param holderAddr The address of the holder.
* @param receiverAddr The address of the receiver.
*/
event WithdrawalRequested(uint256 shares, address indexed holderAddr, address indexed receiverAddr);
/**
* @notice This event is triggered when a lagged redemption is processed.
* @param assetsAmount The amount of underlying assets sent to the receiving address.
* @param receiverAddr The address of the receiver.
*/
event WithdrawalProcessed(uint256 assetsAmount, address indexed receiverAddr);
event Withdraw(
address indexed sender,
address indexed receiver,
address indexed owner,
uint256 assets,
uint256 shares
);
// --------------------------------------------------------------------------
// Modifiers
// --------------------------------------------------------------------------
modifier ifWithdrawalsNotPaused() {
if (withdrawalsPaused) revert WithdrawalsPaused();
_;
}
// --------------------------------------------------------------------------
// Functions
// --------------------------------------------------------------------------
/**
* @notice Updates the fee applicable to instant redemptions.
* @param newValue The new fee.
* @param pKeepFeeInVault If true, the redemption fee stays in the vault giving a PnL boost.
*/
function updateInstantRedemptionFee(
uint256 newValue,
bool pKeepFeeInVault
) external nonReentrant onlyOwner {
instantRedemptionFee = newValue;
keepFeeInVault = pKeepFeeInVault;
}
/**
* @notice Updates the issuance and redemption settings of the vault.
* @param newMaxDepositAmount The maximum deposit amount of reference assets (say USDC) investors are allowed to deposit in the vault.
* @param newMaxWithdrawalAmount The maximum withdrawal amount of the vault, expressed in reference assets (for example: USDC)
*/
function updateLimits(
uint256 newMaxDepositAmount,
uint256 newMaxWithdrawalAmount,
uint256 newDepositCap
) external nonReentrant onlyOwner {
if (newMaxDepositAmount < 1) revert InvalidDepositLimit();
if (newMaxWithdrawalAmount < 1) revert InvalidWithdrawalLimit();
maxDepositAmount = newMaxDepositAmount;
maxWithdrawalAmount = newMaxWithdrawalAmount;
depositCap = newDepositCap;
}
/**
* @notice Redeems the number of shares specified, instantly.
* @dev The redemption transfers reference tokens only. Throws in case of insufficient balance.
* @param shares The number of shares to redeem.
* @param receiverAddr The address of the receiver.
*/
function instantRedeem(
uint256 shares,
address receiverAddr
) external nonReentrant ifConfigured ifWithdrawalsNotPaused ifSenderWhitelisted {
// Checks
if ((receiverAddr == address(0)) || (receiverAddr == address(this))) revert InvalidReceiver();
if (shares < 1) revert InvalidAmount();
_executeRedemption(shares, receiverAddr, true);
}
/**
* @notice Requests the redemption of the shares specified.
* @dev Throws if the vault is not time-locked.
* @param shares The number of shares to redeem.
* @param receiverAddr The receiving address.
* @return claimableEpoch The Unix epoch at which the redemption can take place.
*/
function requestRedeem(
uint256 shares,
address receiverAddr
) external nonReentrant ifConfigured ifWithdrawalsNotPaused ifSenderWhitelisted returns (
uint256 claimableEpoch,
uint256 year,
uint256 month,
uint256 day
) {
// Validate the input parameters
if ((receiverAddr == address(0)) || (receiverAddr == address(this))) revert InvalidReceiver();
if (shares < 1) revert InvalidAmount();
(uint256 assetsAmount, uint256 assetsAfterFee) = _previewRedemption(shares, withdrawalFee);
if (assetsAmount > maxWithdrawalAmount) revert WithdrawalLimitReached();
if (assetsAfterFee < 1) revert AmountTooLow();
// If the vault has no time-lock then it doesn't make sense to request a redemption (tx1) and claim later (tx2).
// Users should call the function "instantRedeem()" instead.
if (lagDuration < 1) revert VaultNotTimelocked();
// The time slot (cluster) of the lagged withdrawal
(year, month, day) = DateUtils.timestampToDate(block.timestamp + _TIMESTAMP_MANIPULATION_WINDOW + lagDuration);
// The hash of the cluster
bytes32 dailyCluster = keccak256(abi.encode(year, month, day));
// The withdrawal will be processed at the following epoch
claimableEpoch = DateUtils.timestampFromDateTime(year, month, day, _DEFAULT_LIQUIDATION_HOUR, 0, 0);
// Trusted internal changes
globalLiabilityShares += shares;
_dailyRequirement[dailyCluster] += shares;
// Unique receivers by date. We will transfer underlying tokens to this receiver shortly.
if (_burnableAmounts[dailyCluster][receiverAddr] == 0) {
_uniqueReceiversPerCluster[dailyCluster].push(receiverAddr);
_receiverIndexes[dailyCluster][receiverAddr] = _uniqueReceiversPerCluster[dailyCluster].length;
}
_burnableAmounts[dailyCluster][receiverAddr] += shares;
emit WithdrawalRequested(shares, msg.sender, receiverAddr);
// Trusted external changes
SafeERC20Upgradeable.safeTransferFrom(IERC20Upgradeable(lpTokenAddress), msg.sender, address(this), shares);
}
/**
* @notice Allows any public address to process the scheduled withdrawal requests of the receiver specified.
* @dev Throws if the receiving address is not the legitimate address you registered via "requestRedeem()"
* @param year The year component of the claim. It can be a past date.
* @param month The month component of the claim. It can be a past date.
* @param day The day component of the claim. It can be a past date.
* @param receiverAddr The address of the legitimate receiver of the funds.
* @return uint256 The effective number of shares (LP tokens) that were burnt from the liquidity pool.
* @return uint256 The effective amount of underlying assets that were transfered to the receiver.
*/
function claim(
uint256 year,
uint256 month,
uint256 day,
address receiverAddr
) external nonReentrant ifConfigured ifWithdrawalsNotPaused ifSenderWhitelisted returns (
uint256,
uint256
) {
bytes32 dailyCluster = keccak256(abi.encode(year, month, day));
// The number of shares to burn for a given cluster and receiver
uint256 shares = _burnableAmounts[dailyCluster][receiverAddr];
if (shares < 1) revert NoSharesForReceiver();
// Make sure withdrawals are processed at the expected epoch only.
// slither-disable-next-line timestamp
if (
(lagDuration > 0) &&
(msg.sender != _owner) &&
(msg.sender != operatorAddress) &&
(block.timestamp + _TIMESTAMP_MANIPULATION_WINDOW < DateUtils.timestampFromDateTime(year, month, day, _DEFAULT_LIQUIDATION_HOUR, 0, 0))
) {
revert TooEarly();
}
// Trusted oracle call (view)
(uint256 assetsAmount, uint256 assetsAfterFee) = _previewRedemption(shares, withdrawalFee);
// The withdrawal fee to apply
uint256 applicableFee = assetsAmount - assetsAfterFee;
// Internal state changes (trusted)
_burnableAmounts[dailyCluster][receiverAddr] = 0; // Same as substract, but setting this back to zero is more efficient.
_dailyRequirement[dailyCluster] -= shares;
globalLiabilityShares -= shares;
totalCollectableFees += applicableFee;
_deleteReceiver(dailyCluster, receiverAddr);
emit WithdrawalProcessed(assetsAfterFee, receiverAddr);
// [Trusted external change]: alter the total supply of LP tokens.
// The external call below is considered trusted because the vault is allowed to burn LP tokens.
IMintableBurnable(lpTokenAddress).burn(address(this), shares);
// [Untrusted external change]: defer the ERC20 transfer to the Reference Asset
SafeERC20Upgradeable.safeTransfer(IERC20Upgradeable(_referenceAsset), receiverAddr, assetsAfterFee);
return (shares, assetsAfterFee);
}
/**
* @notice Processes all of the withdrawal requests scheduled for the date specified.
* @dev Throws if the date is earlier than the liquidation/processing hour.
* @param year The year component of the claim. It can be a past date.
* @param month The month component of the claim. It can be a past date.
* @param day The day component of the claim. It can be a past date.
* @param maxLimit The number of transactions to process. The maximum is defined by the function "getScheduledTransactionsByDate()"
*/
function processAllClaimsByDate(
uint256 year,
uint256 month,
uint256 day,
uint256 maxLimit
) external nonReentrant ifConfigured ifWithdrawalsNotPaused {
if (maxLimit < 1) revert LimitRequired();
bytes32 dailyCluster = keccak256(abi.encode(year, month, day));
// Make sure we have pending requests to process.
if (_dailyRequirement[dailyCluster] < 1) revert NothingToProcess();
// Make sure withdrawals are processed at the expected epoch only.
// The owner or the operator are allowed to bypass this check.
if (
(lagDuration > 0) &&
(msg.sender != _owner) &&
(msg.sender != operatorAddress) &&
// slither-disable-next-line timestamp
(block.timestamp + _TIMESTAMP_MANIPULATION_WINDOW < DateUtils.timestampFromDateTime(year, month, day, _DEFAULT_LIQUIDATION_HOUR, 0, 0))
) {
revert TooEarly();
}
// This is the number of unique ERC20 transfers we will need to make in this transaction
uint256 workSize = (_uniqueReceiversPerCluster[dailyCluster].length > maxLimit) ? maxLimit : _uniqueReceiversPerCluster[dailyCluster].length;
uint256 startingPos = _uniqueReceiversPerCluster[dailyCluster].length;
address[] memory receivers = new address[](workSize);
uint256[] memory amounts = new uint256[](workSize);
uint256 sharesToBurn;
address receiverAddr;
uint256 assetsAmount;
uint256 assetsAfterFee;
uint256 x = workSize;
for (uint256 i = startingPos; i > (startingPos - workSize); i--) {
receiverAddr = _uniqueReceiversPerCluster[dailyCluster][i - 1];
x--;
receivers[x] = receiverAddr;
sharesToBurn += _burnableAmounts[dailyCluster][receiverAddr];
// Costly operation inside a loop. The external call is trusted though.
(assetsAmount, assetsAfterFee) = _previewRedemption(_burnableAmounts[dailyCluster][receiverAddr], withdrawalFee);
emit WithdrawalProcessed(assetsAfterFee, receiverAddr);
amounts[x] = assetsAfterFee;
totalCollectableFees += (assetsAmount - assetsAfterFee);
_burnableAmounts[dailyCluster][receiverAddr] = 0;
_uniqueReceiversPerCluster[dailyCluster].pop();
_receiverIndexes[dailyCluster][receiverAddr] = 0;
}
globalLiabilityShares -= sharesToBurn;
_dailyRequirement[dailyCluster] -= sharesToBurn;
IMintableBurnable(lpTokenAddress).burn(address(this), sharesToBurn);
// Untrusted external calls
for (uint256 i; i < receivers.length; i++) {
SafeERC20Upgradeable.safeTransfer(IERC20Upgradeable(_referenceAsset), receivers[i], amounts[i]);
}
}
function _executeRedemption(
uint256 shares,
address receiverAddr,
bool isInstant
) internal returns (uint256 assetsAmount, uint256 assetsAfterFee) {
// Apply the redemption fee
uint256 applicableRedemptionFee = (isInstant) ? instantRedemptionFee : withdrawalFee;
(assetsAmount, assetsAfterFee) = _previewRedemption(shares, applicableRedemptionFee);
if (assetsAmount > maxWithdrawalAmount) revert WithdrawalLimitReached();
if (assetsAfterFee < 1) revert AmountTooLow();
if (!keepFeeInVault) totalCollectableFees += (assetsAmount - assetsAfterFee);
// Emit the withdrawal event
emit Withdraw(msg.sender, receiverAddr, msg.sender, assetsAfterFee, shares);
// Burn the respective number of shares from the token holder
IMintableBurnable(lpTokenAddress).burn(msg.sender, shares);
// Transfer the funds to the receiving address
SafeERC20Upgradeable.safeTransfer(IERC20Upgradeable(_referenceAsset), receiverAddr, assetsAfterFee);
}
function _deleteReceiver(bytes32 dailyCluster, address addr) private {
uint256 idx = _receiverIndexes[dailyCluster][addr] - 1;
uint256 totalReceiversByDate = _uniqueReceiversPerCluster[dailyCluster].length;
address lastItem = _uniqueReceiversPerCluster[dailyCluster][totalReceiversByDate - 1];
if (addr != lastItem) {
_uniqueReceiversPerCluster[dailyCluster][totalReceiversByDate - 1] = _uniqueReceiversPerCluster[dailyCluster][idx];
_uniqueReceiversPerCluster[dailyCluster][idx] = lastItem;
_receiverIndexes[dailyCluster][lastItem] = idx + 1;
}
_uniqueReceiversPerCluster[dailyCluster].pop();
_receiverIndexes[dailyCluster][addr] = 0;
}
function _previewRedemption(
uint256 shares,
uint256 fee
) internal view returns (
uint256 assetsAmount,
uint256 assetsAfterFee
) {
assetsAmount = _convertToAssets(shares, MathUpgradeable.Rounding.Down);
assetsAfterFee = assetsAmount;
uint256 applicableFee = 0;
if (fee > 0) {
applicableFee = (fee * assetsAmount) / 1e4;
assetsAfterFee = assetsAmount - applicableFee;
}
return (assetsAmount, assetsAfterFee);
}
/**
* @notice Previews a redemption.
* @param shares The number of shares to redeem.
* @param isInstant Indicates whether the redemption is lagged or instant.
* @return assetsAmount The withdrawal amount without any applicable fees.
* @return assetsAfterFee The effective withdrawal amount.
*/
function previewRedemption(
uint256 shares,
bool isInstant
) external view returns (
uint256 assetsAmount,
uint256 assetsAfterFee
) {
uint256 applicableRedemptionFee = (isInstant) ? instantRedemptionFee : withdrawalFee;
return _previewRedemption(shares, applicableRedemptionFee);
}
/**
* @notice Gets the date at which your withdrawal request can be claimed.
* @return year The year.
* @return month The month.
* @return day The day.
* @return claimableEpoch The Unix epoch at which your withdrawal request can be claimed.
*/
function getWithdrawalEpoch() external view returns (
uint256 year,
uint256 month,
uint256 day,
uint256 claimableEpoch
) {
(year, month, day) = DateUtils.timestampToDate(block.timestamp + _TIMESTAMP_MANIPULATION_WINDOW + lagDuration);
claimableEpoch = DateUtils.timestampFromDateTime(year, month, day, _DEFAULT_LIQUIDATION_HOUR, 0, 0);
}
/**
* @notice Gets the funding requirement of the date specified.
* @dev This is a forecast on the amount of assets that need to be available at the pool on the date specified.
* @param year The year.
* @param month The month.
* @param day The day.
* @return shares The number of shares (LP tokens) that will be burned on the date specified.
*/
function getRequirementByDate(
uint256 year,
uint256 month,
uint256 day
) external view returns (uint256 shares) {
bytes32 dailyCluster = keccak256(abi.encode(year, month, day));
shares = _dailyRequirement[dailyCluster];
}
/**
* @notice Gets the total number of shares to burn at the date specified for a given receiver.
* @dev This is a forecast on the amount of assets that can be claimed by a given party on the date specified.
* @param year The year.
* @param month The month.
* @param day The day.
* @param receiverAddr The address of the receiver.
* @return uint256 The total number of shares to burn at the date specified for a given receiver.
*/
function getBurnableAmountByReceiver(
uint256 year,
uint256 month,
uint256 day,
address receiverAddr
) external view returns (uint256) {
bytes32 dailyCluster = keccak256(abi.encode(year, month, day));
return _burnableAmounts[dailyCluster][receiverAddr];
}
/**
* @notice Gets the total number of transactions to run at a given date.
* @param year The year.
* @param month The month.
* @param day The day.
* @return totalTransactions The number of transactions to execute.
* @return executionEpoch The Unix epoch at which these transactions should be submitted to the blockchain.
*/
function getScheduledTransactionsByDate(
uint256 year,
uint256 month,
uint256 day
) external view returns (uint256 totalTransactions, uint256 executionEpoch) {
bytes32 dailyCluster = keccak256(abi.encode(year, month, day));
totalTransactions = _uniqueReceiversPerCluster[dailyCluster].length;
executionEpoch = DateUtils.timestampFromDateTime(year, month, day, _DEFAULT_LIQUIDATION_HOUR, 0, 0);
}
}
// src/tokenized-vaults/TokenizedVault.sol
/**
* @title Represents an upgradeable tokenized vault.
*/
contract TokenizedVault is ITokenizedVault, TimelockedVault {
/// @notice The high watermark.
uint256 public highWatermark;
/// @notice The update date of the high watermark
uint256 public watermarkUpdatedOn;
/// @notice The interval at which the high watermark can be updated.
uint256 public watermarkTimeWindow;
/// @notice The rate for performance fees.
uint256 public performanceFeeRate;
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[10] private __gap;
constructor() {
_disableInitializers();
}
// --------------------------------------------------------------------------
// Functions
// --------------------------------------------------------------------------
/**
* @notice Proxy initialization function.
* @param ownerAddr The owner of the vault.
*/
function initialize(address ownerAddr) external virtual initializer {
depositsPaused = true;
withdrawalsPaused = true;
_owner = ownerAddr;
}
/**
* @notice Configures the vault.
* @param newConfig The vault configuration.
*/
function configure(
ConfigInfo memory newConfig
) public virtual override nonReentrant onlyOwner ifNotConfigured {
if (newConfig.lagDuration < uint256(86400)) revert InvalidLagDuration();
// Set the configuration settings
watermarkTimeWindow = newConfig.watermarkTimeWindow;
maxDepositAmount = newConfig.maxDepositAmount;
maxWithdrawalAmount = newConfig.maxWithdrawalAmount;
depositCap = newConfig.maxDepositAmount;
instantRedemptionFee = newConfig.instantRedemptionFee;
lagDuration = newConfig.lagDuration;
withdrawalFee = newConfig.withdrawalFee;
maxChangePercent = newConfig.maxChangePercent;
managementFeePercent = newConfig.managementFeePercent;
performanceFeeRate = newConfig.performanceFeeRate;
operatorAddress = newConfig.operatorAddress;
scheduledCallerAddress = newConfig.scheduledCallerAddress;
lpTokenAddress = newConfig.lpTokenAddress;
_referenceAsset = newConfig.referenceAsset;
assetsUpdatedOn = block.timestamp;
feesTimestamp = block.timestamp;
assetsWhitelistAddress = newConfig.assetsWhitelistAddress;
sendersWhitelistAddress = newConfig.sendersWhitelistAddress;
depositsPaused = false;
withdrawalsPaused = false;
watermarkUpdatedOn = block.timestamp;
_owner = newConfig.futureOwnerAddress;
// Mark the contract as configured
_configured = true;
emit ContractConfigured();
// External call validations
if (_referenceAsset != IEnableOnlyAssetsWhitelist(assetsWhitelistAddress).REFERENCE_ASSET()) revert ReferenceAssetMismatch();
if (IERC20MetadataUpgradeable(_referenceAsset).decimals() != IERC20MetadataUpgradeable(lpTokenAddress).decimals()) revert TokenDecimalsMismatch();
uint256 shares = 1 * (10 ** IERC20MetadataUpgradeable(lpTokenAddress).decimals());
uint256 currentSharePrice = _convertToAssets(shares, MathUpgradeable.Rounding.Down);
highWatermark = currentSharePrice;
}
/**
* @notice Updates the timelock for withdrawals.
* @dev Setting the timelock to zero will allow to withdraw funds immediately from the vault.
* @param newDuration The duration of the timelock, expressed in seconds. It can be zero.
*/
function updateTimelockDuration(uint256 newDuration) external nonReentrant ifConfigured onlyOwner {
// The time-lock for withdrawals can be zero
lagDuration = newDuration;
// Build the hash of this call and attempt to consume it. The call reverts if the hash can't be consumed.
bytes32 h = keccak256(abi.encode(
abi.encodeWithSignature(
"updateTimelockDuration(uint256)",
newDuration
)
));
IResourceBasedTimelockedCall(scheduledCallerAddress).consume(h);
}
/**
* @notice Updates the performance fee.
* @param newValue The new performance fee.
*/
function updatePerformanceFee(uint256 newValue) external nonReentrant onlyOwner {
performanceFeeRate = newValue;
}
/**
* @notice Charges the performance fees.
* @dev This function is callable by anyone.
*/
function chargePerformanceFees() external virtual nonReentrant {
if (block.timestamp - watermarkUpdatedOn < watermarkTimeWindow) revert HighWatermarkDurationError();
uint256 currentSharePrice = _getSharePrice();
if (currentSharePrice <= highWatermark) revert HighWatermarkViolation();
// Calculate current high water mark totalAssets in reference asset
uint256 totalShares = IERC20Upgradeable(lpTokenAddress).totalSupply();
uint8 lpTokenDecimals = IERC20MetadataUpgradeable(lpTokenAddress).decimals();
uint256 highWatermarkNav = (highWatermark * totalShares) / (10 ** lpTokenDecimals);
uint256 currentTotalAssets = _getTotalAssets();
uint256 totalAssetsIncrease = currentTotalAssets - highWatermarkNav;
uint256 totalPerformanceFee = (totalAssetsIncrease * performanceFeeRate) / 1e6;
uint256 t = performanceFeeRecipients.length;
uint256[] memory amounts = new uint256[](t);
for (uint256 i; i < t; i++) {
uint256 collectableFee = (performanceFeeRecipients[i].percentage * totalPerformanceFee) / 1e6;
if (collectableFee > totalPerformanceFee) revert CollectableFeesExceeded(collectableFee, totalPerformanceFee);
if (collectableFee < 1) revert FeeAmountTooLow();
amounts[i] = collectableFee;
}
watermarkUpdatedOn = block.timestamp;
highWatermark = currentSharePrice;
for (uint256 i; i < t; i++) {
SafeERC20Upgradeable.safeTransfer(IERC20Upgradeable(_referenceAsset), performanceFeeRecipients[i].collectorAddress, amounts[i]);
}
}
/**
* @notice Runs an emergency withdrawal.
* @dev Calling this function pauses deposits and withdrawals automatically.
* @param receiverAddr The receiving address.
*/
function emergencyWithdraw(address receiverAddr) external nonReentrant ifConfigured onlyOwner {
if ((receiverAddr == address(0)) || (receiverAddr == address(this))) revert InvalidReceiver();
// Pause deposits and withdrawals, provided the emergency scenario
depositsPaused = true;
withdrawalsPaused = true;
emit OnEmergencyWithdraw(receiverAddr);
address[] memory assetAddresses = IEnableOnlyAssetsWhitelist(assetsWhitelistAddress).getWhitelistedAssets();
uint256 t = assetAddresses.length;
uint256 b = IERC20Upgradeable(_referenceAsset).balanceOf(address(this));
if (b > 0) SafeERC20Upgradeable.safeTransfer(IERC20Upgradeable(_referenceAsset), receiverAddr, b);
address assetAddr;
for (uint256 i; i < t; i++) {
assetAddr = assetAddresses[i];
b = IERC20Upgradeable(assetAddr).balanceOf(address(this));
if (b > 0) SafeERC20Upgradeable.safeTransfer(IERC20Upgradeable(assetAddr), receiverAddr, b);
}
}
/**
* @notice Gets the reference asset of the vault.
* @return address Returns the address of the reference asset.
*/
function asset() external view override returns (address) {
return _referenceAsset;
}
/**
* @notice Gets the current share price.
* @return uint256 The share price.
*/
function getSharePrice() external view returns (uint256) {
return _getSharePrice();
}
function _getSharePrice() internal view returns (uint256) {
uint256 shares = 1 * (10 ** IERC20MetadataUpgradeable(lpTokenAddress).decimals());
return _convertToAssets(shares, MathUpgradeable.Rounding.Down);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccountNotWhitelisted","type":"error"},{"inputs":[],"name":"AlreadyConfigured","type":"error"},{"inputs":[],"name":"AmountTooLow","type":"error"},{"inputs":[],"name":"AssetNotWhitelisted","type":"error"},{"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"remaining","type":"uint256"}],"name":"CollectableFeesExceeded","type":"error"},{"inputs":[],"name":"DepositCapReached","type":"error"},{"inputs":[],"name":"DepositsPaused","type":"error"},{"inputs":[],"name":"FeeAmountTooLow","type":"error"},{"inputs":[],"name":"FeesMustSum100","type":"error"},{"inputs":[],"name":"HighWatermarkDurationError","type":"error"},{"inputs":[],"name":"HighWatermarkViolation","type":"error"},{"inputs":[],"name":"InsufficientShares","type":"error"},{"inputs":[],"name":"InvalidAccountType","type":"error"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidDepositLimit","type":"error"},{"inputs":[],"name":"InvalidExternalAssets","type":"error"},{"inputs":[],"name":"InvalidLagDuration","type":"error"},{"inputs":[],"name":"InvalidReceiver","type":"error"},{"inputs":[],"name":"InvalidTimestamp","type":"error"},{"inputs":[],"name":"InvalidWithdrawalLimit","type":"error"},{"inputs":[],"name":"LimitRequired","type":"error"},{"inputs":[],"name":"MaxAllowedChangeReached","type":"error"},{"inputs":[],"name":"MaxDepositAmountReached","type":"error"},{"inputs":[],"name":"MissingFeeCollectors","type":"error"},{"inputs":[],"name":"NoSharesForReceiver","type":"error"},{"inputs":[],"name":"NotConfigured","type":"error"},{"inputs":[],"name":"NothingToProcess","type":"error"},{"inputs":[],"name":"OnlyOwnerOrOperator","type":"error"},{"inputs":[],"name":"OperatorOnly","type":"error"},{"inputs":[],"name":"OwnerAddressRequired","type":"error"},{"inputs":[],"name":"OwnerOnly","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[],"name":"ReferenceAssetMismatch","type":"error"},{"inputs":[],"name":"SenderNotWhitelisted","type":"error"},{"inputs":[],"name":"TokenDecimalsMismatch","type":"error"},{"inputs":[],"name":"TooEarly","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"VaultNotTimelocked","type":"error"},{"inputs":[],"name":"WhitelistLimitReached","type":"error"},{"inputs":[],"name":"WithdrawalLimitReached","type":"error"},{"inputs":[],"name":"WithdrawalsPaused","type":"error"},{"inputs":[],"name":"ZeroAddressError","type":"error"},{"anonymous":false,"inputs":[],"name":"ContractConfigured","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"assetIn","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":true,"internalType":"address","name":"senderAddr","type":"address"},{"indexed":true,"internalType":"address","name":"receiverAddr","type":"address"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"bDepositsPaused","type":"bool"},{"indexed":false,"internalType":"bool","name":"bWithdrawalsPaused","type":"bool"}],"name":"DepositWithdrawalStatusChanged","type":"event"},{"anonymous":false,"inputs":[],"name":"FeesCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"managementFeeAmount","type":"uint256"}],"name":"ManagementFeeCharged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newManagementFeePercent","type":"uint256"}],"name":"ManagementFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"MaxChangePercentUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"receiverAddr","type":"address"}],"name":"OnEmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","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":"newWhitelistAddr","type":"address"}],"name":"SendersWhitelistUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"subAccountAddr","type":"address"}],"name":"SubAccountDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"subAccountAddr","type":"address"}],"name":"SubAccountEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"assetsAmount","type":"uint256"},{"indexed":true,"internalType":"address","name":"receiverAddr","type":"address"}],"name":"WithdrawalProcessed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":true,"internalType":"address","name":"holderAddr","type":"address"},{"indexed":true,"internalType":"address","name":"receiverAddr","type":"address"}],"name":"WithdrawalRequested","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"asset","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assetsUpdatedOn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assetsWhitelistAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"chargeManagementFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"chargePerformanceFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"year","type":"uint256"},{"internalType":"uint256","name":"month","type":"uint256"},{"internalType":"uint256","name":"day","type":"uint256"},{"internalType":"address","name":"receiverAddr","type":"address"}],"name":"claim","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collectFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"maxDepositAmount","type":"uint256"},{"internalType":"uint256","name":"maxWithdrawalAmount","type":"uint256"},{"internalType":"uint256","name":"instantRedemptionFee","type":"uint256"},{"internalType":"uint256","name":"lagDuration","type":"uint256"},{"internalType":"uint256","name":"withdrawalFee","type":"uint256"},{"internalType":"uint256","name":"watermarkTimeWindow","type":"uint256"},{"internalType":"uint256","name":"maxChangePercent","type":"uint256"},{"internalType":"uint256","name":"managementFeePercent","type":"uint256"},{"internalType":"uint256","name":"performanceFeeRate","type":"uint256"},{"internalType":"address","name":"sendersWhitelistAddress","type":"address"},{"internalType":"address","name":"operatorAddress","type":"address"},{"internalType":"address","name":"scheduledCallerAddress","type":"address"},{"internalType":"address","name":"lpTokenAddress","type":"address"},{"internalType":"address","name":"referenceAsset","type":"address"},{"internalType":"address","name":"futureOwnerAddress","type":"address"},{"internalType":"address","name":"assetsWhitelistAddress","type":"address"}],"internalType":"struct ITokenizedVault.ConfigInfo","name":"newConfig","type":"tuple"}],"name":"configure","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"assetIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address","name":"receiverAddr","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"inputAssetAddr","type":"address"},{"internalType":"uint256","name":"depositAmount","type":"uint256"},{"internalType":"address","name":"subAccountAddr","type":"address"}],"name":"depositToSubaccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"assetIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address","name":"receiverAddr","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"}],"name":"depositWithPermit","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositsPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"disableSubAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiverAddr","type":"address"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint8","name":"accountType","type":"uint8"}],"name":"enableSubAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"externalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"feeCollectors","outputs":[{"internalType":"address","name":"collectorAddress","type":"address"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feesTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"year","type":"uint256"},{"internalType":"uint256","name":"month","type":"uint256"},{"internalType":"uint256","name":"day","type":"uint256"},{"internalType":"address","name":"receiverAddr","type":"address"}],"name":"getBurnableAmountByReceiver","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"externalAssetsAmount","type":"uint256"}],"name":"getChangePercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFeeCollectors","outputs":[{"components":[{"internalType":"address","name":"collectorAddress","type":"address"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct IFeeCollectorsAware.CollectorDefinition[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxAllowedChange","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPerformanceFeeRecipients","outputs":[{"components":[{"internalType":"address","name":"collectorAddress","type":"address"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct IFeeCollectorsAware.CollectorDefinition[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"year","type":"uint256"},{"internalType":"uint256","name":"month","type":"uint256"},{"internalType":"uint256","name":"day","type":"uint256"}],"name":"getRequirementByDate","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"year","type":"uint256"},{"internalType":"uint256","name":"month","type":"uint256"},{"internalType":"uint256","name":"day","type":"uint256"}],"name":"getScheduledTransactionsByDate","outputs":[{"internalType":"uint256","name":"totalTransactions","type":"uint256"},{"internalType":"uint256","name":"executionEpoch","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSharePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWithdrawalEpoch","outputs":[{"internalType":"uint256","name":"year","type":"uint256"},{"internalType":"uint256","name":"month","type":"uint256"},{"internalType":"uint256","name":"day","type":"uint256"},{"internalType":"uint256","name":"claimableEpoch","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"globalLiabilityShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"highWatermark","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"ownerAddr","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiverAddr","type":"address"}],"name":"instantRedeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"instantRedemptionFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"keepFeeInVault","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lagDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lpTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"managementFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxChangePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxDepositAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxWithdrawalAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operatorAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"bPauseDeposits","type":"bool"},{"internalType":"bool","name":"bPauseWithdrawals","type":"bool"}],"name":"pauseDepositsAndWithdrawals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"performanceFeeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"performanceFeeRecipients","outputs":[{"internalType":"address","name":"collectorAddress","type":"address"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"assetIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"}],"name":"previewDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"bool","name":"isInstant","type":"bool"}],"name":"previewRedemption","outputs":[{"internalType":"uint256","name":"assetsAmount","type":"uint256"},{"internalType":"uint256","name":"assetsAfterFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"year","type":"uint256"},{"internalType":"uint256","name":"month","type":"uint256"},{"internalType":"uint256","name":"day","type":"uint256"},{"internalType":"uint256","name":"maxLimit","type":"uint256"}],"name":"processAllClaimsByDate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiverAddr","type":"address"}],"name":"requestRedeem","outputs":[{"internalType":"uint256","name":"claimableEpoch","type":"uint256"},{"internalType":"uint256","name":"year","type":"uint256"},{"internalType":"uint256","name":"month","type":"uint256"},{"internalType":"uint256","name":"day","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"scheduledCallerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sendersWhitelistAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalCollectableFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newWhitelistAddr","type":"address"}],"name":"updateAssetsWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"collectorAddress","type":"address"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct IFeeCollectorsAware.CollectorDefinition[]","name":"collectors","type":"tuple[]"}],"name":"updateFeeCollectors","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"},{"internalType":"bool","name":"pKeepFeeInVault","type":"bool"}],"name":"updateInstantRedemptionFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxDepositAmount","type":"uint256"},{"internalType":"uint256","name":"newMaxWithdrawalAmount","type":"uint256"},{"internalType":"uint256","name":"newDepositCap","type":"uint256"}],"name":"updateLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newManagementFeePercent","type":"uint256"}],"name":"updateManagementFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"updateMaxChangePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"updatePerformanceFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"collectorAddress","type":"address"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct IFeeCollectorsAware.CollectorDefinition[]","name":"collectors","type":"tuple[]"}],"name":"updatePerformanceFeeCollectors","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newWhitelistAddr","type":"address"}],"name":"updateSendersWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"updateTimelockDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"externalAssetsAmount","type":"uint256"}],"name":"updateTotalAssets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"watermarkTimeWindow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"watermarkUpdatedOn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelistedSubAccounts","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"inputAssetAddr","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"subAccountAddr","type":"address"}],"name":"withdrawFromSubaccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawalFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalsPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]Contract Creation Code
0x6080604052348015600e575f80fd5b5060156019565b60d3565b5f54610100900460ff161560835760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b5f5460ff9081161460d1575f805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b615e82806100e05f395ff3fe608060405234801561000f575f80fd5b5060043610610422575f3560e01c80638ed832711161022c578063d3a8d71811610135578063e976d431116100bf578063f5ae497a11610084578063f5ae497a146108e7578063fa20e0fe146108fa578063fc6fb83714610903578063ff06002b1461090c578063ff3c63c01461091f575f80fd5b8063e976d43114610891578063e9f2838e1461089a578063f2fde38b146108ae578063f3cbf47c146108c1578063f45346dc146108d4575f80fd5b8063dece010211610105578063dece010214610849578063e2eb36b914610851578063e30c397814610864578063e622868014610875578063e89813301461087e575f80fd5b8063d3a8d71814610826578063d961b58c1461082e578063dad361c514610837578063dbd5edc714610840575f80fd5b8063be1f9214116101b6578063c879657211610186578063c8796572146107dd578063c8e11e8e146107e5578063ca55a557146107f8578063cb3dc35714610800578063cdb1fb2b14610813575f80fd5b8063be1f921414610791578063c25dd81f146107a4578063c3646a0f146107b7578063c4d66de8146107ca575f80fd5b80639efee6be116101fc5780639efee6be14610711578063b3c9e83d14610724578063b4db4be814610737578063b8f82b261461074a578063bb2707091461075d575f80fd5b80638ed83271146106d957806390f1c5f1146106e257806399aa14d0146106f55780639cb43f8114610708575f80fd5b8063520cd0361161032e57806373f351c8116102b85780638120b579116102885780638120b5791461069a578063820fe4be146106a35780638bc7e8c4146106ac5780638c0190e3146106b55780638da5cb5b146106c8575f80fd5b806373f351c81461066d578063785c312714610676578063790739a21461067f57806379ba509714610692575f80fd5b806360da3e83116102fe57806360da3e83146106035780636c46407b146106175780636e07302b1461063f5780636f4ab3dd146106475780636ff1c9bc1461065a575f80fd5b8063520cd036146105b95780635486679d146105c15780635b1dac60146105c95780635d9e5cab146105d1575f80fd5b806322928208116103af57806336a0f8a51161037f57806336a0f8a51461055c57806336b7ea151461056f57806338d52e0f146105785780633c7ecb4a14610589578063502bee661461059c575f80fd5b8063229282081461051a57806324e86d671461052d57806328f856801461053657806329451a2214610549575f80fd5b8063127effb2116103f5578063127effb2146104a3578063184466c9146104ce5780631bca5113146104e15780631dddfbe1146104f45780631f4f519c14610507575f80fd5b8063030d624a1461042657806309f25fc01461043b5780630ffbfda414610459578063107703ab14610470575b5f80fd5b61043961043436600461557d565b610970565b005b610443610aea565b6040516104509190615594565b60405180910390f35b610462603e5481565b604051908152602001610450565b61048361047e366004615604565b610b5d565b604080519485526020850193909352918301526060820152608001610450565b6006546104b6906001600160a01b031681565b6040516001600160a01b039091168152602001610450565b6104396104dc36600461557d565b610f3e565b6104396104ef366004615632565b61104f565b6104396105023660046156a3565b61120a565b61043961051536600461557d565b6113ec565b610439610528366004615604565b6114c9565b610462602a5481565b61046261054436600461557d565b61167d565b610439610557366004615632565b611703565b61043961056a3660046156e2565b611890565b61046260185481565b601b546001600160a01b03166104b6565b61043961059736600461570b565b611939565b6031546105a99060ff1681565b6040519015158152602001610450565b610462611a8d565b610439611aeb565b610462611e4b565b6105e46105df36600461557d565b611e54565b604080516001600160a01b039093168352602083019190915201610450565b6006546105a990600160a01b900460ff1681565b61062a6106253660046156e2565b611e8a565b60408051928352602083019190915201610450565b610462611ee5565b6104396106553660046156a3565b611eee565b61043961066836600461570b565b6120b1565b61046260195481565b61046260145481565b61043961068d36600461557d565b612364565b610439612478565b610462603b5481565b61046260295481565b610462602b5481565b6104396106c3366004615733565b612564565b6002546001600160a01b03166104b6565b610462601a5481565b6105e46106f036600461557d565b612665565b61046261070336600461576d565b612674565b610462602c5481565b61043961071f3660046157da565b61290f565b61062a6107323660046157fd565b61297f565b61062a6107453660046157da565b612d26565b61062a61075836600461583b565b612d52565b61077f61076b36600461570b565b60096020525f908152604090205460ff1681565b60405160ff9091168152602001610450565b61046261079f3660046157fd565b612ded565b6008546104b6906001600160a01b031681565b6104396107c536600461570b565b612e46565b6104396107d836600461570b565b612ef4565b610439613028565b6104396107f336600461570b565b613212565b6104836132dd565b61043961080e3660046158d4565b613312565b601d546104b6906001600160a01b031681565b610439613743565b61046260155481565b610462603d5481565b610462601e5481565b610443613831565b6007546104b6906001600160a01b031681565b6003546001600160a01b03166104b6565b61046260165481565b61043961088c36600461557d565b61389a565b61046260285481565b6006546105a990600160a81b900460ff1681565b6104396108bc36600461570b565b6138f6565b6104396108cf3660046159d0565b61397c565b6104626108e23660046156a3565b613eaf565b601c546104b6906001600160a01b031681565b61046260175481565b610462603c5481565b61043961091a3660046159ff565b6140c6565b61046261092d3660046156e2565b604080516020808201959095528082019390935260608084019290925280518084039092018252608090920182528051908301205f908152602d90925290205490565b60026001540361099357604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166109c25760405163d311bc3960e01b815260040160405180910390fd5b6002546001600160a01b031633146109ed57604051630b2db9b760e31b815260040160405180910390fd5b5f81604051602401610a0191815260200190565b60408051601f19818403018152918152602080830180516001600160e01b0316630186b12560e11b1790529051610a39929101615a59565b60408051601f19818403018152908290528051602091820120601985905584835292507f2147e2bc8c39e67f74b1a9e08896ea1485442096765942206af1f4bc8bcde91791015b60405180910390a160075460405163af6f8c1b60e01b8152600481018390526001600160a01b039091169063af6f8c1b906024015b5f604051808303815f87803b158015610acc575f80fd5b505af1158015610ade573d5f803e3d5ffd5b50506001805550505050565b60606005805480602002602001604051908101604052809291908181526020015f905b82821015610b54575f848152602090819020604080518082019091526002850290910180546001600160a01b03168252600190810154828401529083529092019101610b0d565b50505050905090565b5f805f80600260015403610b8457604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff16610bb35760405163d311bc3960e01b815260040160405180910390fd5b600654600160a81b900460ff1615610bde57604051636022a9e760e01b815260040160405180910390fd5b6002546001600160a01b03163314801590610c0457506006546001600160a01b03163314155b8015610c1a57506008546001600160a01b031615155b8015610c8d5750600854604051633af32abf60e01b81523360048201526001600160a01b0390911690633af32abf90602401602060405180830381865afa158015610c67573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c8b9190615a6b565b155b15610cab57604051637ed449a960e01b815260040160405180910390fd5b6001600160a01b0385161580610cc957506001600160a01b03851630145b15610ce757604051631e4ec46b60e01b815260040160405180910390fd5b6001861015610d095760405163162908e360e11b815260040160405180910390fd5b5f80610d1788602b546141e0565b91509150602854821115610d3e57604051631b6132ab60e31b815260040160405180910390fd5b6001811015610d6057604051631fbaba3560e01b815260040160405180910390fd5b6001602a541015610d84576040516394fa99e760e01b815260040160405180910390fd5b602a54610da690610d9761012c42615a9a565b610da19190615a9a565b614226565b604080516020808201869052818301859052606080830185905283518084039091018152608090920190925280519101209297509095509350610ded8686865f808061424b565b965088602c5f828254610e009190615a9a565b90915550505f818152602d6020526040812080548b9290610e22908490615a9a565b90915550505f818152602e602090815260408083206001600160a01b038c1684529091528120549003610ea0575f818152602f6020908152604080832080546001810182558185528385200180546001600160a01b0319166001600160a01b038e169081179091558585529054603084528285209185529252909120555b5f818152602e602090815260408083206001600160a01b038c168452909152812080548b9290610ed1908490615a9a565b90915550506040518981526001600160a01b0389169033907fcf41fab81bee2456b7007d9d1a9e2261a6627a41eba8c3302b6b07f9a7a463959060200160405180910390a3601c54610f2e906001600160a01b031633308c6142a6565b5050600180555092959194509250565b600260015403610f6157604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff16610f905760405163d311bc3960e01b815260040160405180910390fd5b6002546001600160a01b03163314610fbb57604051630b2db9b760e31b815260040160405180910390fd5b602a819055604051602481018290525f9060440160408051601f19818403018152918152602080830180516001600160e01b031663184466c960e01b1790529051611007929101615a59565b60408051808303601f1901815290829052805160209091012060075463af6f8c1b60e01b8352600483018290529092506001600160a01b03169063af6f8c1b90602401610ab5565b60026001540361107257604051633ee5aeb560e01b815260040160405180910390fd5b60026001819055546001600160a01b031633146110a257604051630b2db9b760e31b815260040160405180910390fd5b5f8160018110156110c6576040516333f52ff560e01b815260040160405180910390fd5b6110d160055f61553b565b5f5b818110156111dc5760018585838181106110ef576110ef615aad565b9050604002016020013510156111185760405163162908e360e11b815260040160405180910390fd5b5f85858381811061112b5761112b615aad565b611141926020604090920201908101915061570b565b6001600160a01b0316036111685760405163e6c4247b60e01b815260040160405180910390fd5b84848281811061117a5761117a615aad565b905060400201602001358361118f9190615a9a565b925060058585838181106111a5576111a5615aad565b83546001810185555f94855260209094206040909102929092019260020290910190506111d28282615ac1565b50506001016110d3565b5081620f4240146112005760405163e31ac1db60e01b815260040160405180910390fd5b5050600180555050565b60026001540361122d57604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff1661125c5760405163d311bc3960e01b815260040160405180910390fd5b6006546001600160a01b0316331480159061128257506002546001600160a01b03163314155b156112a05760405163089b7a0760e41b815260040160405180910390fd5b60018210156112c25760405163162908e360e11b815260040160405180910390fd5b6001600160a01b0381165f9081526009602052604090205460ff1660018110156112ff5760405163014cc88960e21b815260040160405180910390fd5b601b545f906001600160a01b03868116911614611325576113208585614317565b611327565b835b905060145481111561134c5760405163200f4ff760e01b815260040160405180910390fd5b8060145f82825461135d9190615af7565b90915550505f1960ff8316016113d557604051631a4ca37b60e21b81526001600160a01b038681166004830152602482018690523060448301528416906369328dec906064015f604051808303815f87803b1580156113ba575f80fd5b505af11580156113cc573d5f803e3d5ffd5b505050506113e1565b6113e1858430876142a6565b505060018055505050565b60026001540361140f57604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff1661143e5760405163d311bc3960e01b815260040160405180910390fd5b6006546001600160a01b0316331480159061146457506002546001600160a01b03163314155b156114825760405163089b7a0760e41b815260040160405180910390fd5b5f61148c8261167d565b90505f611497611a8d565b9050808211156114ba57604051631373d6db60e01b815260040160405180910390fd5b50506014554260175560018055565b6002600154036114ec57604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff1661151b5760405163d311bc3960e01b815260040160405180910390fd5b600654600160a81b900460ff161561154657604051636022a9e760e01b815260040160405180910390fd5b6002546001600160a01b0316331480159061156c57506006546001600160a01b03163314155b801561158257506008546001600160a01b031615155b80156115f55750600854604051633af32abf60e01b81523360048201526001600160a01b0390911690633af32abf90602401602060405180830381865afa1580156115cf573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115f39190615a6b565b155b1561161357604051637ed449a960e01b815260040160405180910390fd5b6001600160a01b038116158061163157506001600160a01b03811630145b1561164f57604051631e4ec46b60e01b815260040160405180910390fd5b60018210156116715760405163162908e360e11b815260040160405180910390fd5b61120082826001614391565b5f6001601454101561169057505f919050565b60018210156116a25750612710919050565b60145482116116d857612710826014546127106116bf9190615b0a565b6116c99190615b35565b6116d39190615af7565b6116fd565b601454612710906116e98483615b0a565b6116f39190615b35565b6116fd9190615af7565b92915050565b60026001540361172657604051633ee5aeb560e01b815260040160405180910390fd5b60026001819055546001600160a01b0316331461175657604051630b2db9b760e31b815260040160405180910390fd5b5f81600181101561177a576040516333f52ff560e01b815260040160405180910390fd5b61178560045f61553b565b5f5b818110156111dc5760018585838181106117a3576117a3615aad565b9050604002016020013510156117cc5760405163162908e360e11b815260040160405180910390fd5b5f8585838181106117df576117df615aad565b6117f5926020604090920201908101915061570b565b6001600160a01b03160361181c5760405163e6c4247b60e01b815260040160405180910390fd5b84848281811061182e5761182e615aad565b90506040020160200135836118439190615a9a565b9250600485858381811061185957611859615aad565b83546001810185555f94855260209094206040909102929092019260020290910190506118868282615ac1565b5050600101611787565b6002600154036118b357604051633ee5aeb560e01b815260040160405180910390fd5b60026001819055546001600160a01b031633146118e357604051630b2db9b760e31b815260040160405180910390fd5b600183101561190557604051637fb1277b60e01b815260040160405180910390fd5b60018210156119275760405163e8498be360e01b815260040160405180910390fd5b601a92909255602855601e5560018055565b60026001540361195c57604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff1661198b5760405163d311bc3960e01b815260040160405180910390fd5b6002546001600160a01b031633146119b657604051630b2db9b760e31b815260040160405180910390fd5b6001600160a01b0381166119dd5760405163e6c4247b60e01b815260040160405180910390fd5b601d80546001600160a01b0319166001600160a01b03831690811790915560408051636f6a537f60e11b8152905163ded4a6fe916004808201926020929091908290030181865afa158015611a34573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a589190615b48565b601b546001600160a01b03908116911614611a8657604051630ecd66ab60e41b815260040160405180910390fd5b5060018055565b6017545f90611a9e61012c42615a9a565b1015611abd5760405163b7d0949760e01b815260040160405180910390fd5b6201518060175442611acf9190615af7565b601654611adc9190615b0a565b611ae69190615b35565b905090565b600260015403611b0e57604051633ee5aeb560e01b815260040160405180910390fd5b6002600155603d54603c54611b239042615af7565b1015611b42576040516311b96bf760e31b815260040160405180910390fd5b5f611b4b6144ed565b9050603b548111611b6f5760405163330c780160e11b815260040160405180910390fd5b601c54604080516318160ddd60e01b815290515f926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa158015611bb6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bda9190615b63565b90505f601c5f9054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c2d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c519190615b7a565b90505f611c5f82600a615c78565b83603b54611c6d9190615b0a565b611c779190615b35565b90505f611c8261458b565b90505f611c8f8383615af7565b90505f620f4240603e5483611ca49190615b0a565b611cae9190615b35565b6005549091505f8167ffffffffffffffff811115611cce57611cce615865565b604051908082528060200260200182016040528015611cf7578160200160208202803683370190505b5090505f5b82811015611dbc575f620f42408560058481548110611d1d57611d1d615aad565b905f5260205f20906002020160010154611d379190615b0a565b611d419190615b35565b905084811115611d7357604051630abb811560e21b815260048101829052602481018690526044015b60405180910390fd5b6001811015611d955760405163debabab560e01b815260040160405180910390fd5b80838381518110611da857611da8615aad565b602090810291909101015250600101611cfc565b5042603c55603b8990555f5b82811015611e3b57601b5460058054611e33926001600160a01b0316919084908110611df657611df6615aad565b5f91825260209091206002909102015484516001600160a01b0390911690859085908110611e2657611e26615aad565b60200260200101516145fa565b600101611dc8565b5050600180555050505050505050565b5f611ae66144ed565b60058181548110611e63575f80fd5b5f918252602090912060029091020180546001909101546001600160a01b03909116915082565b604080516020808201869052818301859052606080830185905283518084039091018152608090920183528151918101919091205f818152602f9092529181205491611eda86868685808061424b565b915050935093915050565b5f611ae661458b565b600260015403611f1157604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff16611f405760405163d311bc3960e01b815260040160405180910390fd5b6006546001600160a01b03163314801590611f6657506002546001600160a01b03163314155b15611f845760405163089b7a0760e41b815260040160405180910390fd5b6001821015611fa65760405163162908e360e11b815260040160405180910390fd5b6001600160a01b0381165f9081526009602052604090205460ff166001811015611fe35760405163014cc88960e21b815260040160405180910390fd5b601b545f906001600160a01b03868116911614612009576120048585614317565b61200b565b835b90508060145f82825461201e9190615a9a565b90915550505f1960ff8316016120a65761203985848661462f565b6040516311f9fbc960e21b81526001600160a01b038681166004830152602482018690528416906347e7ef24906044015f604051808303815f87803b158015612080575f80fd5b505af1158015612092573d5f803e3d5ffd5b505050506120a185845f61462f565b6113e1565b6113e18584866145fa565b6002600154036120d457604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166121035760405163d311bc3960e01b815260040160405180910390fd5b6002546001600160a01b0316331461212e57604051630b2db9b760e31b815260040160405180910390fd5b6001600160a01b038116158061214c57506001600160a01b03811630145b1561216a57604051631e4ec46b60e01b815260040160405180910390fd5b6006805461ffff60a01b191661010160a01b1790556040516001600160a01b03821681527fc513d827bb73b448f995555eff37d93f4d71b6ef96bc6557e2ec370ba22782ac9060200160405180910390a1601d546040805163a22484d960e01b815290515f926001600160a01b03169163a22484d991600480830192869291908290030181865afa158015612201573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526122289190810190615c86565b8051601b546040516370a0823160e01b815230600482015292935090915f916001600160a01b0316906370a0823190602401602060405180830381865afa158015612275573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122999190615b63565b905080156122b857601b546122b8906001600160a01b031685836145fa565b5f805b83811015610ade578481815181106122d5576122d5615aad565b60209081029190910101516040516370a0823160e01b81523060048201529092506001600160a01b038316906370a0823190602401602060405180830381865afa158015612325573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123499190615b63565b9250821561235c5761235c8287856145fa565b6001016122bb565b60026001540361238757604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166123b65760405163d311bc3960e01b815260040160405180910390fd5b6002546001600160a01b031633146123e157604051630b2db9b760e31b815260040160405180910390fd5b5f816040516024016123f591815260200190565b60408051601f19818403018152918152602080830180516001600160e01b0316633c839cd160e11b179052905161242d929101615a59565b60408051601f19818403018152908290528051602091820120601685905584835292507f30d8cff2601d989fea083347b4501d5e97976f0ce3cfef9d4bd76bef1b7f0e8a9101610a80565b600354600160a01b900460ff166124a25760405163d311bc3960e01b815260040160405180910390fd5b6040513360248201525f9060440160408051601f19818403018152918152602080830180516001600160e01b031663f2fde38b60e01b17905290516124e8929101615a59565b604051602081830303815290604052805190602001209050612508614742565b60075460405163af6f8c1b60e01b8152600481018390526001600160a01b039091169063af6f8c1b906024015f604051808303815f87803b15801561254b575f80fd5b505af115801561255d573d5f803e3d5ffd5b5050505050565b60026001540361258757604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166125b65760405163d311bc3960e01b815260040160405180910390fd5b6002546001600160a01b031633146125e157604051630b2db9b760e31b815260040160405180910390fd5b6006805461ffff60a01b1916600160a01b841515810260ff60a81b191691909117600160a81b841515810291909117928390556040805160ff93850484161515815291909304909116151560208201527f559628b27717ff2f5863f3a218839e17c6bc1b900e9de0dc2b3dc365068841d791015b60405180910390a1505060018055565b60048181548110611e63575f80fd5b5f60026001540361269857604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166126c75760405163d311bc3960e01b815260040160405180910390fd5b600654600160a01b900460ff16156126f25760405163deeb694360e01b815260040160405180910390fd5b6002546001600160a01b0316331480159061271857506006546001600160a01b03163314155b801561272e57506008546001600160a01b031615155b80156127a15750600854604051633af32abf60e01b81523360048201526001600160a01b0390911690633af32abf90602401602060405180830381865afa15801561277b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061279f9190615a6b565b155b156127bf57604051637ed449a960e01b815260040160405180910390fd5b601b5488906001600160a01b038083169116148015906128485750601d54604051633af32abf60e01b81526001600160a01b03838116600483015290911690633af32abf90602401602060405180830381865afa158015612822573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128469190615a6b565b155b1561286657604051632188be3960e21b815260040160405180910390fd5b6128718989896147cd565b60405163d505accf60e01b8152336004820152306024820152604481018a90526064810188905260ff8516608482015260a4810187905260c481018690529092506001600160a01b038a169063d505accf9060e4015f604051808303815f87803b1580156128dd575f80fd5b505af11580156128ef573d5f803e3d5ffd5b505050506128ff898989856148c4565b5060018055979650505050505050565b60026001540361293257604051633ee5aeb560e01b815260040160405180910390fd5b60026001819055546001600160a01b0316331461296257604051630b2db9b760e31b815260040160405180910390fd5b6029919091556031805460ff191691151591909117905560018055565b5f806002600154036129a457604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166129d35760405163d311bc3960e01b815260040160405180910390fd5b600654600160a81b900460ff16156129fe57604051636022a9e760e01b815260040160405180910390fd5b6002546001600160a01b03163314801590612a2457506006546001600160a01b03163314155b8015612a3a57506008546001600160a01b031615155b8015612aad5750600854604051633af32abf60e01b81523360048201526001600160a01b0390911690633af32abf90602401602060405180830381865afa158015612a87573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612aab9190615a6b565b155b15612acb57604051637ed449a960e01b815260040160405180910390fd5b6040805160208101889052908101869052606081018590525f9060800160408051601f1981840301815291815281516020928301205f818152602e84528281206001600160a01b03891682529093529120549091506001811015612b42576040516339c556cd60e11b815260040160405180910390fd5b5f602a54118015612b5e57506002546001600160a01b03163314155b8015612b7557506006546001600160a01b03163314155b8015612b985750612b8a8888885f808061424b565b612b9661012c42615a9a565b105b15612bb65760405163085de62560e01b815260040160405180910390fd5b5f80612bc483602b546141e0565b90925090505f612bd48284615af7565b5f868152602e602090815260408083206001600160a01b038d1684528252808320839055888352602d909152812080549293508692909190612c17908490615af7565b9250508190555083602c5f828254612c2f9190615af7565b925050819055508060155f828254612c479190615a9a565b90915550612c5790508589614988565b876001600160a01b03167f2e06b2c9d4ccae2592eda2017cb2fb604b8d7418e85f023375514ab25ff2cc4c83604051612c9291815260200190565b60405180910390a2601c54604051632770a7eb60e21b8152306004820152602481018690526001600160a01b0390911690639dc29fac906044015f604051808303815f87803b158015612ce3575f80fd5b505af1158015612cf5573d5f803e3d5ffd5b5050601b54612d1192506001600160a01b0316905089846145fa565b50600180559199919850909650505050505050565b5f805f83612d3657602b54612d3a565b6029545b9050612d4685826141e0565b92509250509250929050565b601d54601c54601454604051632b78daa360e11b81526001600160a01b03928316600482015285831660248201523060448201526064810185905260848101919091525f92839216906356f1b5469060a4016040805180830381865afa158015612dbe573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612de29190615d2f565b915091509250929050565b604080516020808201879052818301869052606080830186905283518084039091018152608090920183528151918101919091205f908152602e82528281206001600160a01b038516825290915220545b949350505050565b600260015403612e6957604051633ee5aeb560e01b815260040160405180910390fd5b60026001819055546001600160a01b03163314612e9957604051630b2db9b760e31b815260040160405180910390fd5b6001600160a01b0381165f81815260096020908152604091829020805460ff1916905590519182527f2f520fb256d37bacc8a5e0fb9e69362d4bb462500c7e54f56ea54416e92d47d691015b60405180910390a15060018055565b5f54610100900460ff1615808015612f1257505f54600160ff909116105b80612f2b5750303b158015612f2b57505f5460ff166001145b612f8e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401611d6a565b5f805460ff191660011790558015612faf575f805461ff0019166101001790555b6006805461ffff60a01b191661010160a01b179055600280546001600160a01b0319166001600160a01b0384161790558015613024575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b60026001540361304b57604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff1661307a5760405163d311bc3960e01b815260040160405180910390fd5b600454600181101561309f576040516333f52ff560e01b815260040160405180910390fd5b601554801561320a575f8267ffffffffffffffff8111156130c2576130c2615865565b6040519080825280602002602001820160405280156130eb578160200160208202803683370190505b5090505f5b838110156131a6575f620f4240846004848154811061311157613111615aad565b905f5260205f2090600202016001015461312b9190615b0a565b6131359190615b35565b905060155481111561316857601554604051630abb811560e21b8152611d6a918391600401918252602082015260400190565b8083838151811061317b5761317b615aad565b6020026020010181815250508060155f8282546131989190615af7565b9091555050506001016130f0565b506040517f3f33b5ed245dfaf97e122dfc86e9d14ff254c4878a7c9ba8dab46d9c71cc3015905f90a15f5b8381101561320757601b54600480546131ff926001600160a01b0316919084908110611df657611df6615aad565b6001016131d1565b50505b505060018055565b60026001540361323557604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166132645760405163d311bc3960e01b815260040160405180910390fd5b6002546001600160a01b0316331461328f57604051630b2db9b760e31b815260040160405180910390fd5b600880546001600160a01b0319166001600160a01b0383169081179091556040519081527f7e7afb649fef7779605afaad37b91d9f5044726c260bb394570089d052d5dbb790602001612ee5565b5f805f806132f5602a5461012c42610d979190615a9a565b9195509350915061330a8484845f808061424b565b905090919293565b60026001540361333557604051633ee5aeb560e01b815260040160405180910390fd5b60026001819055546001600160a01b0316331461336557604051630b2db9b760e31b815260040160405180910390fd5b600354600160a01b900460ff1615613390576040516308db0db560e11b815260040160405180910390fd5b62015180816060015110156133b857604051630320a41d60e51b815260040160405180910390fd5b60a0810151603d558051601a8190556020820151602855601e556040808201516029556060820151602a556080820151602b5560c082015160165560e0820151601955610100820151603e5561014082015160068054610160850151600780546001600160a01b03199081166001600160a01b0393841617909155610180870151601c805483169184169190911790556101a0870151601b8054831691841691909117905542601781905560188190556101e0880151601d805484169185169190911790556101208801516008805484169185169190911790559482166001600160b01b031990931692909217909255603c929092556101c084015160028054909316911617905560038054600160a01b60ff60a01b19909116179055517f1eb56c868d62c38b9f2e3bd3d0556bed1dc7df623758318faaaaa05ffff993c7905f90a1601d5f9054906101000a90046001600160a01b03166001600160a01b031663ded4a6fe6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561354b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061356f9190615b48565b601b546001600160a01b0390811691161461359d57604051630ecd66ab60e41b815260040160405180910390fd5b601c5f9054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156135ed573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136119190615b7a565b60ff16601b5f9054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613664573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136889190615b7a565b60ff16146136a95760405163697e864b60e01b815260040160405180910390fd5b601c546040805163313ce56760e01b815290515f926001600160a01b03169163313ce5679160048083019260209291908290030181865afa1580156136f0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906137149190615b7a565b61371f90600a615c78565b61372a906001615b0a565b90505f613737825f614b6d565b603b5550506001805550565b60026001540361376657604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166137955760405163d311bc3960e01b815260040160405180910390fd5b5f61379e61458b565b90505f6127106301e13380601854426137b79190615af7565b6019546137c49086615b0a565b6137ce9190615b0a565b6137d89190615b35565b6137e29190615b35565b9050426018819055508060155f8282546137fc9190615a9a565b90915550506040518181527f2d46e156a9ac545bd5f27832a0e6293d21c92faf9237534c6b18c51e9cca59df90602001612655565b60606004805480602002602001604051908101604052809291908181526020015f9082821015610b54575f848152602090819020604080518082019091526002850290910180546001600160a01b03168252600190810154828401529083529092019101610b0d565b6002600154036138bd57604051633ee5aeb560e01b815260040160405180910390fd5b60026001819055546001600160a01b031633146138ed57604051630b2db9b760e31b815260040160405180910390fd5b603e5560018055565b60026001540361391957604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166139485760405163d311bc3960e01b815260040160405180910390fd5b6002546001600160a01b0316331461397357604051630b2db9b760e31b815260040160405180910390fd5b611a8681614c0e565b60026001540361399f57604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166139ce5760405163d311bc3960e01b815260040160405180910390fd5b600654600160a81b900460ff16156139f957604051636022a9e760e01b815260040160405180910390fd5b6001811015613a1b576040516334e33ddb60e01b815260040160405180910390fd5b6040805160208101869052908101849052606081018390525f906080016040516020818303038152906040528051906020012090506001602d5f8381526020019081526020015f20541015613a8357604051630683f18b60e41b815260040160405180910390fd5b5f602a54118015613a9f57506002546001600160a01b03163314155b8015613ab657506006546001600160a01b03163314155b8015613ad95750613acb8585855f808061424b565b613ad761012c42615a9a565b105b15613af75760405163085de62560e01b815260040160405180910390fd5b5f818152602f60205260408120548310613b1e575f828152602f6020526040902054613b20565b825b5f838152602f60205260408120549192508267ffffffffffffffff811115613b4a57613b4a615865565b604051908082528060200260200182016040528015613b73578160200160208202803683370190505b5090505f8367ffffffffffffffff811115613b9057613b90615865565b604051908082528060200260200182016040528015613bb9578160200160208202803683370190505b5090505f80808087875b613bcd8a8a615af7565b811115613db0575f8b8152602f60205260409020613bec600183615af7565b81548110613bfc57613bfc615aad565b5f918252602090912001546001600160a01b0316945081613c1c81615d51565b92505084888381518110613c3257613c32615aad565b6001600160a01b039283166020918202929092018101919091525f8d8152602e825260408082209389168252929091522054613c6e9087615a9a565b5f8c8152602e602090815260408083206001600160a01b038a168452909152902054602b54919750613c9f916141e0565b60405181815291955093506001600160a01b038616907f2e06b2c9d4ccae2592eda2017cb2fb604b8d7418e85f023375514ab25ff2cc4c9060200160405180910390a282878381518110613cf557613cf5615aad565b6020908102919091010152613d0a8385615af7565b60155f828254613d1a9190615a9a565b90915550505f8b8152602e602090815260408083206001600160a01b038916845282528083208390558d8352602f9091529020805480613d5c57613d5c615d66565b5f828152602080822083015f1990810180546001600160a01b03191690559092019092558c82526030815260408083206001600160a01b038916845290915281205580613da881615d51565b915050613bc3565b5084602c5f828254613dc29190615af7565b90915550505f8a8152602d602052604081208054879290613de4908490615af7565b9091555050601c54604051632770a7eb60e21b8152306004820152602481018790526001600160a01b0390911690639dc29fac906044015f604051808303815f87803b158015613e32575f80fd5b505af1158015613e44573d5f803e3d5ffd5b505050505f5b8751811015613e9a57601b548851613e92916001600160a01b0316908a9084908110613e7857613e78615aad565b6020026020010151898481518110611e2657611e26615aad565b600101613e4a565b50506001805550505050505050505050505050565b5f600260015403613ed357604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff16613f025760405163d311bc3960e01b815260040160405180910390fd5b600654600160a01b900460ff1615613f2d5760405163deeb694360e01b815260040160405180910390fd5b6002546001600160a01b03163314801590613f5357506006546001600160a01b03163314155b8015613f6957506008546001600160a01b031615155b8015613fdc5750600854604051633af32abf60e01b81523360048201526001600160a01b0390911690633af32abf90602401602060405180830381865afa158015613fb6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613fda9190615a6b565b155b15613ffa57604051637ed449a960e01b815260040160405180910390fd5b601b5484906001600160a01b038083169116148015906140835750601d54604051633af32abf60e01b81526001600160a01b03838116600483015290911690633af32abf90602401602060405180830381865afa15801561405d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906140819190615a6b565b155b156140a157604051632188be3960e21b815260040160405180910390fd5b6140ac8585856147cd565b91506140ba858585856148c4565b50600180559392505050565b6002600154036140e957604051633ee5aeb560e01b815260040160405180910390fd5b60026001819055546001600160a01b0316331461411957604051630b2db9b760e31b815260040160405180910390fd5b6001600160a01b038216158061413757506001600160a01b03821630145b156141555760405163e6c4247b60e01b815260040160405180910390fd5b60ff811660011480159061416d575060ff8116600214155b1561418b5760405163e01b409760e01b815260040160405180910390fd5b6001600160a01b0382165f81815260096020908152604091829020805460ff191660ff861617905590519182527f324201c119d7f14ed24d964257aa0c870524bde20d9ecb31d4b37eadc20336ff9101612655565b5f806141ec845f614b6d565b91508190505f831561421e576127106142058486615b0a565b61420f9190615b35565b905061421b8184615af7565b91505b509250929050565b5f808061423e6142396201518086615b35565b614dc0565b9196909550909350915050565b5f81614258603c85615b0a565b614264610e1087615b0a565b620151806142738b8b8b614f2f565b61427d9190615b0a565b6142879190615a9a565b6142919190615a9a565b61429b9190615a9a565b979650505050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526143119085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152615095565b50505050565b601d546040516364696fab60e11b81526001600160a01b038481166004830152602482018490525f92169063c8d2df5690604401602060405180830381865afa158015614366573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061438a9190615b63565b9392505050565b5f805f836143a157602b546143a5565b6029545b90506143b186826141e0565b60285491945092508311156143d957604051631b6132ab60e31b815260040160405180910390fd5b60018210156143fb57604051631fbaba3560e01b815260040160405180910390fd5b60315460ff166144255761440f8284615af7565b60155f82825461441f9190615a9a565b90915550505b604080518381526020810188905233916001600160a01b0388169183917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4601c54604051632770a7eb60e21b8152336004820152602481018890526001600160a01b0390911690639dc29fac906044015f604051808303815f87803b1580156144b6575f80fd5b505af11580156144c8573d5f803e3d5ffd5b5050601b546144e492506001600160a01b0316905086846145fa565b50935093915050565b5f80601c5f9054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561453f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906145639190615b7a565b61456e90600a615c78565b614579906001615b0a565b9050614585815f614b6d565b91505090565b601d5460145460405163ad07802160e01b815260048101919091525f916001600160a01b03169063ad07802190602401602060405180830381865afa1580156145d6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ae69190615b63565b6040516001600160a01b03831660248201526044810182905261462a90849063a9059cbb60e01b906064016142da565b505050565b8015806146a75750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015614681573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906146a59190615b63565b155b6147125760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401611d6a565b6040516001600160a01b03831660248201526044810182905261462a90849063095ea7b360e01b906064016142da565b60026001540361476557604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166147945760405163d311bc3960e01b815260040160405180910390fd5b6003546001600160a01b031633146147be576040516282b42960e81b815260040160405180910390fd5b6147c733615168565b60018055565b5f60018310156147f05760405163162908e360e11b815260040160405180910390fd5b6001600160a01b038216158061480e57506001600160a01b03821630145b1561482c57604051631e4ec46b60e01b815260040160405180910390fd5b5f806148388686612d52565b91509150600182101561485e57604051633999656760e01b815260040160405180910390fd5b601a5481111561488157604051639ade546d60e01b815260040160405180910390fd5b5f61488a61458b565b6148949083615a9a565b9050601e548111156148b9576040516312e7cad560e21b815260040160405180910390fd5b509095945050505050565b604080516001600160a01b038681168252602082018690529181018390529083169033907fc436f473cd90c9b4dd731856a14b80f713d384a1688a506d4230140c5b36d5cd9060600160405180910390a3614921843330866142a6565b601c546040516340c10f1960e01b81526001600160a01b03848116600483015260248201849052909116906340c10f19906044015f604051808303815f87803b15801561496c575f80fd5b505af115801561497e573d5f803e3d5ffd5b5050505050505050565b5f8281526030602090815260408083206001600160a01b03851684529091528120546149b690600190615af7565b5f848152602f6020526040812080549293506149d3600184615af7565b815481106149e3576149e3615aad565b5f918252602090912001546001600160a01b03908116915084168114614b07575f858152602f60205260409020805484908110614a2257614a22615aad565b5f918252602080832090910154878352602f90915260409091206001600160a01b0390911690614a53600185615af7565b81548110614a6357614a63615aad565b905f5260205f20015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555080602f5f8781526020019081526020015f208481548110614ab157614ab1615aad565b5f91825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055614ae4836001615a9a565b5f8681526030602090815260408083206001600160a01b03861684529091529020555b5f858152602f60205260409020805480614b2357614b23615d66565b5f828152602080822083015f1990810180546001600160a01b03191690559092019092559581526030865260408082206001600160a01b0396909616825294909552505050812055565b5f80601c5f9054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015614bbf573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190614be39190615b63565b905060018110614c0657614c01614bf861458b565b85908386615184565b612e3e565b509192915050565b6003545f906001600160a01b031615614c8d576003546040516001600160a01b03909116602482015260440160408051601f19818403018152918152602080830180516001600160e01b031663f2fde38b60e01b1790529051614c72929101615a59565b60405160208183030381529060405280519060200120614c8f565b5f5b6040516001600160a01b03841660248201529091505f9060440160408051601f19818403018152918152602080830180516001600160e01b031663f2fde38b60e01b1790529051614ce1929101615a59565b604051602081830303815290604052805190602001209050614d02836151df565b8115614d625760075460405163c4d252f560e01b8152600481018490526001600160a01b039091169063c4d252f5906024015f604051808303815f87803b158015614d4b575f80fd5b505af1158015614d5d573d5f803e3d5ffd5b505050505b600754604051631523ab0160e21b8152600481018390526001600160a01b039091169063548eac04906024015f604051808303815f87803b158015614da5575f80fd5b505af1158015614db7573d5f803e3d5ffd5b50505050505050565b5f8080838162253d8c614dd68362010bd9615d7a565b614de09190615d7a565b90505f62023ab1614df2836004615da1565b614dfc9190615dd0565b90506004614e0d8262023ab1615da1565b614e18906003615d7a565b614e229190615dd0565b614e2c9083615dfc565b91505f62164b09614e3e846001615d7a565b614e4a90610fa0615da1565b614e549190615dd0565b90506004614e64826105b5615da1565b614e6e9190615dd0565b614e789084615dfc565b614e8390601f615d7a565b92505f61098f614e94856050615da1565b614e9e9190615dd0565b90505f6050614eaf8361098f615da1565b614eb99190615dd0565b614ec39086615dfc565b9050614ed0600b83615dd0565b9450614edd85600c615da1565b614ee8836002615d7a565b614ef29190615dfc565b91508483614f01603187615dfc565b614f0c906064615da1565b614f169190615d7a565b614f209190615d7a565b9a919950975095505050505050565b5f6107b2841015614f6a5760405162461bcd60e51b815260206004820152600560248201526422b93937b960d91b6044820152606401611d6a565b8383835f62253d8c60046064600c614f83600e88615dfc565b614f8d9190615dd0565b614f9988611324615d7a565b614fa39190615d7a565b614fad9190615dd0565b614fb8906003615da1565b614fc29190615dd0565b600c80614fd0600e88615dfc565b614fda9190615dd0565b614fe590600c615da1565b614ff0600288615dfc565b614ffa9190615dfc565b6150069061016f615da1565b6150109190615dd0565b6004600c61501f600e89615dfc565b6150299190615dd0565b615035896112c0615d7a565b61503f9190615d7a565b61504b906105b5615da1565b6150559190615dd0565b615061617d4b87615dfc565b61506b9190615d7a565b6150759190615d7a565b61507f9190615dfc565b6150899190615dfc565b98975050505050505050565b5f6150e9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661526c9092919063ffffffff16565b905080515f14806151095750808060200190518101906151099190615a6b565b61462a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611d6a565b600380546001600160a01b03191690556151818161527a565b50565b5f806151918686866152f2565b905060018360028111156151a7576151a7615e22565b1480156151c357505f84806151be576151be615b21565b868809115b156151d6576151d3600182615a9a565b90505b95945050505050565b6001600160a01b03811615806151fd57506001600160a01b03811630145b1561521b5760405163e6c4247b60e01b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b03838116918217909255600254604051919216907f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700905f90a350565b6060612e3e84845f856153d7565b6001600160a01b0381166152a15760405163156fee5160e31b815260040160405180910390fd5b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f80805f19858709858702925082811083820303915050805f036153295783828161531f5761531f615b21565b049250505061438a565b8084116153705760405162461bcd60e51b81526020600482015260156024820152744d6174683a206d756c446976206f766572666c6f7760581b6044820152606401611d6a565b5f8486880960026001871981018816978890046003810283188082028403028082028403028082028403028082028403028082028403029081029092039091025f889003889004909101858311909403939093029303949094049190911702949350505050565b6060824710156154385760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401611d6a565b5f80866001600160a01b031685876040516154539190615e36565b5f6040518083038185875af1925050503d805f811461548d576040519150601f19603f3d011682016040523d82523d5f602084013e615492565b606091505b509150915061429b878383876060831561550c5782515f03615505576001600160a01b0385163b6155055760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611d6a565b5081612e3e565b612e3e83838151156155215781518083602001fd5b8060405162461bcd60e51b8152600401611d6a9190615a59565b5080545f8255600202905f5260205f209081019061518191905b808211156155795780546001600160a01b03191681555f6001820155600201615555565b5090565b5f6020828403121561558d575f80fd5b5035919050565b602080825282518282018190525f918401906040840190835b818110156148b957835180516001600160a01b0316845260209081015181850152909301926040909201916001016155ad565b6001600160a01b0381168114615181575f80fd5b80356155ff816155e0565b919050565b5f8060408385031215615615575f80fd5b823591506020830135615627816155e0565b809150509250929050565b5f8060208385031215615643575f80fd5b823567ffffffffffffffff811115615659575f80fd5b8301601f81018513615669575f80fd5b803567ffffffffffffffff81111561567f575f80fd5b8560208260061b8401011115615693575f80fd5b6020919091019590945092505050565b5f805f606084860312156156b5575f80fd5b83356156c0816155e0565b92506020840135915060408401356156d7816155e0565b809150509250925092565b5f805f606084860312156156f4575f80fd5b505081359360208301359350604090920135919050565b5f6020828403121561571b575f80fd5b813561438a816155e0565b8015158114615181575f80fd5b5f8060408385031215615744575f80fd5b823561574f81615726565b9150602083013561562781615726565b60ff81168114615181575f80fd5b5f805f805f805f60e0888a031215615783575f80fd5b873561578e816155e0565b96506020880135955060408801356157a5816155e0565b9450606088013593506080880135925060a0880135915060c08801356157ca8161575f565b8091505092959891949750929550565b5f80604083850312156157eb575f80fd5b82359150602083013561562781615726565b5f805f8060808587031215615810575f80fd5b8435935060208501359250604085013591506060850135615830816155e0565b939692955090935050565b5f806040838503121561584c575f80fd5b8235615857816155e0565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b604051610200810167ffffffffffffffff8111828210171561589d5761589d615865565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156158cc576158cc615865565b604052919050565b5f6102008284031280156158e6575f80fd5b506158ef615879565b823581526020808401359082015260408084013590820152606080840135908201526080808401359082015260a0808401359082015260c0808401359082015260e08084013590820152610100808401359082015261595161012084016155f4565b61012082015261596461014084016155f4565b61014082015261597761016084016155f4565b61016082015261598a61018084016155f4565b61018082015261599d6101a084016155f4565b6101a08201526159b06101c084016155f4565b6101c08201526159c36101e084016155f4565b6101e08201529392505050565b5f805f80608085870312156159e3575f80fd5b5050823594602084013594506040840135936060013592509050565b5f8060408385031215615a10575f80fd5b8235615a1b816155e0565b915060208301356156278161575f565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f61438a6020830184615a2b565b5f60208284031215615a7b575f80fd5b815161438a81615726565b634e487b7160e01b5f52601160045260245ffd5b808201808211156116fd576116fd615a86565b634e487b7160e01b5f52603260045260245ffd5b8135615acc816155e0565b81546001600160a01b0319166001600160a01b03919091161781556020919091013560019190910155565b818103818111156116fd576116fd615a86565b80820281158282048414176116fd576116fd615a86565b634e487b7160e01b5f52601260045260245ffd5b5f82615b4357615b43615b21565b500490565b5f60208284031215615b58575f80fd5b815161438a816155e0565b5f60208284031215615b73575f80fd5b5051919050565b5f60208284031215615b8a575f80fd5b815161438a8161575f565b6001815b6001841115615bd057808504811115615bb457615bb4615a86565b6001841615615bc257908102905b60019390931c928002615b99565b935093915050565b5f82615be6575060016116fd565b81615bf257505f6116fd565b8160018114615c085760028114615c1257615c2e565b60019150506116fd565b60ff841115615c2357615c23615a86565b50506001821b6116fd565b5060208310610133831016604e8410600b8410161715615c51575081810a6116fd565b615c5d5f198484615b95565b805f1904821115615c7057615c70615a86565b029392505050565b5f61438a60ff841683615bd8565b5f60208284031215615c96575f80fd5b815167ffffffffffffffff811115615cac575f80fd5b8201601f81018413615cbc575f80fd5b805167ffffffffffffffff811115615cd657615cd6615865565b8060051b615ce6602082016158a3565b91825260208184018101929081019087841115615d01575f80fd5b6020850194505b8385101561429b5784519250615d1d836155e0565b82825260209485019490910190615d08565b5f8060408385031215615d40575f80fd5b505080516020909101519092909150565b5f81615d5f57615d5f615a86565b505f190190565b634e487b7160e01b5f52603160045260245ffd5b8082018281125f831280158216821582161715615d9957615d99615a86565b505092915050565b8082025f8212600160ff1b84141615615dbc57615dbc615a86565b81810583148215176116fd576116fd615a86565b5f82615dde57615dde615b21565b600160ff1b82145f1984141615615df757615df7615a86565b500590565b8181035f831280158383131683831282161715615e1b57615e1b615a86565b5092915050565b634e487b7160e01b5f52602160045260245ffd5b5f82518060208501845e5f92019182525091905056fea26469706673582212203cfcf2e0022a02b0895fd09591f4c48f657caaa7f78c4e71c56e624254dc08fb64736f6c634300081a0033
Deployed Bytecode
0x608060405234801561000f575f80fd5b5060043610610422575f3560e01c80638ed832711161022c578063d3a8d71811610135578063e976d431116100bf578063f5ae497a11610084578063f5ae497a146108e7578063fa20e0fe146108fa578063fc6fb83714610903578063ff06002b1461090c578063ff3c63c01461091f575f80fd5b8063e976d43114610891578063e9f2838e1461089a578063f2fde38b146108ae578063f3cbf47c146108c1578063f45346dc146108d4575f80fd5b8063dece010211610105578063dece010214610849578063e2eb36b914610851578063e30c397814610864578063e622868014610875578063e89813301461087e575f80fd5b8063d3a8d71814610826578063d961b58c1461082e578063dad361c514610837578063dbd5edc714610840575f80fd5b8063be1f9214116101b6578063c879657211610186578063c8796572146107dd578063c8e11e8e146107e5578063ca55a557146107f8578063cb3dc35714610800578063cdb1fb2b14610813575f80fd5b8063be1f921414610791578063c25dd81f146107a4578063c3646a0f146107b7578063c4d66de8146107ca575f80fd5b80639efee6be116101fc5780639efee6be14610711578063b3c9e83d14610724578063b4db4be814610737578063b8f82b261461074a578063bb2707091461075d575f80fd5b80638ed83271146106d957806390f1c5f1146106e257806399aa14d0146106f55780639cb43f8114610708575f80fd5b8063520cd0361161032e57806373f351c8116102b85780638120b579116102885780638120b5791461069a578063820fe4be146106a35780638bc7e8c4146106ac5780638c0190e3146106b55780638da5cb5b146106c8575f80fd5b806373f351c81461066d578063785c312714610676578063790739a21461067f57806379ba509714610692575f80fd5b806360da3e83116102fe57806360da3e83146106035780636c46407b146106175780636e07302b1461063f5780636f4ab3dd146106475780636ff1c9bc1461065a575f80fd5b8063520cd036146105b95780635486679d146105c15780635b1dac60146105c95780635d9e5cab146105d1575f80fd5b806322928208116103af57806336a0f8a51161037f57806336a0f8a51461055c57806336b7ea151461056f57806338d52e0f146105785780633c7ecb4a14610589578063502bee661461059c575f80fd5b8063229282081461051a57806324e86d671461052d57806328f856801461053657806329451a2214610549575f80fd5b8063127effb2116103f5578063127effb2146104a3578063184466c9146104ce5780631bca5113146104e15780631dddfbe1146104f45780631f4f519c14610507575f80fd5b8063030d624a1461042657806309f25fc01461043b5780630ffbfda414610459578063107703ab14610470575b5f80fd5b61043961043436600461557d565b610970565b005b610443610aea565b6040516104509190615594565b60405180910390f35b610462603e5481565b604051908152602001610450565b61048361047e366004615604565b610b5d565b604080519485526020850193909352918301526060820152608001610450565b6006546104b6906001600160a01b031681565b6040516001600160a01b039091168152602001610450565b6104396104dc36600461557d565b610f3e565b6104396104ef366004615632565b61104f565b6104396105023660046156a3565b61120a565b61043961051536600461557d565b6113ec565b610439610528366004615604565b6114c9565b610462602a5481565b61046261054436600461557d565b61167d565b610439610557366004615632565b611703565b61043961056a3660046156e2565b611890565b61046260185481565b601b546001600160a01b03166104b6565b61043961059736600461570b565b611939565b6031546105a99060ff1681565b6040519015158152602001610450565b610462611a8d565b610439611aeb565b610462611e4b565b6105e46105df36600461557d565b611e54565b604080516001600160a01b039093168352602083019190915201610450565b6006546105a990600160a01b900460ff1681565b61062a6106253660046156e2565b611e8a565b60408051928352602083019190915201610450565b610462611ee5565b6104396106553660046156a3565b611eee565b61043961066836600461570b565b6120b1565b61046260195481565b61046260145481565b61043961068d36600461557d565b612364565b610439612478565b610462603b5481565b61046260295481565b610462602b5481565b6104396106c3366004615733565b612564565b6002546001600160a01b03166104b6565b610462601a5481565b6105e46106f036600461557d565b612665565b61046261070336600461576d565b612674565b610462602c5481565b61043961071f3660046157da565b61290f565b61062a6107323660046157fd565b61297f565b61062a6107453660046157da565b612d26565b61062a61075836600461583b565b612d52565b61077f61076b36600461570b565b60096020525f908152604090205460ff1681565b60405160ff9091168152602001610450565b61046261079f3660046157fd565b612ded565b6008546104b6906001600160a01b031681565b6104396107c536600461570b565b612e46565b6104396107d836600461570b565b612ef4565b610439613028565b6104396107f336600461570b565b613212565b6104836132dd565b61043961080e3660046158d4565b613312565b601d546104b6906001600160a01b031681565b610439613743565b61046260155481565b610462603d5481565b610462601e5481565b610443613831565b6007546104b6906001600160a01b031681565b6003546001600160a01b03166104b6565b61046260165481565b61043961088c36600461557d565b61389a565b61046260285481565b6006546105a990600160a81b900460ff1681565b6104396108bc36600461570b565b6138f6565b6104396108cf3660046159d0565b61397c565b6104626108e23660046156a3565b613eaf565b601c546104b6906001600160a01b031681565b61046260175481565b610462603c5481565b61043961091a3660046159ff565b6140c6565b61046261092d3660046156e2565b604080516020808201959095528082019390935260608084019290925280518084039092018252608090920182528051908301205f908152602d90925290205490565b60026001540361099357604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166109c25760405163d311bc3960e01b815260040160405180910390fd5b6002546001600160a01b031633146109ed57604051630b2db9b760e31b815260040160405180910390fd5b5f81604051602401610a0191815260200190565b60408051601f19818403018152918152602080830180516001600160e01b0316630186b12560e11b1790529051610a39929101615a59565b60408051601f19818403018152908290528051602091820120601985905584835292507f2147e2bc8c39e67f74b1a9e08896ea1485442096765942206af1f4bc8bcde91791015b60405180910390a160075460405163af6f8c1b60e01b8152600481018390526001600160a01b039091169063af6f8c1b906024015b5f604051808303815f87803b158015610acc575f80fd5b505af1158015610ade573d5f803e3d5ffd5b50506001805550505050565b60606005805480602002602001604051908101604052809291908181526020015f905b82821015610b54575f848152602090819020604080518082019091526002850290910180546001600160a01b03168252600190810154828401529083529092019101610b0d565b50505050905090565b5f805f80600260015403610b8457604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff16610bb35760405163d311bc3960e01b815260040160405180910390fd5b600654600160a81b900460ff1615610bde57604051636022a9e760e01b815260040160405180910390fd5b6002546001600160a01b03163314801590610c0457506006546001600160a01b03163314155b8015610c1a57506008546001600160a01b031615155b8015610c8d5750600854604051633af32abf60e01b81523360048201526001600160a01b0390911690633af32abf90602401602060405180830381865afa158015610c67573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c8b9190615a6b565b155b15610cab57604051637ed449a960e01b815260040160405180910390fd5b6001600160a01b0385161580610cc957506001600160a01b03851630145b15610ce757604051631e4ec46b60e01b815260040160405180910390fd5b6001861015610d095760405163162908e360e11b815260040160405180910390fd5b5f80610d1788602b546141e0565b91509150602854821115610d3e57604051631b6132ab60e31b815260040160405180910390fd5b6001811015610d6057604051631fbaba3560e01b815260040160405180910390fd5b6001602a541015610d84576040516394fa99e760e01b815260040160405180910390fd5b602a54610da690610d9761012c42615a9a565b610da19190615a9a565b614226565b604080516020808201869052818301859052606080830185905283518084039091018152608090920190925280519101209297509095509350610ded8686865f808061424b565b965088602c5f828254610e009190615a9a565b90915550505f818152602d6020526040812080548b9290610e22908490615a9a565b90915550505f818152602e602090815260408083206001600160a01b038c1684529091528120549003610ea0575f818152602f6020908152604080832080546001810182558185528385200180546001600160a01b0319166001600160a01b038e169081179091558585529054603084528285209185529252909120555b5f818152602e602090815260408083206001600160a01b038c168452909152812080548b9290610ed1908490615a9a565b90915550506040518981526001600160a01b0389169033907fcf41fab81bee2456b7007d9d1a9e2261a6627a41eba8c3302b6b07f9a7a463959060200160405180910390a3601c54610f2e906001600160a01b031633308c6142a6565b5050600180555092959194509250565b600260015403610f6157604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff16610f905760405163d311bc3960e01b815260040160405180910390fd5b6002546001600160a01b03163314610fbb57604051630b2db9b760e31b815260040160405180910390fd5b602a819055604051602481018290525f9060440160408051601f19818403018152918152602080830180516001600160e01b031663184466c960e01b1790529051611007929101615a59565b60408051808303601f1901815290829052805160209091012060075463af6f8c1b60e01b8352600483018290529092506001600160a01b03169063af6f8c1b90602401610ab5565b60026001540361107257604051633ee5aeb560e01b815260040160405180910390fd5b60026001819055546001600160a01b031633146110a257604051630b2db9b760e31b815260040160405180910390fd5b5f8160018110156110c6576040516333f52ff560e01b815260040160405180910390fd5b6110d160055f61553b565b5f5b818110156111dc5760018585838181106110ef576110ef615aad565b9050604002016020013510156111185760405163162908e360e11b815260040160405180910390fd5b5f85858381811061112b5761112b615aad565b611141926020604090920201908101915061570b565b6001600160a01b0316036111685760405163e6c4247b60e01b815260040160405180910390fd5b84848281811061117a5761117a615aad565b905060400201602001358361118f9190615a9a565b925060058585838181106111a5576111a5615aad565b83546001810185555f94855260209094206040909102929092019260020290910190506111d28282615ac1565b50506001016110d3565b5081620f4240146112005760405163e31ac1db60e01b815260040160405180910390fd5b5050600180555050565b60026001540361122d57604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff1661125c5760405163d311bc3960e01b815260040160405180910390fd5b6006546001600160a01b0316331480159061128257506002546001600160a01b03163314155b156112a05760405163089b7a0760e41b815260040160405180910390fd5b60018210156112c25760405163162908e360e11b815260040160405180910390fd5b6001600160a01b0381165f9081526009602052604090205460ff1660018110156112ff5760405163014cc88960e21b815260040160405180910390fd5b601b545f906001600160a01b03868116911614611325576113208585614317565b611327565b835b905060145481111561134c5760405163200f4ff760e01b815260040160405180910390fd5b8060145f82825461135d9190615af7565b90915550505f1960ff8316016113d557604051631a4ca37b60e21b81526001600160a01b038681166004830152602482018690523060448301528416906369328dec906064015f604051808303815f87803b1580156113ba575f80fd5b505af11580156113cc573d5f803e3d5ffd5b505050506113e1565b6113e1858430876142a6565b505060018055505050565b60026001540361140f57604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff1661143e5760405163d311bc3960e01b815260040160405180910390fd5b6006546001600160a01b0316331480159061146457506002546001600160a01b03163314155b156114825760405163089b7a0760e41b815260040160405180910390fd5b5f61148c8261167d565b90505f611497611a8d565b9050808211156114ba57604051631373d6db60e01b815260040160405180910390fd5b50506014554260175560018055565b6002600154036114ec57604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff1661151b5760405163d311bc3960e01b815260040160405180910390fd5b600654600160a81b900460ff161561154657604051636022a9e760e01b815260040160405180910390fd5b6002546001600160a01b0316331480159061156c57506006546001600160a01b03163314155b801561158257506008546001600160a01b031615155b80156115f55750600854604051633af32abf60e01b81523360048201526001600160a01b0390911690633af32abf90602401602060405180830381865afa1580156115cf573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115f39190615a6b565b155b1561161357604051637ed449a960e01b815260040160405180910390fd5b6001600160a01b038116158061163157506001600160a01b03811630145b1561164f57604051631e4ec46b60e01b815260040160405180910390fd5b60018210156116715760405163162908e360e11b815260040160405180910390fd5b61120082826001614391565b5f6001601454101561169057505f919050565b60018210156116a25750612710919050565b60145482116116d857612710826014546127106116bf9190615b0a565b6116c99190615b35565b6116d39190615af7565b6116fd565b601454612710906116e98483615b0a565b6116f39190615b35565b6116fd9190615af7565b92915050565b60026001540361172657604051633ee5aeb560e01b815260040160405180910390fd5b60026001819055546001600160a01b0316331461175657604051630b2db9b760e31b815260040160405180910390fd5b5f81600181101561177a576040516333f52ff560e01b815260040160405180910390fd5b61178560045f61553b565b5f5b818110156111dc5760018585838181106117a3576117a3615aad565b9050604002016020013510156117cc5760405163162908e360e11b815260040160405180910390fd5b5f8585838181106117df576117df615aad565b6117f5926020604090920201908101915061570b565b6001600160a01b03160361181c5760405163e6c4247b60e01b815260040160405180910390fd5b84848281811061182e5761182e615aad565b90506040020160200135836118439190615a9a565b9250600485858381811061185957611859615aad565b83546001810185555f94855260209094206040909102929092019260020290910190506118868282615ac1565b5050600101611787565b6002600154036118b357604051633ee5aeb560e01b815260040160405180910390fd5b60026001819055546001600160a01b031633146118e357604051630b2db9b760e31b815260040160405180910390fd5b600183101561190557604051637fb1277b60e01b815260040160405180910390fd5b60018210156119275760405163e8498be360e01b815260040160405180910390fd5b601a92909255602855601e5560018055565b60026001540361195c57604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff1661198b5760405163d311bc3960e01b815260040160405180910390fd5b6002546001600160a01b031633146119b657604051630b2db9b760e31b815260040160405180910390fd5b6001600160a01b0381166119dd5760405163e6c4247b60e01b815260040160405180910390fd5b601d80546001600160a01b0319166001600160a01b03831690811790915560408051636f6a537f60e11b8152905163ded4a6fe916004808201926020929091908290030181865afa158015611a34573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a589190615b48565b601b546001600160a01b03908116911614611a8657604051630ecd66ab60e41b815260040160405180910390fd5b5060018055565b6017545f90611a9e61012c42615a9a565b1015611abd5760405163b7d0949760e01b815260040160405180910390fd5b6201518060175442611acf9190615af7565b601654611adc9190615b0a565b611ae69190615b35565b905090565b600260015403611b0e57604051633ee5aeb560e01b815260040160405180910390fd5b6002600155603d54603c54611b239042615af7565b1015611b42576040516311b96bf760e31b815260040160405180910390fd5b5f611b4b6144ed565b9050603b548111611b6f5760405163330c780160e11b815260040160405180910390fd5b601c54604080516318160ddd60e01b815290515f926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa158015611bb6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bda9190615b63565b90505f601c5f9054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c2d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c519190615b7a565b90505f611c5f82600a615c78565b83603b54611c6d9190615b0a565b611c779190615b35565b90505f611c8261458b565b90505f611c8f8383615af7565b90505f620f4240603e5483611ca49190615b0a565b611cae9190615b35565b6005549091505f8167ffffffffffffffff811115611cce57611cce615865565b604051908082528060200260200182016040528015611cf7578160200160208202803683370190505b5090505f5b82811015611dbc575f620f42408560058481548110611d1d57611d1d615aad565b905f5260205f20906002020160010154611d379190615b0a565b611d419190615b35565b905084811115611d7357604051630abb811560e21b815260048101829052602481018690526044015b60405180910390fd5b6001811015611d955760405163debabab560e01b815260040160405180910390fd5b80838381518110611da857611da8615aad565b602090810291909101015250600101611cfc565b5042603c55603b8990555f5b82811015611e3b57601b5460058054611e33926001600160a01b0316919084908110611df657611df6615aad565b5f91825260209091206002909102015484516001600160a01b0390911690859085908110611e2657611e26615aad565b60200260200101516145fa565b600101611dc8565b5050600180555050505050505050565b5f611ae66144ed565b60058181548110611e63575f80fd5b5f918252602090912060029091020180546001909101546001600160a01b03909116915082565b604080516020808201869052818301859052606080830185905283518084039091018152608090920183528151918101919091205f818152602f9092529181205491611eda86868685808061424b565b915050935093915050565b5f611ae661458b565b600260015403611f1157604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff16611f405760405163d311bc3960e01b815260040160405180910390fd5b6006546001600160a01b03163314801590611f6657506002546001600160a01b03163314155b15611f845760405163089b7a0760e41b815260040160405180910390fd5b6001821015611fa65760405163162908e360e11b815260040160405180910390fd5b6001600160a01b0381165f9081526009602052604090205460ff166001811015611fe35760405163014cc88960e21b815260040160405180910390fd5b601b545f906001600160a01b03868116911614612009576120048585614317565b61200b565b835b90508060145f82825461201e9190615a9a565b90915550505f1960ff8316016120a65761203985848661462f565b6040516311f9fbc960e21b81526001600160a01b038681166004830152602482018690528416906347e7ef24906044015f604051808303815f87803b158015612080575f80fd5b505af1158015612092573d5f803e3d5ffd5b505050506120a185845f61462f565b6113e1565b6113e18584866145fa565b6002600154036120d457604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166121035760405163d311bc3960e01b815260040160405180910390fd5b6002546001600160a01b0316331461212e57604051630b2db9b760e31b815260040160405180910390fd5b6001600160a01b038116158061214c57506001600160a01b03811630145b1561216a57604051631e4ec46b60e01b815260040160405180910390fd5b6006805461ffff60a01b191661010160a01b1790556040516001600160a01b03821681527fc513d827bb73b448f995555eff37d93f4d71b6ef96bc6557e2ec370ba22782ac9060200160405180910390a1601d546040805163a22484d960e01b815290515f926001600160a01b03169163a22484d991600480830192869291908290030181865afa158015612201573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526122289190810190615c86565b8051601b546040516370a0823160e01b815230600482015292935090915f916001600160a01b0316906370a0823190602401602060405180830381865afa158015612275573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122999190615b63565b905080156122b857601b546122b8906001600160a01b031685836145fa565b5f805b83811015610ade578481815181106122d5576122d5615aad565b60209081029190910101516040516370a0823160e01b81523060048201529092506001600160a01b038316906370a0823190602401602060405180830381865afa158015612325573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123499190615b63565b9250821561235c5761235c8287856145fa565b6001016122bb565b60026001540361238757604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166123b65760405163d311bc3960e01b815260040160405180910390fd5b6002546001600160a01b031633146123e157604051630b2db9b760e31b815260040160405180910390fd5b5f816040516024016123f591815260200190565b60408051601f19818403018152918152602080830180516001600160e01b0316633c839cd160e11b179052905161242d929101615a59565b60408051601f19818403018152908290528051602091820120601685905584835292507f30d8cff2601d989fea083347b4501d5e97976f0ce3cfef9d4bd76bef1b7f0e8a9101610a80565b600354600160a01b900460ff166124a25760405163d311bc3960e01b815260040160405180910390fd5b6040513360248201525f9060440160408051601f19818403018152918152602080830180516001600160e01b031663f2fde38b60e01b17905290516124e8929101615a59565b604051602081830303815290604052805190602001209050612508614742565b60075460405163af6f8c1b60e01b8152600481018390526001600160a01b039091169063af6f8c1b906024015f604051808303815f87803b15801561254b575f80fd5b505af115801561255d573d5f803e3d5ffd5b5050505050565b60026001540361258757604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166125b65760405163d311bc3960e01b815260040160405180910390fd5b6002546001600160a01b031633146125e157604051630b2db9b760e31b815260040160405180910390fd5b6006805461ffff60a01b1916600160a01b841515810260ff60a81b191691909117600160a81b841515810291909117928390556040805160ff93850484161515815291909304909116151560208201527f559628b27717ff2f5863f3a218839e17c6bc1b900e9de0dc2b3dc365068841d791015b60405180910390a1505060018055565b60048181548110611e63575f80fd5b5f60026001540361269857604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166126c75760405163d311bc3960e01b815260040160405180910390fd5b600654600160a01b900460ff16156126f25760405163deeb694360e01b815260040160405180910390fd5b6002546001600160a01b0316331480159061271857506006546001600160a01b03163314155b801561272e57506008546001600160a01b031615155b80156127a15750600854604051633af32abf60e01b81523360048201526001600160a01b0390911690633af32abf90602401602060405180830381865afa15801561277b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061279f9190615a6b565b155b156127bf57604051637ed449a960e01b815260040160405180910390fd5b601b5488906001600160a01b038083169116148015906128485750601d54604051633af32abf60e01b81526001600160a01b03838116600483015290911690633af32abf90602401602060405180830381865afa158015612822573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128469190615a6b565b155b1561286657604051632188be3960e21b815260040160405180910390fd5b6128718989896147cd565b60405163d505accf60e01b8152336004820152306024820152604481018a90526064810188905260ff8516608482015260a4810187905260c481018690529092506001600160a01b038a169063d505accf9060e4015f604051808303815f87803b1580156128dd575f80fd5b505af11580156128ef573d5f803e3d5ffd5b505050506128ff898989856148c4565b5060018055979650505050505050565b60026001540361293257604051633ee5aeb560e01b815260040160405180910390fd5b60026001819055546001600160a01b0316331461296257604051630b2db9b760e31b815260040160405180910390fd5b6029919091556031805460ff191691151591909117905560018055565b5f806002600154036129a457604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166129d35760405163d311bc3960e01b815260040160405180910390fd5b600654600160a81b900460ff16156129fe57604051636022a9e760e01b815260040160405180910390fd5b6002546001600160a01b03163314801590612a2457506006546001600160a01b03163314155b8015612a3a57506008546001600160a01b031615155b8015612aad5750600854604051633af32abf60e01b81523360048201526001600160a01b0390911690633af32abf90602401602060405180830381865afa158015612a87573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612aab9190615a6b565b155b15612acb57604051637ed449a960e01b815260040160405180910390fd5b6040805160208101889052908101869052606081018590525f9060800160408051601f1981840301815291815281516020928301205f818152602e84528281206001600160a01b03891682529093529120549091506001811015612b42576040516339c556cd60e11b815260040160405180910390fd5b5f602a54118015612b5e57506002546001600160a01b03163314155b8015612b7557506006546001600160a01b03163314155b8015612b985750612b8a8888885f808061424b565b612b9661012c42615a9a565b105b15612bb65760405163085de62560e01b815260040160405180910390fd5b5f80612bc483602b546141e0565b90925090505f612bd48284615af7565b5f868152602e602090815260408083206001600160a01b038d1684528252808320839055888352602d909152812080549293508692909190612c17908490615af7565b9250508190555083602c5f828254612c2f9190615af7565b925050819055508060155f828254612c479190615a9a565b90915550612c5790508589614988565b876001600160a01b03167f2e06b2c9d4ccae2592eda2017cb2fb604b8d7418e85f023375514ab25ff2cc4c83604051612c9291815260200190565b60405180910390a2601c54604051632770a7eb60e21b8152306004820152602481018690526001600160a01b0390911690639dc29fac906044015f604051808303815f87803b158015612ce3575f80fd5b505af1158015612cf5573d5f803e3d5ffd5b5050601b54612d1192506001600160a01b0316905089846145fa565b50600180559199919850909650505050505050565b5f805f83612d3657602b54612d3a565b6029545b9050612d4685826141e0565b92509250509250929050565b601d54601c54601454604051632b78daa360e11b81526001600160a01b03928316600482015285831660248201523060448201526064810185905260848101919091525f92839216906356f1b5469060a4016040805180830381865afa158015612dbe573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612de29190615d2f565b915091509250929050565b604080516020808201879052818301869052606080830186905283518084039091018152608090920183528151918101919091205f908152602e82528281206001600160a01b038516825290915220545b949350505050565b600260015403612e6957604051633ee5aeb560e01b815260040160405180910390fd5b60026001819055546001600160a01b03163314612e9957604051630b2db9b760e31b815260040160405180910390fd5b6001600160a01b0381165f81815260096020908152604091829020805460ff1916905590519182527f2f520fb256d37bacc8a5e0fb9e69362d4bb462500c7e54f56ea54416e92d47d691015b60405180910390a15060018055565b5f54610100900460ff1615808015612f1257505f54600160ff909116105b80612f2b5750303b158015612f2b57505f5460ff166001145b612f8e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401611d6a565b5f805460ff191660011790558015612faf575f805461ff0019166101001790555b6006805461ffff60a01b191661010160a01b179055600280546001600160a01b0319166001600160a01b0384161790558015613024575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b60026001540361304b57604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff1661307a5760405163d311bc3960e01b815260040160405180910390fd5b600454600181101561309f576040516333f52ff560e01b815260040160405180910390fd5b601554801561320a575f8267ffffffffffffffff8111156130c2576130c2615865565b6040519080825280602002602001820160405280156130eb578160200160208202803683370190505b5090505f5b838110156131a6575f620f4240846004848154811061311157613111615aad565b905f5260205f2090600202016001015461312b9190615b0a565b6131359190615b35565b905060155481111561316857601554604051630abb811560e21b8152611d6a918391600401918252602082015260400190565b8083838151811061317b5761317b615aad565b6020026020010181815250508060155f8282546131989190615af7565b9091555050506001016130f0565b506040517f3f33b5ed245dfaf97e122dfc86e9d14ff254c4878a7c9ba8dab46d9c71cc3015905f90a15f5b8381101561320757601b54600480546131ff926001600160a01b0316919084908110611df657611df6615aad565b6001016131d1565b50505b505060018055565b60026001540361323557604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166132645760405163d311bc3960e01b815260040160405180910390fd5b6002546001600160a01b0316331461328f57604051630b2db9b760e31b815260040160405180910390fd5b600880546001600160a01b0319166001600160a01b0383169081179091556040519081527f7e7afb649fef7779605afaad37b91d9f5044726c260bb394570089d052d5dbb790602001612ee5565b5f805f806132f5602a5461012c42610d979190615a9a565b9195509350915061330a8484845f808061424b565b905090919293565b60026001540361333557604051633ee5aeb560e01b815260040160405180910390fd5b60026001819055546001600160a01b0316331461336557604051630b2db9b760e31b815260040160405180910390fd5b600354600160a01b900460ff1615613390576040516308db0db560e11b815260040160405180910390fd5b62015180816060015110156133b857604051630320a41d60e51b815260040160405180910390fd5b60a0810151603d558051601a8190556020820151602855601e556040808201516029556060820151602a556080820151602b5560c082015160165560e0820151601955610100820151603e5561014082015160068054610160850151600780546001600160a01b03199081166001600160a01b0393841617909155610180870151601c805483169184169190911790556101a0870151601b8054831691841691909117905542601781905560188190556101e0880151601d805484169185169190911790556101208801516008805484169185169190911790559482166001600160b01b031990931692909217909255603c929092556101c084015160028054909316911617905560038054600160a01b60ff60a01b19909116179055517f1eb56c868d62c38b9f2e3bd3d0556bed1dc7df623758318faaaaa05ffff993c7905f90a1601d5f9054906101000a90046001600160a01b03166001600160a01b031663ded4a6fe6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561354b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061356f9190615b48565b601b546001600160a01b0390811691161461359d57604051630ecd66ab60e41b815260040160405180910390fd5b601c5f9054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156135ed573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136119190615b7a565b60ff16601b5f9054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613664573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136889190615b7a565b60ff16146136a95760405163697e864b60e01b815260040160405180910390fd5b601c546040805163313ce56760e01b815290515f926001600160a01b03169163313ce5679160048083019260209291908290030181865afa1580156136f0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906137149190615b7a565b61371f90600a615c78565b61372a906001615b0a565b90505f613737825f614b6d565b603b5550506001805550565b60026001540361376657604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166137955760405163d311bc3960e01b815260040160405180910390fd5b5f61379e61458b565b90505f6127106301e13380601854426137b79190615af7565b6019546137c49086615b0a565b6137ce9190615b0a565b6137d89190615b35565b6137e29190615b35565b9050426018819055508060155f8282546137fc9190615a9a565b90915550506040518181527f2d46e156a9ac545bd5f27832a0e6293d21c92faf9237534c6b18c51e9cca59df90602001612655565b60606004805480602002602001604051908101604052809291908181526020015f9082821015610b54575f848152602090819020604080518082019091526002850290910180546001600160a01b03168252600190810154828401529083529092019101610b0d565b6002600154036138bd57604051633ee5aeb560e01b815260040160405180910390fd5b60026001819055546001600160a01b031633146138ed57604051630b2db9b760e31b815260040160405180910390fd5b603e5560018055565b60026001540361391957604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166139485760405163d311bc3960e01b815260040160405180910390fd5b6002546001600160a01b0316331461397357604051630b2db9b760e31b815260040160405180910390fd5b611a8681614c0e565b60026001540361399f57604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166139ce5760405163d311bc3960e01b815260040160405180910390fd5b600654600160a81b900460ff16156139f957604051636022a9e760e01b815260040160405180910390fd5b6001811015613a1b576040516334e33ddb60e01b815260040160405180910390fd5b6040805160208101869052908101849052606081018390525f906080016040516020818303038152906040528051906020012090506001602d5f8381526020019081526020015f20541015613a8357604051630683f18b60e41b815260040160405180910390fd5b5f602a54118015613a9f57506002546001600160a01b03163314155b8015613ab657506006546001600160a01b03163314155b8015613ad95750613acb8585855f808061424b565b613ad761012c42615a9a565b105b15613af75760405163085de62560e01b815260040160405180910390fd5b5f818152602f60205260408120548310613b1e575f828152602f6020526040902054613b20565b825b5f838152602f60205260408120549192508267ffffffffffffffff811115613b4a57613b4a615865565b604051908082528060200260200182016040528015613b73578160200160208202803683370190505b5090505f8367ffffffffffffffff811115613b9057613b90615865565b604051908082528060200260200182016040528015613bb9578160200160208202803683370190505b5090505f80808087875b613bcd8a8a615af7565b811115613db0575f8b8152602f60205260409020613bec600183615af7565b81548110613bfc57613bfc615aad565b5f918252602090912001546001600160a01b0316945081613c1c81615d51565b92505084888381518110613c3257613c32615aad565b6001600160a01b039283166020918202929092018101919091525f8d8152602e825260408082209389168252929091522054613c6e9087615a9a565b5f8c8152602e602090815260408083206001600160a01b038a168452909152902054602b54919750613c9f916141e0565b60405181815291955093506001600160a01b038616907f2e06b2c9d4ccae2592eda2017cb2fb604b8d7418e85f023375514ab25ff2cc4c9060200160405180910390a282878381518110613cf557613cf5615aad565b6020908102919091010152613d0a8385615af7565b60155f828254613d1a9190615a9a565b90915550505f8b8152602e602090815260408083206001600160a01b038916845282528083208390558d8352602f9091529020805480613d5c57613d5c615d66565b5f828152602080822083015f1990810180546001600160a01b03191690559092019092558c82526030815260408083206001600160a01b038916845290915281205580613da881615d51565b915050613bc3565b5084602c5f828254613dc29190615af7565b90915550505f8a8152602d602052604081208054879290613de4908490615af7565b9091555050601c54604051632770a7eb60e21b8152306004820152602481018790526001600160a01b0390911690639dc29fac906044015f604051808303815f87803b158015613e32575f80fd5b505af1158015613e44573d5f803e3d5ffd5b505050505f5b8751811015613e9a57601b548851613e92916001600160a01b0316908a9084908110613e7857613e78615aad565b6020026020010151898481518110611e2657611e26615aad565b600101613e4a565b50506001805550505050505050505050505050565b5f600260015403613ed357604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff16613f025760405163d311bc3960e01b815260040160405180910390fd5b600654600160a01b900460ff1615613f2d5760405163deeb694360e01b815260040160405180910390fd5b6002546001600160a01b03163314801590613f5357506006546001600160a01b03163314155b8015613f6957506008546001600160a01b031615155b8015613fdc5750600854604051633af32abf60e01b81523360048201526001600160a01b0390911690633af32abf90602401602060405180830381865afa158015613fb6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613fda9190615a6b565b155b15613ffa57604051637ed449a960e01b815260040160405180910390fd5b601b5484906001600160a01b038083169116148015906140835750601d54604051633af32abf60e01b81526001600160a01b03838116600483015290911690633af32abf90602401602060405180830381865afa15801561405d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906140819190615a6b565b155b156140a157604051632188be3960e21b815260040160405180910390fd5b6140ac8585856147cd565b91506140ba858585856148c4565b50600180559392505050565b6002600154036140e957604051633ee5aeb560e01b815260040160405180910390fd5b60026001819055546001600160a01b0316331461411957604051630b2db9b760e31b815260040160405180910390fd5b6001600160a01b038216158061413757506001600160a01b03821630145b156141555760405163e6c4247b60e01b815260040160405180910390fd5b60ff811660011480159061416d575060ff8116600214155b1561418b5760405163e01b409760e01b815260040160405180910390fd5b6001600160a01b0382165f81815260096020908152604091829020805460ff191660ff861617905590519182527f324201c119d7f14ed24d964257aa0c870524bde20d9ecb31d4b37eadc20336ff9101612655565b5f806141ec845f614b6d565b91508190505f831561421e576127106142058486615b0a565b61420f9190615b35565b905061421b8184615af7565b91505b509250929050565b5f808061423e6142396201518086615b35565b614dc0565b9196909550909350915050565b5f81614258603c85615b0a565b614264610e1087615b0a565b620151806142738b8b8b614f2f565b61427d9190615b0a565b6142879190615a9a565b6142919190615a9a565b61429b9190615a9a565b979650505050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526143119085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152615095565b50505050565b601d546040516364696fab60e11b81526001600160a01b038481166004830152602482018490525f92169063c8d2df5690604401602060405180830381865afa158015614366573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061438a9190615b63565b9392505050565b5f805f836143a157602b546143a5565b6029545b90506143b186826141e0565b60285491945092508311156143d957604051631b6132ab60e31b815260040160405180910390fd5b60018210156143fb57604051631fbaba3560e01b815260040160405180910390fd5b60315460ff166144255761440f8284615af7565b60155f82825461441f9190615a9a565b90915550505b604080518381526020810188905233916001600160a01b0388169183917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4601c54604051632770a7eb60e21b8152336004820152602481018890526001600160a01b0390911690639dc29fac906044015f604051808303815f87803b1580156144b6575f80fd5b505af11580156144c8573d5f803e3d5ffd5b5050601b546144e492506001600160a01b0316905086846145fa565b50935093915050565b5f80601c5f9054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561453f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906145639190615b7a565b61456e90600a615c78565b614579906001615b0a565b9050614585815f614b6d565b91505090565b601d5460145460405163ad07802160e01b815260048101919091525f916001600160a01b03169063ad07802190602401602060405180830381865afa1580156145d6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ae69190615b63565b6040516001600160a01b03831660248201526044810182905261462a90849063a9059cbb60e01b906064016142da565b505050565b8015806146a75750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015614681573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906146a59190615b63565b155b6147125760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401611d6a565b6040516001600160a01b03831660248201526044810182905261462a90849063095ea7b360e01b906064016142da565b60026001540361476557604051633ee5aeb560e01b815260040160405180910390fd5b6002600155600354600160a01b900460ff166147945760405163d311bc3960e01b815260040160405180910390fd5b6003546001600160a01b031633146147be576040516282b42960e81b815260040160405180910390fd5b6147c733615168565b60018055565b5f60018310156147f05760405163162908e360e11b815260040160405180910390fd5b6001600160a01b038216158061480e57506001600160a01b03821630145b1561482c57604051631e4ec46b60e01b815260040160405180910390fd5b5f806148388686612d52565b91509150600182101561485e57604051633999656760e01b815260040160405180910390fd5b601a5481111561488157604051639ade546d60e01b815260040160405180910390fd5b5f61488a61458b565b6148949083615a9a565b9050601e548111156148b9576040516312e7cad560e21b815260040160405180910390fd5b509095945050505050565b604080516001600160a01b038681168252602082018690529181018390529083169033907fc436f473cd90c9b4dd731856a14b80f713d384a1688a506d4230140c5b36d5cd9060600160405180910390a3614921843330866142a6565b601c546040516340c10f1960e01b81526001600160a01b03848116600483015260248201849052909116906340c10f19906044015f604051808303815f87803b15801561496c575f80fd5b505af115801561497e573d5f803e3d5ffd5b5050505050505050565b5f8281526030602090815260408083206001600160a01b03851684529091528120546149b690600190615af7565b5f848152602f6020526040812080549293506149d3600184615af7565b815481106149e3576149e3615aad565b5f918252602090912001546001600160a01b03908116915084168114614b07575f858152602f60205260409020805484908110614a2257614a22615aad565b5f918252602080832090910154878352602f90915260409091206001600160a01b0390911690614a53600185615af7565b81548110614a6357614a63615aad565b905f5260205f20015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555080602f5f8781526020019081526020015f208481548110614ab157614ab1615aad565b5f91825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055614ae4836001615a9a565b5f8681526030602090815260408083206001600160a01b03861684529091529020555b5f858152602f60205260409020805480614b2357614b23615d66565b5f828152602080822083015f1990810180546001600160a01b03191690559092019092559581526030865260408082206001600160a01b0396909616825294909552505050812055565b5f80601c5f9054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015614bbf573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190614be39190615b63565b905060018110614c0657614c01614bf861458b565b85908386615184565b612e3e565b509192915050565b6003545f906001600160a01b031615614c8d576003546040516001600160a01b03909116602482015260440160408051601f19818403018152918152602080830180516001600160e01b031663f2fde38b60e01b1790529051614c72929101615a59565b60405160208183030381529060405280519060200120614c8f565b5f5b6040516001600160a01b03841660248201529091505f9060440160408051601f19818403018152918152602080830180516001600160e01b031663f2fde38b60e01b1790529051614ce1929101615a59565b604051602081830303815290604052805190602001209050614d02836151df565b8115614d625760075460405163c4d252f560e01b8152600481018490526001600160a01b039091169063c4d252f5906024015f604051808303815f87803b158015614d4b575f80fd5b505af1158015614d5d573d5f803e3d5ffd5b505050505b600754604051631523ab0160e21b8152600481018390526001600160a01b039091169063548eac04906024015f604051808303815f87803b158015614da5575f80fd5b505af1158015614db7573d5f803e3d5ffd5b50505050505050565b5f8080838162253d8c614dd68362010bd9615d7a565b614de09190615d7a565b90505f62023ab1614df2836004615da1565b614dfc9190615dd0565b90506004614e0d8262023ab1615da1565b614e18906003615d7a565b614e229190615dd0565b614e2c9083615dfc565b91505f62164b09614e3e846001615d7a565b614e4a90610fa0615da1565b614e549190615dd0565b90506004614e64826105b5615da1565b614e6e9190615dd0565b614e789084615dfc565b614e8390601f615d7a565b92505f61098f614e94856050615da1565b614e9e9190615dd0565b90505f6050614eaf8361098f615da1565b614eb99190615dd0565b614ec39086615dfc565b9050614ed0600b83615dd0565b9450614edd85600c615da1565b614ee8836002615d7a565b614ef29190615dfc565b91508483614f01603187615dfc565b614f0c906064615da1565b614f169190615d7a565b614f209190615d7a565b9a919950975095505050505050565b5f6107b2841015614f6a5760405162461bcd60e51b815260206004820152600560248201526422b93937b960d91b6044820152606401611d6a565b8383835f62253d8c60046064600c614f83600e88615dfc565b614f8d9190615dd0565b614f9988611324615d7a565b614fa39190615d7a565b614fad9190615dd0565b614fb8906003615da1565b614fc29190615dd0565b600c80614fd0600e88615dfc565b614fda9190615dd0565b614fe590600c615da1565b614ff0600288615dfc565b614ffa9190615dfc565b6150069061016f615da1565b6150109190615dd0565b6004600c61501f600e89615dfc565b6150299190615dd0565b615035896112c0615d7a565b61503f9190615d7a565b61504b906105b5615da1565b6150559190615dd0565b615061617d4b87615dfc565b61506b9190615d7a565b6150759190615d7a565b61507f9190615dfc565b6150899190615dfc565b98975050505050505050565b5f6150e9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661526c9092919063ffffffff16565b905080515f14806151095750808060200190518101906151099190615a6b565b61462a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611d6a565b600380546001600160a01b03191690556151818161527a565b50565b5f806151918686866152f2565b905060018360028111156151a7576151a7615e22565b1480156151c357505f84806151be576151be615b21565b868809115b156151d6576151d3600182615a9a565b90505b95945050505050565b6001600160a01b03811615806151fd57506001600160a01b03811630145b1561521b5760405163e6c4247b60e01b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b03838116918217909255600254604051919216907f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700905f90a350565b6060612e3e84845f856153d7565b6001600160a01b0381166152a15760405163156fee5160e31b815260040160405180910390fd5b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f80805f19858709858702925082811083820303915050805f036153295783828161531f5761531f615b21565b049250505061438a565b8084116153705760405162461bcd60e51b81526020600482015260156024820152744d6174683a206d756c446976206f766572666c6f7760581b6044820152606401611d6a565b5f8486880960026001871981018816978890046003810283188082028403028082028403028082028403028082028403028082028403029081029092039091025f889003889004909101858311909403939093029303949094049190911702949350505050565b6060824710156154385760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401611d6a565b5f80866001600160a01b031685876040516154539190615e36565b5f6040518083038185875af1925050503d805f811461548d576040519150601f19603f3d011682016040523d82523d5f602084013e615492565b606091505b509150915061429b878383876060831561550c5782515f03615505576001600160a01b0385163b6155055760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611d6a565b5081612e3e565b612e3e83838151156155215781518083602001fd5b8060405162461bcd60e51b8152600401611d6a9190615a59565b5080545f8255600202905f5260205f209081019061518191905b808211156155795780546001600160a01b03191681555f6001820155600201615555565b5090565b5f6020828403121561558d575f80fd5b5035919050565b602080825282518282018190525f918401906040840190835b818110156148b957835180516001600160a01b0316845260209081015181850152909301926040909201916001016155ad565b6001600160a01b0381168114615181575f80fd5b80356155ff816155e0565b919050565b5f8060408385031215615615575f80fd5b823591506020830135615627816155e0565b809150509250929050565b5f8060208385031215615643575f80fd5b823567ffffffffffffffff811115615659575f80fd5b8301601f81018513615669575f80fd5b803567ffffffffffffffff81111561567f575f80fd5b8560208260061b8401011115615693575f80fd5b6020919091019590945092505050565b5f805f606084860312156156b5575f80fd5b83356156c0816155e0565b92506020840135915060408401356156d7816155e0565b809150509250925092565b5f805f606084860312156156f4575f80fd5b505081359360208301359350604090920135919050565b5f6020828403121561571b575f80fd5b813561438a816155e0565b8015158114615181575f80fd5b5f8060408385031215615744575f80fd5b823561574f81615726565b9150602083013561562781615726565b60ff81168114615181575f80fd5b5f805f805f805f60e0888a031215615783575f80fd5b873561578e816155e0565b96506020880135955060408801356157a5816155e0565b9450606088013593506080880135925060a0880135915060c08801356157ca8161575f565b8091505092959891949750929550565b5f80604083850312156157eb575f80fd5b82359150602083013561562781615726565b5f805f8060808587031215615810575f80fd5b8435935060208501359250604085013591506060850135615830816155e0565b939692955090935050565b5f806040838503121561584c575f80fd5b8235615857816155e0565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b604051610200810167ffffffffffffffff8111828210171561589d5761589d615865565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156158cc576158cc615865565b604052919050565b5f6102008284031280156158e6575f80fd5b506158ef615879565b823581526020808401359082015260408084013590820152606080840135908201526080808401359082015260a0808401359082015260c0808401359082015260e08084013590820152610100808401359082015261595161012084016155f4565b61012082015261596461014084016155f4565b61014082015261597761016084016155f4565b61016082015261598a61018084016155f4565b61018082015261599d6101a084016155f4565b6101a08201526159b06101c084016155f4565b6101c08201526159c36101e084016155f4565b6101e08201529392505050565b5f805f80608085870312156159e3575f80fd5b5050823594602084013594506040840135936060013592509050565b5f8060408385031215615a10575f80fd5b8235615a1b816155e0565b915060208301356156278161575f565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f61438a6020830184615a2b565b5f60208284031215615a7b575f80fd5b815161438a81615726565b634e487b7160e01b5f52601160045260245ffd5b808201808211156116fd576116fd615a86565b634e487b7160e01b5f52603260045260245ffd5b8135615acc816155e0565b81546001600160a01b0319166001600160a01b03919091161781556020919091013560019190910155565b818103818111156116fd576116fd615a86565b80820281158282048414176116fd576116fd615a86565b634e487b7160e01b5f52601260045260245ffd5b5f82615b4357615b43615b21565b500490565b5f60208284031215615b58575f80fd5b815161438a816155e0565b5f60208284031215615b73575f80fd5b5051919050565b5f60208284031215615b8a575f80fd5b815161438a8161575f565b6001815b6001841115615bd057808504811115615bb457615bb4615a86565b6001841615615bc257908102905b60019390931c928002615b99565b935093915050565b5f82615be6575060016116fd565b81615bf257505f6116fd565b8160018114615c085760028114615c1257615c2e565b60019150506116fd565b60ff841115615c2357615c23615a86565b50506001821b6116fd565b5060208310610133831016604e8410600b8410161715615c51575081810a6116fd565b615c5d5f198484615b95565b805f1904821115615c7057615c70615a86565b029392505050565b5f61438a60ff841683615bd8565b5f60208284031215615c96575f80fd5b815167ffffffffffffffff811115615cac575f80fd5b8201601f81018413615cbc575f80fd5b805167ffffffffffffffff811115615cd657615cd6615865565b8060051b615ce6602082016158a3565b91825260208184018101929081019087841115615d01575f80fd5b6020850194505b8385101561429b5784519250615d1d836155e0565b82825260209485019490910190615d08565b5f8060408385031215615d40575f80fd5b505080516020909101519092909150565b5f81615d5f57615d5f615a86565b505f190190565b634e487b7160e01b5f52603160045260245ffd5b8082018281125f831280158216821582161715615d9957615d99615a86565b505092915050565b8082025f8212600160ff1b84141615615dbc57615dbc615a86565b81810583148215176116fd576116fd615a86565b5f82615dde57615dde615b21565b600160ff1b82145f1984141615615df757615df7615a86565b500590565b8181035f831280158383131683831282161715615e1b57615e1b615a86565b5092915050565b634e487b7160e01b5f52602160045260245ffd5b5f82518060208501845e5f92019182525091905056fea26469706673582212203cfcf2e0022a02b0895fd09591f4c48f657caaa7f78c4e71c56e624254dc08fb64736f6c634300081a0033
Deployed Bytecode Sourcemap
108271:8401:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80234:642;;;;;;:::i;:::-;;:::i;:::-;;68441:162;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;108674:33;;;;;;;;;1190:25:1;;;1178:2;1163:18;108674:33:0;1044:177:1;93304:2246:0;;;;;;:::i;:::-;;:::i;:::-;;;;2104:25:1;;;2160:2;2145:18;;2138:34;;;;2188:18;;;2181:34;2246:2;2231:18;;2224:34;2091:3;2076:19;93304:2246:0;1873:391:1;59997:30:0;;;;;-1:-1:-1;;;;;59997:30:0;;;;;;-1:-1:-1;;;;;2433:32:1;;;2415:51;;2403:2;2388:18;59997:30:0;2269:203:1;112060:580:0;;;;;;:::i;:::-;;:::i;65796:703::-;;;;;;:::i;:::-;;:::i;78194:1130::-;;;;;;:::i;:::-;;:::i;73857:488::-;;;;;;:::i;:::-;;:::i;92565:404::-;;;;;;:::i;:::-;;:::i;87993:26::-;;;;;;84685:433;;;;;;:::i;:::-;;:::i;64972:678::-;;;;;;:::i;:::-;;:::i;91794:466::-;;;;;;:::i;:::-;;:::i;70624:28::-;;;;;;116119:99;116195:15;;-1:-1:-1;;;;;116195:15:0;116119:99;;73288:365;;;;;;:::i;:::-;;:::i;89000:26::-;;;;;;;;;;;;4531:14:1;;4524:22;4506:41;;4494:2;4479:18;89000:26:0;4366:187:1;85284:413:0;;;:::i;113010:1689::-;;;:::i;116331:99::-;;;:::i;59869:73::-;;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;4750:32:1;;;4732:51;;4814:2;4799:18;;4792:34;;;;4705:18;59869:73:0;4558:274:1;60099:26:0;;;;;-1:-1:-1;;;60099:26:0;;;;;;107691:463;;;;;;:::i;:::-;;:::i;:::-;;;;5011:25:1;;;5067:2;5052:18;;5045:34;;;;4984:18;107691:463:0;4837:248:1;86865:109:0;;;:::i;76579:1304::-;;;;;;:::i;:::-;;:::i;114904:1066::-;;;;;;:::i;:::-;;:::i;70716:35::-;;;;;;70212:29;;;;;;79490:571;;;;;;:::i;:::-;;:::i;67042:369::-;;;:::i;108375:28::-;;;;;;87896:35;;;;;;88087:28;;;;;;63022:316;;;;;;:::i;:::-;;:::i;41760:89::-;41835:6;;-1:-1:-1;;;;;41835:6:0;41760:89;;70836:31;;;;;;59745:62;;;;;;:::i;:::-;;:::i;75619:580::-;;;;;;:::i;:::-;;:::i;88221:36::-;;;;;;91194:227;;;;;;:::i;:::-;;:::i;96323:2208::-;;;;;;:::i;:::-;;:::i;104762:353::-;;;;;;:::i;:::-;;:::i;84196:281::-;;;;;;:::i;:::-;;:::i;60487:56::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;8250:4:1;8238:17;;;8220:36;;8208:2;8193:18;60487:56:0;8078:184:1;106990:321:0;;;;;;:::i;:::-;;:::i;60394:38::-;;;;;-1:-1:-1;;;;;60394:38:0;;;64661:167;;;;;;:::i;:::-;;:::i;109375:172::-;;;;;;:::i;:::-;;:::i;81539:1024::-;;;:::i;63685:221::-;;;;;;:::i;:::-;;:::i;105408:403::-;;;:::i;109661:2125::-;;;;;;:::i;:::-;;:::i;71094:37::-;;;;;-1:-1:-1;;;;;71094:37:0;;;80946:452;;;:::i;70327:35::-;;;;;;108583:34;;;;;;71245:25;;;;;;68293:140;;;:::i;60297:37::-;;;;;-1:-1:-1;;;;;60297:37:0;;;51794:95;51868:13;;-1:-1:-1;;;;;51868:13:0;51794:95;;70434:31;;;;;;112760:128;;;;;;:::i;:::-;;:::i;87775:34::-;;;;;;60200:29;;;;;-1:-1:-1;;;60200:29:0;;;;;;66760:160;;;;;;:::i;:::-;;:::i;99094:2918::-;;;;;;:::i;:::-;;:::i;74688:377::-;;;;;;:::i;:::-;;:::i;71016:29::-;;;;;-1:-1:-1;;;;;71016:29:0;;;70535:30;;;;;;108467:33;;;;;;64110:429;;;;;;:::i;:::-;;:::i;106211:287::-;;;;;;:::i;:::-;106402:28;;;;;;;13161:25:1;;;;13202:18;;;13195:34;;;;13245:18;;;;13238:34;;;;106402:28:0;;;;;;;;;;13134:18:1;;;;106402:28:0;;106392:39;;;;;;-1:-1:-1;106459:31:0;;;:17;:31;;;;;;;106211:287;80234:642;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;50000:11:::1;::::0;-1:-1:-1;;;50000:11:0;::::1;;;49995:40;;50020:15;;-1:-1:-1::0;;;50020:15:0::1;;;;;;;;;;;49995:40;40786:6:::2;::::0;-1:-1:-1;;;;;40786:6:0::2;40772:10;:20;40768:44;;40801:11;;-1:-1:-1::0;;;40801:11:0::2;;;;;;;;;;;40768:44;80483:9:::3;80622:23;80530:130;;;;;;1190:25:1::0;;1178:2;1163:18;;1044:177;80530:130:0::3;;::::0;;-1:-1:-1;;80530:130:0;;::::3;::::0;;;;;;::::3;::::0;;::::3;::::0;;-1:-1:-1;;;;;80530:130:0::3;-1:-1:-1::0;;;80530:130:0::3;::::0;;80505:166;;::::3;::::0;80530:130;80505:166:::3;;:::i;:::-;;::::0;;-1:-1:-1;;80505:166:0;;::::3;::::0;;;;;;;80495:177;;80505:166:::3;80495:177:::0;;::::3;::::0;80685:20:::3;:46:::0;;;1190:25:1;;;80495:177:0;-1:-1:-1;80747:45:0::3;::::0;1163:18:1;80747:45:0::3;;;;;;;;80834:22;::::0;80805:63:::3;::::0;-1:-1:-1;;;80805:63:0;;::::3;::::0;::::3;1190:25:1::0;;;-1:-1:-1;;;;;80834:22:0;;::::3;::::0;80805:60:::3;::::0;1163:18:1;;80805:63:0::3;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;-1:-1:-1::0;;38345:1:0;40614:21;;-1:-1:-1;;;;80234:642:0:o;68441:162::-;68503:48;68571:24;68564:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;68564:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68441:162;:::o;93304:2246::-;93488:22;93521:12;93545:13;93570:11;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;50000:11:::1;::::0;-1:-1:-1;;;50000:11:0;::::1;;;49995:40;;50020:15;;-1:-1:-1::0;;;50020:15:0::1;;;;;;;;;;;49995:40;90717:17:::2;::::0;-1:-1:-1;;;90717:17:0;::::2;;;90713:49;;;90743:19;;-1:-1:-1::0;;;90743:19:0::2;;;;;;;;;;;90713:49;62285:6:::3;::::0;-1:-1:-1;;;;;62285:6:0::3;62271:10;:20;::::0;::::3;::::0;62270:71:::3;;-1:-1:-1::0;62325:15:0::3;::::0;-1:-1:-1;;;;;62325:15:0::3;62311:10;:29;;62270:71;:128;;;;-1:-1:-1::0;62360:23:0::3;::::0;-1:-1:-1;;;;;62360:23:0::3;:37:::0;::::3;62270:128;:217;;;;-1:-1:-1::0;62436:23:0::3;::::0;62418:68:::3;::::0;-1:-1:-1;;;62418:68:0;;62475:10:::3;62418:68;::::0;::::3;2415:51:1::0;-1:-1:-1;;;;;62436:23:0;;::::3;::::0;62418:56:::3;::::0;2388:18:1;;62418:68:0::3;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62417:69;62270:217;62252:276;;;62506:22;;-1:-1:-1::0;;;62506:22:0::3;;;;;;;;;;;62252:276;-1:-1:-1::0;;;;;93647:26:0;::::4;::::0;;93646:63:::4;;-1:-1:-1::0;;;;;;93679:29:0;::::4;93703:4;93679:29;93646:63;93642:93;;;93718:17;;-1:-1:-1::0;;;93718:17:0::4;;;;;;;;;;;93642:93;93759:1;93750:6;:10;93746:38;;;93769:15;;-1:-1:-1::0;;;93769:15:0::4;;;;;;;;;;;93746:38;93798:20;93820:22:::0;93846:41:::4;93865:6;93873:13;;93846:18;:41::i;:::-;93797:90;;;;93917:19;;93902:12;:34;93898:71;;;93945:24;;-1:-1:-1::0;;;93945:24:0::4;;;;;;;;;;;93898:71;94001:1;93984:14;:18;93980:45;;;94011:14;;-1:-1:-1::0;;;94011:14:0::4;;;;;;;;;;;93980:45;94248:1;94234:11;;:15;94230:48;;;94258:20;;-1:-1:-1::0;;;94258:20:0::4;;;;;;;;;;;94230:48;94450:11;::::0;94373:89:::4;::::0;94399:48:::4;69790:9;94399:15;:48;:::i;:::-;:62;;;;:::i;:::-;94373:25;:89::i;:::-;94544:28;::::0;;::::4;::::0;;::::4;13161:25:1::0;;;13202:18;;;13195:34;;;13245:18;;;;13238:34;;;94544:28:0;;;;;;;;;;13134:18:1;;;;94544:28:0;;;94534:39;;;::::4;::::0;13161:25:1;;-1:-1:-1;13195:34:1;;-1:-1:-1;13238:34:1;-1:-1:-1;94671:82:0::4;13161:25:1::0;13195:34;13238;-1:-1:-1;;;94671:31:0::4;:82::i;:::-;94654:99;;94828:6;94803:21;;:31;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;94845:31:0::4;::::0;;;:17:::4;:31;::::0;;;;:41;;94880:6;;94845:31;:41:::4;::::0;94880:6;;94845:41:::4;:::i;:::-;::::0;;;-1:-1:-1;;95002:30:0::4;::::0;;;:16:::4;:30;::::0;;;;;;;-1:-1:-1;;;;;95002:44:0;::::4;::::0;;;;;;;;:49;;94998:250:::4;;95068:40;::::0;;;:26:::4;:40;::::0;;;;;;;:59;;::::4;::::0;::::4;::::0;;;;;;;;::::4;::::0;;-1:-1:-1;;;;;;95068:59:0::4;-1:-1:-1::0;;;;;95068:59:0;::::4;::::0;;::::4;::::0;;;95189:40;;;:47;;95142:16:::4;:30:::0;;;;;:44;;;;;;;;:94;94998:250:::4;95260:30;::::0;;;:16:::4;:30;::::0;;;;;;;-1:-1:-1;;;;;95260:44:0;::::4;::::0;;;;;;;:54;;95308:6;;95260:30;:54:::4;::::0;95308:6;;95260:54:::4;:::i;:::-;::::0;;;-1:-1:-1;;95332:53:0::4;::::0;1190:25:1;;;-1:-1:-1;;;;;95332:53:0;::::4;::::0;95360:10:::4;::::0;95332:53:::4;::::0;1178:2:1;1163:18;95332:53:0::4;;;;;;;95491:14;::::0;95435:107:::4;::::0;-1:-1:-1;;;;;95491:14:0::4;95508:10;95528:4;95535:6:::0;95435:37:::4;:107::i;:::-;-1:-1:-1::0;;38345:1:0;40614:21;;-1:-1:-1;93304:2246:0;;;;-1:-1:-1;93304:2246:0;-1:-1:-1;93304:2246:0:o;112060:580::-;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;50000:11:::1;::::0;-1:-1:-1;;;50000:11:0;::::1;;;49995:40;;50020:15;;-1:-1:-1::0;;;50020:15:0::1;;;;;;;;;;;49995:40;40786:6:::2;::::0;-1:-1:-1;;;;;40786:6:0::2;40772:10;:20;40768:44;;40801:11;;-1:-1:-1::0;;;40801:11:0::2;;;;;;;;;;;40768:44;112223:11:::3;:25:::0;;;112423:121:::3;::::0;::::3;::::0;::::3;1190:25:1::0;;;112376:9:0::3;::::0;1163:18:1;;112423:121:0::3;::::0;;-1:-1:-1;;112423:121:0;;::::3;::::0;;;;;;::::3;::::0;;::::3;::::0;;-1:-1:-1;;;;;112423:121:0::3;-1:-1:-1::0;;;112423:121:0::3;::::0;;112398:157;;::::3;::::0;112423:121;112398:157:::3;;:::i;:::-;;::::0;;;;::::3;-1:-1:-1::0;;112398:157:0;;;;;;;112388:168;;112398:157:::3;112388:168:::0;;::::3;::::0;112598:22:::3;::::0;-1:-1:-1;;;112569:63:0;;::::3;::::0;::::3;1190:25:1::0;;;112388:168:0;;-1:-1:-1;;;;;;112598:22:0::3;::::0;112569:60:::3;::::0;1163:18:1;;112569:63:0::3;1044:177:1::0;65796:703:0;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;;;40786:6;-1:-1:-1;;;;;40786:6:0::1;40772:10;:20;40768:44;;40801:11;;-1:-1:-1::0;;;40801:11:0::1;;;;;;;;;;;40768:44;65967:12:::2;66002:10:::0;66038:1:::2;66034:5:::0;::::2;66030:40;;;66048:22;;-1:-1:-1::0;;;66048:22:0::2;;;;;;;;;;;66030:40;66083:31;66090:24;;66083:31;:::i;:::-;66132:9;66127:307;66147:1;66143;:5;66127:307;;;66201:1;66174:10;;66185:1;66174:13;;;;;;;:::i;:::-;;;;;;:24;;;:28;66170:56;;;66211:15;;-1:-1:-1::0;;;66211:15:0::2;;;;;;;;;;;66170:56;66287:1;66245:10:::0;;66256:1;66245:13;;::::2;;;;;:::i;:::-;:30;::::0;::::2;:13;::::0;;::::2;;:30:::0;;::::2;::::0;-1:-1:-1;66245:30:0::2;:::i;:::-;-1:-1:-1::0;;;;;66245:44:0::2;::::0;66241:73:::2;;66298:16;;-1:-1:-1::0;;;66298:16:0::2;;;;;;;;;;;66241:73;66339:10;;66350:1;66339:13;;;;;;;:::i;:::-;;;;;;:24;;;66331:32;;;;;:::i;:::-;;;66378:24;66408:10;;66419:1;66408:13;;;;;;;:::i;:::-;66378:44:::0;;::::2;::::0;::::2;::::0;;-1:-1:-1;66378:44:0;;;::::2;::::0;;;66408:13:::2;::::0;;::::2;::::0;;;::::2;::::0;66378:44:::2;;::::0;;::::2;::::0;-1:-1:-1;66378:44:0::2;66408:13:::0;66378:44;::::2;:::i;:::-;-1:-1:-1::0;;66150:3:0::2;;66127:307;;;;66450:4;66458:8;66450:16;66446:45;;66475:16;;-1:-1:-1::0;;;66475:16:0::2;;;;;;;;;;;66446:45;-1:-1:-1::0;;38345:1:0;40614:21;;-1:-1:-1;;65796:703:0:o;78194:1130::-;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;50000:11:::1;::::0;-1:-1:-1;;;50000:11:0;::::1;;;49995:40;;50020:15;;-1:-1:-1::0;;;50020:15:0::1;;;;;;;;;;;49995:40;62009:15:::2;::::0;-1:-1:-1;;;;;62009:15:0::2;61995:10;:29;::::0;::::2;::::0;61994:57:::2;;-1:-1:-1::0;62044:6:0::2;::::0;-1:-1:-1;;;;;62044:6:0::2;62030:10;:20;;61994:57;61990:91;;;62060:21;;-1:-1:-1::0;;;62060:21:0::2;;;;;;;;;;;61990:91;78403:1:::3;78394:6;:10;78390:38;;;78413:15;;-1:-1:-1::0;;;78413:15:0::3;;;;;;;;;;;78390:38;-1:-1:-1::0;;;;;78461:38:0;::::3;78441:17;78461:38:::0;;;:22:::3;:38;::::0;;;;;::::3;;::::0;78514:15;::::3;78510:51;;;78538:23;;-1:-1:-1::0;;;78538:23:0::3;;;;;;;;;;;78510:51;78709:15;::::0;78656:31:::3;::::0;-1:-1:-1;;;;;78691:33:0;;::::3;78709:15:::0;::::3;78691:33;78690:102;;78737:55;78769:14;78785:6;78737:31;:55::i;:::-;78690:102;;;78728:6;78690:102;78656:136;;78835:14;;78809:23;:40;78805:76;;;78858:23;;-1:-1:-1::0;;;78858:23:0::3;;;;;;;;;;;78805:76;78910:23;78892:14;;:41;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;;;78950:38:0::3;::::0;::::3;::::0;78946:371:::3;;79005:93;::::0;-1:-1:-1;;;79005:93:0;;-1:-1:-1;;;;;14205:32:1;;;79005:93:0::3;::::0;::::3;14187:51:1::0;14254:18;;;14247:34;;;79091:4:0::3;14297:18:1::0;;;14290:60;79005:45:0;::::3;::::0;::::3;::::0;14160:18:1;;79005:93:0::3;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;78946:371;;;79194:111;79250:14;79267;79291:4;79298:6;79194:37;:111::i;:::-;-1:-1:-1::0;;38345:1:0;40614:21;;-1:-1:-1;;;78194:1130:0:o;73857:488::-;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;50000:11:::1;::::0;-1:-1:-1;;;50000:11:0;::::1;;;49995:40;;50020:15;;-1:-1:-1::0;;;50020:15:0::1;;;;;;;;;;;49995:40;62009:15:::2;::::0;-1:-1:-1;;;;;62009:15:0::2;61995:10;:29;::::0;::::2;::::0;61994:57:::2;;-1:-1:-1::0;62044:6:0::2;::::0;-1:-1:-1;;;;;62044:6:0::2;62030:10;:20;;61994:57;61990:91;;;62060:21;;-1:-1:-1::0;;;62060:21:0::2;;;;;;;;;;;61990:91;73980:17:::3;74000:41;74020:20;74000:19;:41::i;:::-;73980:61;;74052:28;74083:21;:19;:21::i;:::-;74052:52;;74189:20;74177:9;:32;74173:70;;;74218:25;;-1:-1:-1::0;;;74218:25:0::3;;;;;;;;;;;74173:70;-1:-1:-1::0;;74256:14:0::3;:37:::0;74322:15:::3;74304;:33:::0;38345:1;40614:21;;73857:488::o;92565:404::-;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;50000:11:::1;::::0;-1:-1:-1;;;50000:11:0;::::1;;;49995:40;;50020:15;;-1:-1:-1::0;;;50020:15:0::1;;;;;;;;;;;49995:40;90717:17:::2;::::0;-1:-1:-1;;;90717:17:0;::::2;;;90713:49;;;90743:19;;-1:-1:-1::0;;;90743:19:0::2;;;;;;;;;;;90713:49;62285:6:::3;::::0;-1:-1:-1;;;;;62285:6:0::3;62271:10;:20;::::0;::::3;::::0;62270:71:::3;;-1:-1:-1::0;62325:15:0::3;::::0;-1:-1:-1;;;;;62325:15:0::3;62311:10;:29;;62270:71;:128;;;;-1:-1:-1::0;62360:23:0::3;::::0;-1:-1:-1;;;;;62360:23:0::3;:37:::0;::::3;62270:128;:217;;;;-1:-1:-1::0;62436:23:0::3;::::0;62418:68:::3;::::0;-1:-1:-1;;;62418:68:0;;62475:10:::3;62418:68;::::0;::::3;2415:51:1::0;-1:-1:-1;;;;;62436:23:0;;::::3;::::0;62418:56:::3;::::0;2388:18:1;;62418:68:0::3;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62417:69;62270:217;62252:276;;;62506:22;;-1:-1:-1::0;;;62506:22:0::3;;;;;;;;;;;62252:276;-1:-1:-1::0;;;;;92765:26:0;::::4;::::0;;92764:63:::4;;-1:-1:-1::0;;;;;;92797:29:0;::::4;92821:4;92797:29;92764:63;92760:93;;;92836:17;;-1:-1:-1::0;;;92836:17:0::4;;;;;;;;;;;92760:93;92877:1;92868:6;:10;92864:38;;;92887:15;;-1:-1:-1::0;;;92887:15:0::4;;;;;;;;;;;92864:38;92915:46;92934:6;92942:12;92956:4;92915:18;:46::i;84685:433::-:0;84765:7;84806:1;84789:14;;:18;84785:41;;;-1:-1:-1;84824:1:0;;84685:433;-1:-1:-1;84685:433:0:o;84785:41::-;84864:1;84841:20;:24;84837:51;;;-1:-1:-1;84882:5:0;;84685:433;-1:-1:-1;84685:433:0:o;84837:51::-;84940:14;;84917:20;:37;84916:194;;85105:5;85081:20;85055:14;;85072:5;85055:22;;;;:::i;:::-;85054:47;;;;:::i;:::-;85053:57;;;;:::i;:::-;84916:194;;;85010:14;;85028:5;;84978:28;:20;85028:5;84978:28;:::i;:::-;84977:47;;;;:::i;:::-;84976:57;;;;:::i;:::-;84909:201;84685:433;-1:-1:-1;;84685:433:0:o;64972:678::-;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;;;40786:6;-1:-1:-1;;;;;40786:6:0::1;40772:10;:20;40768:44;;40801:11;;-1:-1:-1::0;;;40801:11:0::1;;;;;;;;;;;40768:44;65140:12:::2;65175:10:::0;65211:1:::2;65207:5:::0;::::2;65203:40;;;65221:22;;-1:-1:-1::0;;;65221:22:0::2;;;;;;;;;;;65203:40;65256:20;65263:13;;65256:20;:::i;:::-;65294:9;65289:296;65309:1;65305;:5;65289:296;;;65363:1;65336:10;;65347:1;65336:13;;;;;;;:::i;:::-;;;;;;:24;;;:28;65332:56;;;65373:15;;-1:-1:-1::0;;;65373:15:0::2;;;;;;;;;;;65332:56;65449:1;65407:10:::0;;65418:1;65407:13;;::::2;;;;;:::i;:::-;:30;::::0;::::2;:13;::::0;;::::2;;:30:::0;;::::2;::::0;-1:-1:-1;65407:30:0::2;:::i;:::-;-1:-1:-1::0;;;;;65407:44:0::2;::::0;65403:73:::2;;65460:16;;-1:-1:-1::0;;;65460:16:0::2;;;;;;;;;;;65403:73;65501:10;;65512:1;65501:13;;;;;;;:::i;:::-;;;;;;:24;;;65493:32;;;;;:::i;:::-;;;65540:13;65559:10;;65570:1;65559:13;;;;;;;:::i;:::-;65540:33:::0;;::::2;::::0;::::2;::::0;;-1:-1:-1;65540:33:0;;;::::2;::::0;;;65559:13:::2;::::0;;::::2;::::0;;;::::2;::::0;65540:33:::2;;::::0;;::::2;::::0;-1:-1:-1;65540:33:0::2;65559:13:::0;65540:33;::::2;:::i;:::-;-1:-1:-1::0;;65312:3:0::2;;65289:296;;91794:466:::0;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;;;40786:6;-1:-1:-1;;;;;40786:6:0::1;40772:10;:20;40768:44;;40801:11;;-1:-1:-1::0;;;40801:11:0::1;;;;;;;;;;;40768:44;92004:1:::2;91982:19;:23;91978:57;;;92014:21;;-1:-1:-1::0;;;92014:21:0::2;;;;;;;;;;;91978:57;92075:1;92050:22;:26;92046:63;;;92085:24;;-1:-1:-1::0;;;92085:24:0::2;;;;;;;;;;;92046:63;92122:16;:38:::0;;;;92171:19:::2;:44:::0;92226:10:::2;:26:::0;38345:1;40614:21;;91794:466::o;73288:365::-;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;50000:11:::1;::::0;-1:-1:-1;;;50000:11:0;::::1;;;49995:40;;50020:15;;-1:-1:-1::0;;;50020:15:0::1;;;;;;;;;;;49995:40;40786:6:::2;::::0;-1:-1:-1;;;;;40786:6:0::2;40772:10;:20;40768:44;;40801:11;;-1:-1:-1::0;;;40801:11:0::2;;;;;;;;;;;40768:44;-1:-1:-1::0;;;;;73405:30:0;::::3;73401:59;;73444:16;;-1:-1:-1::0;;;73444:16:0::3;;;;;;;;;;;73401:59;73473:22;:41:::0;;-1:-1:-1;;;;;;73473:41:0::3;-1:-1:-1::0;;;;;73473:41:0;::::3;::::0;;::::3;::::0;;;73550:62:::3;::::0;;-1:-1:-1;;;73550:62:0;;;;:60:::3;::::0;:62:::3;::::0;;::::3;::::0;::::3;::::0;;;;;;;;;73473:41;73550:62:::3;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73531:15;::::0;-1:-1:-1;;;;;73531:15:0;;::::3;:81:::0;::::3;;73527:118;;73621:24;;-1:-1:-1::0;;;73621:24:0::3;;;;;;;;;;;73527:118;-1:-1:-1::0;38345:1:0;40614:21;;73288:365::o;85284:413::-;85459:15;;85336:7;;85408:48;69790:9;85408:15;:48;:::i;:::-;:66;85404:97;;;85483:18;;-1:-1:-1;;;85483:18:0;;;;;;;;;;;85404:97;85683:5;85655:15;;85637;:33;;;;:::i;:::-;85617:16;;:54;;;;:::i;:::-;85616:73;;;;:::i;:::-;85609:80;;85284:413;:::o;113010:1689::-;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;113127:19:::1;::::0;113106:18:::1;::::0;113088:36:::1;::::0;:15:::1;:36;:::i;:::-;:58;113084:99;;;113155:28;;-1:-1:-1::0;;;113155:28:0::1;;;;;;;;;;;113084:99;113196:25;113224:16;:14;:16::i;:::-;113196:44;;113276:13;;113255:17;:34;113251:71;;113298:24;;-1:-1:-1::0;;;113298:24:0::1;;;;;;;;;;;113251:71;113452:14;::::0;113434:47:::1;::::0;;-1:-1:-1;;;113434:47:0;;;;113412:19:::1;::::0;-1:-1:-1;;;;;113452:14:0::1;::::0;113434:45:::1;::::0;:47:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;113452:14;113434:47:::1;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;113412:69;;113492:21;113542:14;;;;;;;;;-1:-1:-1::0;;;;;113542:14:0::1;-1:-1:-1::0;;;;;113516:50:0::1;;:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;113492:76:::0;-1:-1:-1;113579:24:0::1;113639:21;113492:76:::0;113639:2:::1;:21;:::i;:::-;113623:11;113607:13;;:27;;;;:::i;:::-;113606:55;;;;:::i;:::-;113579:82;;113682:26;113711:17;:15;:17::i;:::-;113682:46:::0;-1:-1:-1;113739:27:0::1;113769:37;113790:16:::0;113682:46;113769:37:::1;:::i;:::-;113739:67;;113817:27;113892:3;113870:18;;113848:19;:40;;;;:::i;:::-;113847:48;;;;:::i;:::-;113920:24;:31:::0;113817:78;;-1:-1:-1;113908:9:0::1;113920:31:::0;113989:16:::1;::::0;::::1;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;113989:16:0::1;;113962:43;;114023:9;114018:379;114038:1;114034;:5;114018:379;;;114061:22;114151:3;114128:19;114087:24;114112:1;114087:27;;;;;;;;:::i;:::-;;;;;;;;;;;:38;;;:60;;;;:::i;:::-;114086:68;;;;:::i;:::-;114061:93;;114190:19;114173:14;:36;114169:109;;;114218:60;::::0;-1:-1:-1;;;114218:60:0;;::::1;::::0;::::1;5011:25:1::0;;;5052:18;;;5045:34;;;4984:18;;114218:60:0::1;;;;;;;;114169:109;114314:1;114297:14;:18;114293:48;;;114324:17;;-1:-1:-1::0;;;114324:17:0::1;;;;;;;;;;;114293:48;114371:14;114358:7;114366:1;114358:10;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;:27;-1:-1:-1;114041:3:0::1;;114018:379;;;-1:-1:-1::0;114430:15:0::1;114409:18;:36:::0;114464:13:::1;:33:::0;;;-1:-1:-1;114510:182:0::1;114530:1;114526;:5;114510:182;;;114605:15;::::0;114623:24:::1;:27:::0;;114553:127:::1;::::0;-1:-1:-1;;;;;114605:15:0::1;::::0;114623:24;114648:1;;114623:27;::::1;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;;:44:::0;114669:10;;-1:-1:-1;;;;;114623:44:0;;::::1;::::0;114669:7;;114677:1;;114669:10;::::1;;;;;:::i;:::-;;;;;;;114553:33;:127::i;:::-;114533:3;;114510:182;;;-1:-1:-1::0;;38345:1:0;40614:21;;-1:-1:-1;;;;;;;;113010:1689:0:o;116331:99::-;116379:7;116406:16;:14;:16::i;59869:73::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;59869:73:0;;;;-1:-1:-1;59869:73:0;:::o;107691:463::-;107927:28;;;;;;;13161:25:1;;;13202:18;;;13195:34;;;13245:18;;;;13238:34;;;107927:28:0;;;;;;;;;;13134:18:1;;;;107927:28:0;;107917:39;;;;;;;;;-1:-1:-1;107989:40:0;;;:26;:40;;;;;;:47;;108064:82;13161:25:1;13195:34;13238;-1:-1:-1;;;108064:31:0;:82::i;:::-;108047:99;;107883:271;107691:463;;;;;;:::o;86865:109::-;86922:7;86949:17;:15;:17::i;76579:1304::-;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;50000:11:::1;::::0;-1:-1:-1;;;50000:11:0;::::1;;;49995:40;;50020:15;;-1:-1:-1::0;;;50020:15:0::1;;;;;;;;;;;49995:40;62009:15:::2;::::0;-1:-1:-1;;;;;62009:15:0::2;61995:10;:29;::::0;::::2;::::0;61994:57:::2;;-1:-1:-1::0;62044:6:0::2;::::0;-1:-1:-1;;;;;62044:6:0::2;62030:10;:20;;61994:57;61990:91;;;62060:21;;-1:-1:-1::0;;;62060:21:0::2;;;;;;;;;;;61990:91;76799:1:::3;76783:13;:17;76779:45;;;76809:15;;-1:-1:-1::0;;;76809:15:0::3;;;;;;;;;;;76779:45;-1:-1:-1::0;;;;;76857:38:0;::::3;76837:17;76857:38:::0;;;:22:::3;:38;::::0;;;;;::::3;;::::0;76910:15;::::3;76906:51;;;76934:23;;-1:-1:-1::0;;;76934:23:0::3;;;;;;;;;;;76906:51;77105:15;::::0;77052:31:::3;::::0;-1:-1:-1;;;;;77087:33:0;;::::3;77105:15:::0;::::3;77087:33;77086:116;;77140:62;77172:14;77188:13;77140:31;:62::i;:::-;77086:116;;;77124:13;77086:116;77052:150;;77233:23;77215:14;;:41;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;;;77273:38:0::3;::::0;::::3;::::0;77269:607:::3;;77377:98;77428:14;77445;77461:13;77377:32;:98::i;:::-;77490:75;::::0;-1:-1:-1;;;77490:75:0;;-1:-1:-1;;;;;4750:32:1;;;77490:75:0::3;::::0;::::3;4732:51:1::0;4799:18;;;4792:34;;;77490:44:0;::::3;::::0;::::3;::::0;4705:18:1;;77490:75:0::3;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;77580:86;77631:14;77648;77664:1;77580:32;:86::i;:::-;77269:607;;;77765:99;77817:14;77834;77850:13;77765:33;:99::i;114904:1066::-:0;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;50000:11:::1;::::0;-1:-1:-1;;;50000:11:0;::::1;;;49995:40;;50020:15;;-1:-1:-1::0;;;50020:15:0::1;;;;;;;;;;;49995:40;40786:6:::2;::::0;-1:-1:-1;;;;;40786:6:0::2;40772:10;:20;40768:44;;40801:11;;-1:-1:-1::0;;;40801:11:0::2;;;;;;;;;;;40768:44;-1:-1:-1::0;;;;;115022:26:0;::::3;::::0;;115021:63:::3;;-1:-1:-1::0;;;;;;115054:29:0;::::3;115078:4;115054:29;115021:63;115017:93;;;115093:17;;-1:-1:-1::0;;;115093:17:0::3;;;;;;;;;;;115017:93;115199:14;:21:::0;;-1:-1:-1;;;;115231:24:0;-1:-1:-1;;;115231:24:0;;;115271:33:::3;::::0;-1:-1:-1;;;;;2433:32:1;;2415:51;;115271:33:0::3;::::0;2403:2:1;2388:18;115271:33:0::3;;;;;;;115378:22;::::0;115351:73:::3;::::0;;-1:-1:-1;;;115351:73:0;;;;115317:31:::3;::::0;-1:-1:-1;;;;;115378:22:0::3;::::0;115351:71:::3;::::0;:73:::3;::::0;;::::3;::::0;115317:31;;115351:73;;;;;;;115378:22;115351:73:::3;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;::::0;;::::3;-1:-1:-1::0;;115351:73:0::3;::::0;::::3;;::::0;::::3;::::0;;;::::3;::::0;::::3;:::i;:::-;115447:21:::0;;115511:15:::3;::::0;115493:59:::3;::::0;-1:-1:-1;;;115493:59:0;;115546:4:::3;115493:59;::::0;::::3;2415:51:1::0;115447:21:0;;-1:-1:-1;115447:21:0;;115435:9:::3;::::0;-1:-1:-1;;;;;115511:15:0::3;::::0;115493:44:::3;::::0;2388:18:1;;115493:59:0::3;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;115481:71:::0;-1:-1:-1;115567:5:0;;115563:97:::3;;115626:15;::::0;115574:86:::3;::::0;-1:-1:-1;;;;;115626:15:0::3;115644:12:::0;115658:1;115574:33:::3;:86::i;:::-;115673:17;115706:9:::0;115701:262:::3;115721:1;115717;:5;115701:262;;;115756:14;115771:1;115756:17;;;;;;;;:::i;:::-;;::::0;;::::3;::::0;;;;;;115792:53:::3;::::0;-1:-1:-1;;;115792:53:0;;115839:4:::3;115792:53;::::0;::::3;2415:51:1::0;115756:17:0;;-1:-1:-1;;;;;;115792:38:0;::::3;::::0;::::3;::::0;2388:18:1;;115792:53:0::3;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;115788:57:::0;-1:-1:-1;115864:5:0;;115860:91:::3;;115871:80;115923:9;115935:12;115949:1;115871:33;:80::i;:::-;115724:3;;115701:262;;79490:571:::0;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;50000:11:::1;::::0;-1:-1:-1;;;50000:11:0;::::1;;;49995:40;;50020:15;;-1:-1:-1::0;;;50020:15:0::1;;;;;;;;;;;49995:40;40786:6:::2;::::0;-1:-1:-1;;;;;40786:6:0::2;40772:10;:20;40768:44;;40801:11;;-1:-1:-1::0;;;40801:11:0::2;;;;;;;;;;;40768:44;79711:9:::3;79853:8;79758:118;;;;;;1190:25:1::0;;1178:2;1163:18;;1044:177;79758:118:0::3;;::::0;;-1:-1:-1;;79758:118:0;;::::3;::::0;;;;;;::::3;::::0;;::::3;::::0;;-1:-1:-1;;;;;79758:118:0::3;-1:-1:-1::0;;;79758:118:0::3;::::0;;79733:154;;::::3;::::0;79758:118;79733:154:::3;;:::i;:::-;;::::0;;-1:-1:-1;;79733:154:0;;::::3;::::0;;;;;;;79723:165;;79733:154:::3;79723:165:::0;;::::3;::::0;79901:16:::3;:27:::0;;;1190:25:1;;;79723:165:0;-1:-1:-1;79944:33:0::3;::::0;1163:18:1;79944:33:0::3;1044:177:1::0;67042:369:0;50000:11;;-1:-1:-1;;;50000:11:0;;;;49995:40;;50020:15;;-1:-1:-1;;;50020:15:0;;;;;;;;;;;49995:40;67164:115:::1;::::0;67254:10:::1;67164:115;::::0;::::1;2415:51:1::0;67117:9:0::1;::::0;2388:18:1;;67164:115:0::1;::::0;;-1:-1:-1;;67164:115:0;;::::1;::::0;;;;;;::::1;::::0;;::::1;::::0;;-1:-1:-1;;;;;67164:115:0::1;-1:-1:-1::0;;;67164:115:0::1;::::0;;67139:151;;::::1;::::0;67164:115;67139:151:::1;;:::i;:::-;;;;;;;;;;;;;67129:162;;;;;;67117:174;;67304:23;:21;:23::i;:::-;67369:22;::::0;67340:63:::1;::::0;-1:-1:-1;;;67340:63:0;;::::1;::::0;::::1;1190:25:1::0;;;-1:-1:-1;;;;;67369:22:0;;::::1;::::0;67340:60:::1;::::0;1163:18:1;;67340:63:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;67106:305;67042:369::o:0;63022:316::-;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;50000:11:::1;::::0;-1:-1:-1;;;50000:11:0;::::1;;;49995:40;;50020:15;;-1:-1:-1::0;;;50020:15:0::1;;;;;;;;;;;49995:40;40786:6:::2;::::0;-1:-1:-1;;;;;40786:6:0::2;40772:10;:20;40768:44;;40801:11;;-1:-1:-1::0;;;40801:11:0::2;;;;;;;;;;;40768:44;63160:14:::3;:31:::0;;-1:-1:-1;;;;63202:37:0;-1:-1:-1;;;63160:31:0;::::3;;::::0;::::3;-1:-1:-1::0;;;;63202:37:0;;;;;-1:-1:-1;;;63202:37:0;::::3;;::::0;::::3;::::0;;;::::3;::::0;;;;63265:65:::3;::::0;;63160:31:::3;63296:14:::0;;::::3;::::0;::::3;18159::1::0;18152:22;18134:41;;63312:17:0;;;::::3;::::0;;::::3;18218:14:1::0;18211:22;18206:2;18191:18;;18184:50;63265:65:0::3;::::0;18107:18:1;63265:65:0::3;;;;;;;;-1:-1:-1::0;;38345:1:0;40614:21;;63022:316::o;59745:62::-;;;;;;;;;;;;75619:580;75934:14;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;50000:11:::1;::::0;-1:-1:-1;;;50000:11:0;::::1;;;49995:40;;50020:15;;-1:-1:-1::0;;;50020:15:0::1;;;;;;;;;;;49995:40;72893:14:::2;::::0;-1:-1:-1;;;72893:14:0;::::2;;;72889:43;;;72916:16;;-1:-1:-1::0;;;72916:16:0::2;;;;;;;;;;;72889:43;62285:6:::3;::::0;-1:-1:-1;;;;;62285:6:0::3;62271:10;:20;::::0;::::3;::::0;62270:71:::3;;-1:-1:-1::0;62325:15:0::3;::::0;-1:-1:-1;;;;;62325:15:0::3;62311:10;:29;;62270:71;:128;;;;-1:-1:-1::0;62360:23:0::3;::::0;-1:-1:-1;;;;;62360:23:0::3;:37:::0;::::3;62270:128;:217;;;;-1:-1:-1::0;62436:23:0::3;::::0;62418:68:::3;::::0;-1:-1:-1;;;62418:68:0;;62475:10:::3;62418:68;::::0;::::3;2415:51:1::0;-1:-1:-1;;;;;62436:23:0;;::::3;::::0;62418:56:::3;::::0;2388:18:1;;62418:68:0::3;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62417:69;62270:217;62252:276;;;62506:22;;-1:-1:-1::0;;;62506:22:0::3;;;;;;;;;;;62252:276;72646:15:::4;::::0;75916:7;;-1:-1:-1;;;;;72633:28:0;;::::4;72646:15:::0;::::4;72633:28;::::0;::::4;::::0;72632:112:::4;;-1:-1:-1::0;72695:22:0::4;::::0;72668:75:::4;::::0;-1:-1:-1;;;72668:75:0;;-1:-1:-1;;;;;2433:32:1;;;72668:75:0::4;::::0;::::4;2415:51:1::0;72695:22:0;;::::4;::::0;72668:64:::4;::::0;2388:18:1;;72668:75:0::4;;;;;;;;;;;;;;;;;::::0;::::4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72667:76;72632:112;72628:146;;;72753:21;;-1:-1:-1::0;;;72753:21:0::4;;;;;;;;;;;72628:146;75970:47:::5;75985:7;75994:8;76004:12;75970:14;:47::i;:::-;76030:95;::::0;-1:-1:-1;;;76030:95:0;;76070:10:::5;76030:95;::::0;::::5;18556:51:1::0;76090:4:0::5;18623:18:1::0;;;18616:60;18692:18;;;18685:34;;;18735:18;;;18728:34;;;18811:4;18799:17;;18778:19;;;18771:46;18833:19;;;18826:35;;;18877:19;;;18870:35;;;75961:56:0;;-1:-1:-1;;;;;;76030:39:0;::::5;::::0;::::5;::::0;18528:19:1;;76030:95:0::5;;;;;;;;;;;;;;;;;::::0;::::5;;;;;;;;;;;;::::0;::::5;;;;;;;;;76138:53;76151:7;76160:8;76170:12;76184:6;76138:12;:53::i;:::-;-1:-1:-1::0;38345:1:0;40614:21;;75619:580;;-1:-1:-1;;;;;;;75619:580:0:o;91194:227::-;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;;;40786:6;-1:-1:-1;;;;;40786:6:0::1;40772:10;:20;40768:44;;40801:11;;-1:-1:-1::0;;;40801:11:0::1;;;;;;;;;;;40768:44;91339:20:::2;:31:::0;;;;91381:14:::2;:32:::0;;-1:-1:-1;;91381:32:0::2;::::0;::::2;;::::0;;;::::2;::::0;;-1:-1:-1;40614:21:0;;91194:227::o;96323:2208::-;96544:7;96563;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;50000:11:::1;::::0;-1:-1:-1;;;50000:11:0;::::1;;;49995:40;;50020:15;;-1:-1:-1::0;;;50020:15:0::1;;;;;;;;;;;49995:40;90717:17:::2;::::0;-1:-1:-1;;;90717:17:0;::::2;;;90713:49;;;90743:19;;-1:-1:-1::0;;;90743:19:0::2;;;;;;;;;;;90713:49;62285:6:::3;::::0;-1:-1:-1;;;;;62285:6:0::3;62271:10;:20;::::0;::::3;::::0;62270:71:::3;;-1:-1:-1::0;62325:15:0::3;::::0;-1:-1:-1;;;;;62325:15:0::3;62311:10;:29;;62270:71;:128;;;;-1:-1:-1::0;62360:23:0::3;::::0;-1:-1:-1;;;;;62360:23:0::3;:37:::0;::::3;62270:128;:217;;;;-1:-1:-1::0;62436:23:0::3;::::0;62418:68:::3;::::0;-1:-1:-1;;;62418:68:0;;62475:10:::3;62418:68;::::0;::::3;2415:51:1::0;-1:-1:-1;;;;;62436:23:0;;::::3;::::0;62418:56:::3;::::0;2388:18:1;;62418:68:0::3;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62417:69;62270:217;62252:276;;;62506:22;;-1:-1:-1::0;;;62506:22:0::3;;;;;;;;;;;62252:276;96622:28:::4;::::0;;::::4;::::0;::::4;13161:25:1::0;;;13202:18;;;13195:34;;;13245:18;;;13238:34;;;96589:20:0::4;::::0;13134:18:1;;96622:28:0::4;::::0;;-1:-1:-1;;96622:28:0;;::::4;::::0;;;;;;96612:39;;96622:28:::4;96612:39:::0;;::::4;::::0;96738:14:::4;96755:30:::0;;;:16:::4;:30:::0;;;;;-1:-1:-1;;;;;96755:44:0;::::4;::::0;;;;;;;;96612:39;;-1:-1:-1;96823:1:0::4;96814:10:::0;::::4;96810:44;;;96833:21;;-1:-1:-1::0;;;96833:21:0::4;;;;;;;;;;;96810:44;97033:1;97019:11;;:15;97018:57;;;;-1:-1:-1::0;97068:6:0::4;::::0;-1:-1:-1;;;;;97068:6:0::4;97054:10;:20;;97018:57;:106;;;;-1:-1:-1::0;97108:15:0::4;::::0;-1:-1:-1;;;;;97108:15:0::4;97094:10;:29;;97018:106;:259;;;;-1:-1:-1::0;97194:82:0::4;97226:4:::0;97232:5;97239:3;87528:1:::4;::::0;;97194:31:::4;:82::i;:::-;97143:48;69790:9;97143:15;:48;:::i;:::-;:133;97018:259;97000:333;;;97311:10;;-1:-1:-1::0;;;97311:10:0::4;;;;;;;;;;;97000:333;97385:20;97407:22:::0;97433:41:::4;97452:6;97460:13;;97433:18;:41::i;:::-;97384:90:::0;;-1:-1:-1;97384:90:0;-1:-1:-1;97527:21:0::4;97551:29;97384:90:::0;;97551:29:::4;:::i;:::-;97685:1;97638:30:::0;;;:16:::4;:30;::::0;;;;;;;-1:-1:-1;;;;;97638:44:0;::::4;::::0;;;;;;;:48;;;97768:31;;;:17:::4;:31:::0;;;;;:41;;97527:53;;-1:-1:-1;97803:6:0;;97768:31;;97685:1;97768:41:::4;::::0;97803:6;;97768:41:::4;:::i;:::-;;;;;;;;97845:6;97820:21;;:31;;;;;;;:::i;:::-;;;;;;;;97886:13;97862:20;;:37;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;97912:43:0::4;::::0;-1:-1:-1;97928:12:0;97942;97912:15:::4;:43::i;:::-;98009:12;-1:-1:-1::0;;;;;97973:49:0::4;;97993:14;97973:49;;;;1190:25:1::0;;1178:2;1163:18;;1044:177;97973:49:0::4;;;;;;;;98235:14;::::0;98217:61:::4;::::0;-1:-1:-1;;;98217:61:0;;98264:4:::4;98217:61;::::0;::::4;4732:51:1::0;4799:18;;;4792:34;;;-1:-1:-1;;;;;98235:14:0;;::::4;::::0;98217:38:::4;::::0;4705:18:1;;98217:61:0::4;;;;;;;;;;;;;;;;;::::0;::::4;;;;;;;;;;;;::::0;::::4;;;;;-1:-1:-1::0;;98432:15:0::4;::::0;98380:99:::4;::::0;-1:-1:-1;;;;;;98432:15:0::4;::::0;-1:-1:-1;98450:12:0;98464:14;98380:33:::4;:99::i;:::-;-1:-1:-1::0;38345:1:0;40614:21;;98500:6;;;;-1:-1:-1;96323:2208:0;;-1:-1:-1;;;;;;;96323:2208:0:o;104762:353::-;104879:20;104911:22;104952:31;104987:9;104986:50;;105023:13;;104986:50;;;105000:20;;104986:50;104952:84;;105056:51;105075:6;105083:23;105056:18;:51::i;:::-;105049:58;;;;;104762:353;;;;;:::o;84196:281::-;84364:22;;84404:14;;84454;;84337:132;;-1:-1:-1;;;84337:132:0;;-1:-1:-1;;;;;84404:14:0;;;84337:132;;;19175:51:1;19262:32;;;19242:18;;;19235:60;84437:4:0;19311:18:1;;;19304:60;19380:18;;;19373:34;;;19423:19;;;19416:35;;;;84301:7:0;;;;84364:22;;84337:66;;19147:19:1;;84337:132:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;84330:139;;;;84196:281;;;;;:::o;106990:321::-;107212:28;;;;;;;13161:25:1;;;13202:18;;;13195:34;;;13245:18;;;;13238:34;;;107212:28:0;;;;;;;;;;13134:18:1;;;;107212:28:0;;107202:39;;;;;;;;;-1:-1:-1;107259:30:0;;;:16;:30;;;;;-1:-1:-1;;;;;107259:44:0;;;;;;;;;106990:321;;;;;;;:::o;64661:167::-;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;;;40786:6;-1:-1:-1;;;;;40786:6:0::1;40772:10;:20;40768:44;;40801:11;;-1:-1:-1::0;;;40801:11:0::1;;;;;;;;;;;40768:44;-1:-1:-1::0;;;;;64752:28:0;::::2;;::::0;;;:22:::2;:28;::::0;;;;;;;;64745:35;;-1:-1:-1;;64745:35:0::2;::::0;;64796:24;;2415:51:1;;;64796:24:0::2;::::0;2388:18:1;64796:24:0::2;;;;;;;;-1:-1:-1::0;38345:1:0;40614:21;;64661:167::o;109375:172::-;45932:19;45955:13;;;;;;45954:14;;46002:34;;;;-1:-1:-1;46020:12:0;;46035:1;46020:12;;;;:16;46002:34;46001:108;;;-1:-1:-1;46081:4:0;1858:19;:23;;;46042:66;;-1:-1:-1;46091:12:0;;;;;:17;46042:66;45979:204;;;;-1:-1:-1;;;45979:204:0;;20012:2:1;45979:204:0;;;19994:21:1;20051:2;20031:18;;;20024:30;20090:34;20070:18;;;20063:62;-1:-1:-1;;;20141:18:1;;;20134:44;20195:19;;45979:204:0;19810:410:1;45979:204:0;46194:12;:16;;-1:-1:-1;;46194:16:0;46209:1;46194:16;;;46221:67;;;;46256:13;:20;;-1:-1:-1;;46256:20:0;;;;;46221:67;109454:14:::1;:21:::0;;-1:-1:-1;;;;109486:24:0;-1:-1:-1;;;109486:24:0;;;109521:6:::1;:18:::0;;-1:-1:-1;;;;;;109521:18:0::1;-1:-1:-1::0;;;;;109521:18:0;::::1;;::::0;;46310:102;;;;46361:5;46345:21;;-1:-1:-1;;46345:21:0;;;46386:14;;-1:-1:-1;8220:36:1;;46386:14:0;;8208:2:1;8193:18;46386:14:0;;;;;;;46310:102;45921:498;109375:172;:::o;81539:1024::-;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;50000:11:::1;::::0;-1:-1:-1;;;50000:11:0;::::1;;;49995:40;;50020:15;;-1:-1:-1::0;;;50020:15:0::1;;;;;;;;;;;49995:40;81628:13:::2;:20:::0;81667:1:::2;81663:5:::0;::::2;81659:40;;;81677:22;;-1:-1:-1::0;;;81677:22:0::2;;;;;;;;;;;81659:40;81724:20;::::0;81761:5;;81757:799:::2;;81783:24;81824:1;81810:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;81810:16:0::2;;81783:43;;81848:9;81843:436;81863:1;81859;:5;81843:436;;;81890:22;81951:3;81946:1;81916:13;81930:1;81916:16;;;;;;;;:::i;:::-;;;;;;;;;;;:27;;;:31;;;;:::i;:::-;81915:39;;;;:::i;:::-;81890:64;;82068:20;;82051:14;:37;82047:111;;;82137:20;::::0;82097:61:::2;::::0;-1:-1:-1;;;82097:61:0;;::::2;::::0;82121:14;;82097:61:::2;;5011:25:1::0;;;5067:2;5052:18;;5045:34;4999:2;4984:18;;4837:248;82047:111:0::2;82192:14;82179:7;82187:1;82179:10;;;;;;;;:::i;:::-;;;;;;:27;;;::::0;::::2;82249:14;82225:20;;:38;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;;81866:3:0::2;;81843:436;;;-1:-1:-1::0;82300:15:0::2;::::0;::::2;::::0;;;::::2;82371:9;82366:179;82386:1;82382;:5;82366:179;;;82465:15;::::0;82483:13:::2;:16:::0;;82413:116:::2;::::0;-1:-1:-1;;;;;82465:15:0::2;::::0;82483:13;82497:1;;82483:16;::::2;;;;;:::i;82413:116::-;82389:3;;82366:179;;;;81768:788;81757:799;-1:-1:-1::0;;38345:1:0;40614:21;;81539:1024::o;63685:221::-;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;50000:11:::1;::::0;-1:-1:-1;;;50000:11:0;::::1;;;49995:40;;50020:15;;-1:-1:-1::0;;;50020:15:0::1;;;;;;;;;;;49995:40;40786:6:::2;::::0;-1:-1:-1;;;;;40786:6:0::2;40772:10;:20;40768:44;;40801:11;;-1:-1:-1::0;;;40801:11:0::2;;;;;;;;;;;40768:44;63799:23:::3;:42:::0;;-1:-1:-1;;;;;;63799:42:0::3;-1:-1:-1::0;;;;;63799:42:0;::::3;::::0;;::::3;::::0;;;63857:41:::3;::::0;2415:51:1;;;63857:41:0::3;::::0;2403:2:1;2388:18;63857:41:0::3;2269:203:1::0;105408:403:0;105471:12;105495:13;105520:11;105542:22;105604:89;105681:11;;69790:9;105630:15;:48;;;;:::i;105604:89::-;105583:110;;-1:-1:-1;105583:110:0;-1:-1:-1;105583:110:0;-1:-1:-1;105721:82:0;105583:110;;;87528:1;;;105721:31;:82::i;:::-;105704:99;;105408:403;;;;:::o;109661:2125::-;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;;;40786:6;-1:-1:-1;;;;;40786:6:0::1;40772:10;:20;40768:44;;40801:11;;-1:-1:-1::0;;;40801:11:0::1;;;;;;;;;;;40768:44;50165:11:::2;::::0;-1:-1:-1;;;50165:11:0;::::2;;;50161:43;;;50185:19;;-1:-1:-1::0;;;50185:19:0::2;;;;;;;;;;;50161:43;109835:5:::3;109803:9;:21;;;:38;109799:71;;;109850:20;;-1:-1:-1::0;;;109850:20:0::3;;;;;;;;;;;109799:71;109948:29;::::0;::::3;::::0;109926:19:::3;:51:::0;110007:26;;109988:16:::3;:45:::0;;;110066:29:::3;::::0;::::3;::::0;110044:19:::3;:51:::0;110106:10:::3;:39:::0;110179:30:::3;::::0;;::::3;::::0;110156:20:::3;:53:::0;110234:21:::3;::::0;::::3;::::0;110220:11:::3;:35:::0;110282:23:::3;::::0;::::3;::::0;110266:13:::3;:39:::0;110335:26:::3;::::0;::::3;::::0;110316:16:::3;:45:::0;110395:30:::3;::::0;::::3;::::0;110372:20:::3;:53:::0;110457:28:::3;::::0;::::3;::::0;110436:18:::3;:49:::0;110514:25:::3;::::0;::::3;::::0;110496:15:::3;:43:::0;;110575:32:::3;::::0;::::3;::::0;110550:22:::3;:57:::0;;-1:-1:-1;;;;;;110550:57:0;;::::3;-1:-1:-1::0;;;;;110550:57:0;;::::3;;::::0;;;110635:24:::3;::::0;::::3;::::0;110618:14:::3;:41:::0;;;::::3;::::0;;::::3;::::0;;;::::3;::::0;;110688:24:::3;::::0;::::3;::::0;110670:15:::3;:42:::0;;;::::3;::::0;;::::3;::::0;;;::::3;::::0;;110741:15:::3;-1:-1:-1::0;110723:33:0;;;-1:-1:-1;110767:31:0;;;110834:32:::3;::::0;::::3;::::0;110809:22:::3;:57:::0;;;::::3;::::0;;::::3;::::0;;;::::3;::::0;;110903:33:::3;::::0;::::3;::::0;-1:-1:-1;110877:59:0;;;::::3;::::0;;::::3;::::0;;;::::3;::::0;;110496:43;;::::3;-1:-1:-1::0;;;;;;110980:25:0;;;;;;;;;;111016:18:::3;:36:::0;;;;111072:28:::3;::::0;::::3;::::0;-1:-1:-1;111063:37:0;;;;::::3;::::0;::::3;;::::0;;-1:-1:-1;111157:18:0;;-1:-1:-1;;;;;;;111157:18:0;;::::3;;::::0;;111193:20;::::3;::::0;-1:-1:-1;;111193:20:0::3;111314:22;;;;;;;;;-1:-1:-1::0;;;;;111314:22:0::3;-1:-1:-1::0;;;;;111287:66:0::3;;:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;111268:15;::::0;-1:-1:-1;;;;;111268:15:0;;::::3;:87:::0;::::3;;111264:124;;111364:24;;-1:-1:-1::0;;;111364:24:0::3;;;;;;;;;;;111264:124;111486:14;;;;;;;;;-1:-1:-1::0;;;;;111486:14:0::3;-1:-1:-1::0;;;;;111460:50:0::3;;:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;111403:109;;111429:15;;;;;;;;;-1:-1:-1::0;;;;;111429:15:0::3;-1:-1:-1::0;;;;;111403:51:0::3;;:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:109;;;111399:145;;111521:23;;-1:-1:-1::0;;;111521:23:0::3;;;;;;;;;;;111399:145;111611:14;::::0;111585:52:::3;::::0;;-1:-1:-1;;;111585:52:0;;;;111557:14:::3;::::0;-1:-1:-1;;;;;111611:14:0::3;::::0;111585:50:::3;::::0;:52:::3;::::0;;::::3;::::0;::::3;::::0;;;;;;;;111611:14;111585:52:::3;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;111579:58;::::0;:2:::3;:58;:::i;:::-;111574:64;::::0;:1:::3;:64;:::i;:::-;111557:81;;111649:25;111677:55;111694:6;111702:29;111677:16;:55::i;:::-;111745:13;:33:::0;-1:-1:-1;;38345:1:0;40614:21;;-1:-1:-1;109661:2125:0:o;80946:452::-;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;50000:11:::1;::::0;-1:-1:-1;;;50000:11:0;::::1;;;49995:40;;50020:15;;-1:-1:-1::0;;;50020:15:0::1;;;;;;;;;;;49995:40;81031:25:::2;81059:17;:15;:17::i;:::-;81031:45;;81087:31;81222:3;69900:18;81184:13;;81166:15;:31;;;;:::i;:::-;81142:20;::::0;81122:40:::2;::::0;:17;:40:::2;:::i;:::-;:76;;;;:::i;:::-;81121:98;;;;:::i;:::-;:104;;;;:::i;:::-;81087:138;;81254:15;81238:13;:31;;;;81304:23;81280:20;;:47;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;81345:45:0::2;::::0;1190:25:1;;;81345:45:0::2;::::0;1178:2:1;1163:18;81345:45:0::2;1044:177:1::0;68293:140:0;68344:48;68412:13;68405:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;68405:20:0;;;;;;;;;;;;;;;;;;;;;;112760:128;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;;;40786:6;-1:-1:-1;;;;;40786:6:0::1;40772:10;:20;40768:44;;40801:11;;-1:-1:-1::0;;;40801:11:0::1;;;;;;;;;;;40768:44;112851:18:::2;:29:::0;38345:1;40614:21;;112760:128::o;66760:160::-;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;50000:11:::1;::::0;-1:-1:-1;;;50000:11:0;::::1;;;49995:40;;50020:15;;-1:-1:-1::0;;;50020:15:0::1;;;;;;;;;;;49995:40;40786:6:::2;::::0;-1:-1:-1;;;;;40786:6:0::2;40772:10;:20;40768:44;;40801:11;;-1:-1:-1::0;;;40801:11:0::2;;;;;;;;;;;40768:44;66876:36:::3;66903:8;66876:26;:36::i;99094:2918::-:0;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;50000:11:::1;::::0;-1:-1:-1;;;50000:11:0;::::1;;;49995:40;;50020:15;;-1:-1:-1::0;;;50020:15:0::1;;;;;;;;;;;49995:40;90717:17:::2;::::0;-1:-1:-1;;;90717:17:0;::::2;;;90713:49;;;90743:19;;-1:-1:-1::0;;;90743:19:0::2;;;;;;;;;;;90713:49;99315:1:::3;99304:8;:12;99300:40;;;99325:15;;-1:-1:-1::0;;;99325:15:0::3;;;;;;;;;;;99300:40;99386:28;::::0;;::::3;::::0;::::3;13161:25:1::0;;;13202:18;;;13195:34;;;13245:18;;;13238:34;;;99353:20:0::3;::::0;13134:18:1;;99386:28:0::3;;;;;;;;;;;;99376:39;;;;;;99353:62;;99525:1;99491:17;:31;99509:12;99491:31;;;;;;;;;;;;:35;99487:66;;;99535:18;;-1:-1:-1::0;;;99535:18:0::3;;;;;;;;;;;99487:66;99747:1;99733:11;;:15;99732:57;;;;-1:-1:-1::0;99782:6:0::3;::::0;-1:-1:-1;;;;;99782:6:0::3;99768:10;:20;;99732:57;:106;;;;-1:-1:-1::0;99822:15:0::3;::::0;-1:-1:-1;;;;;99822:15:0::3;99808:10;:29;;99732:106;:311;;;;-1:-1:-1::0;99960:82:0::3;99992:4:::0;99998:5;100005:3;87528:1:::3;::::0;;99960:31:::3;:82::i;:::-;99909:48;69790:9;99909:15;:48;:::i;:::-;:133;99732:311;99714:385;;;100077:10;;-1:-1:-1::0;;;100077:10:0::3;;;;;;;;;;;99714:385;100209:16;100229:40:::0;;;:26:::3;:40;::::0;;;;:47;:58;-1:-1:-1;100228:121:0::3;;100302:40;::::0;;;:26:::3;:40;::::0;;;;:47;100228:121:::3;;;100291:8;100228:121;100360:19;100382:40:::0;;;:26:::3;:40;::::0;;;;:47;100209:140;;-1:-1:-1;100209:140:0;100471:23:::3;::::0;::::3;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;100471:23:0::3;;100442:52;;100505:24;100546:8;100532:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;100532:23:0::3;-1:-1:-1::0;100505:50:0;-1:-1:-1;100566:20:0::3;::::0;;;100705:8;100743:11;100726:877:::3;100761:22;100775:8:::0;100761:11;:22:::3;:::i;:::-;100756:1;:28;100726:877;;;100821:40;::::0;;;:26:::3;:40;::::0;;;;100862:5:::3;100866:1;100862::::0;:5:::3;:::i;:::-;100821:47;;;;;;;;:::i;:::-;;::::0;;;::::3;::::0;;;::::3;::::0;-1:-1:-1;;;;;100821:47:0::3;::::0;-1:-1:-1;100883:3:0;::::3;::::0;::::3;:::i;:::-;;;;100916:12;100901:9;100911:1;100901:12;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;100901:27:0;;::::3;:12;::::0;;::::3;::::0;;;;;;:27;;;;100959:30:::3;::::0;;;:16:::3;:30:::0;;;;;;:44;;::::3;::::0;;;;;;;;100943:60:::3;::::0;;::::3;:::i;:::-;101157:30;::::0;;;:16:::3;:30;::::0;;;;;;;-1:-1:-1;;;;;101157:44:0;::::3;::::0;;;;;;;;101203:13:::3;::::0;100943:60;;-1:-1:-1;101138:79:0::3;::::0;:18:::3;:79::i;:::-;101239:49;::::0;1190:25:1;;;101105:112:0;;-1:-1:-1;101105:112:0;-1:-1:-1;;;;;;101239:49:0;::::3;::::0;::::3;::::0;1178:2:1;1163:18;101239:49:0::3;;;;;;;101318:14;101305:7;101313:1;101305:10;;;;;;;;:::i;:::-;;::::0;;::::3;::::0;;;;;:27;101372:29:::3;101387:14:::0;101372:12;:29:::3;:::i;:::-;101347:20;;:55;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;101466:1:0::3;101419:30:::0;;;:16:::3;:30;::::0;;;;;;;-1:-1:-1;;;;;101419:44:0;::::3;::::0;;;;;;;:48;;;101482:40;;;:26:::3;:40:::0;;;;;:46;;;::::3;;;;:::i;:::-;;::::0;;;::::3;::::0;;;;;-1:-1:-1;;101482:46:0;;;;;-1:-1:-1;;;;;;101482:46:0::3;::::0;;;;;;;;101543:30;;;:16:::3;:30:::0;;;;;;-1:-1:-1;;;;;101543:44:0;::::3;::::0;;;;;;;:48;100786:3;::::3;::::0;::::3;:::i;:::-;;;;100726:877;;;;101640:12;101615:21;;:37;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;101663:31:0::3;::::0;;;:17:::3;:31;::::0;;;;:47;;101698:12;;101663:31;:47:::3;::::0;101698:12;;101663:47:::3;:::i;:::-;::::0;;;-1:-1:-1;;101741:14:0::3;::::0;101723:67:::3;::::0;-1:-1:-1;;;101723:67:0;;101770:4:::3;101723:67;::::0;::::3;4732:51:1::0;4799:18;;;4792:34;;;-1:-1:-1;;;;;101741:14:0;;::::3;::::0;101723:38:::3;::::0;4705:18:1;;101723:67:0::3;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;101845:9;101840:165;101860:9;:16;101856:1;:20;101840:165;;;101950:15;::::0;101968:12;;101898:95:::3;::::0;-1:-1:-1;;;;;101950:15:0::3;::::0;101968:9;;101978:1;;101968:12;::::3;;;;;:::i;:::-;;;;;;;101982:7;101990:1;101982:10;;;;;;;;:::i;101898:95::-;101878:3;;101840:165;;;-1:-1:-1::0;;38345:1:0;40614:21;;-1:-1:-1;;;;;;;;;;;;;99094:2918:0:o;74688:377::-;74908:14;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;50000:11:::1;::::0;-1:-1:-1;;;50000:11:0;::::1;;;49995:40;;50020:15;;-1:-1:-1::0;;;50020:15:0::1;;;;;;;;;;;49995:40;72893:14:::2;::::0;-1:-1:-1;;;72893:14:0;::::2;;;72889:43;;;72916:16;;-1:-1:-1::0;;;72916:16:0::2;;;;;;;;;;;72889:43;62285:6:::3;::::0;-1:-1:-1;;;;;62285:6:0::3;62271:10;:20;::::0;::::3;::::0;62270:71:::3;;-1:-1:-1::0;62325:15:0::3;::::0;-1:-1:-1;;;;;62325:15:0::3;62311:10;:29;;62270:71;:128;;;;-1:-1:-1::0;62360:23:0::3;::::0;-1:-1:-1;;;;;62360:23:0::3;:37:::0;::::3;62270:128;:217;;;;-1:-1:-1::0;62436:23:0::3;::::0;62418:68:::3;::::0;-1:-1:-1;;;62418:68:0;;62475:10:::3;62418:68;::::0;::::3;2415:51:1::0;-1:-1:-1;;;;;62436:23:0;;::::3;::::0;62418:56:::3;::::0;2388:18:1;;62418:68:0::3;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62417:69;62270:217;62252:276;;;62506:22;;-1:-1:-1::0;;;62506:22:0::3;;;;;;;;;;;62252:276;72646:15:::4;::::0;74890:7;;-1:-1:-1;;;;;72633:28:0;;::::4;72646:15:::0;::::4;72633:28;::::0;::::4;::::0;72632:112:::4;;-1:-1:-1::0;72695:22:0::4;::::0;72668:75:::4;::::0;-1:-1:-1;;;72668:75:0;;-1:-1:-1;;;;;2433:32:1;;;72668:75:0::4;::::0;::::4;2415:51:1::0;72695:22:0;;::::4;::::0;72668:64:::4;::::0;2388:18:1;;72668:75:0::4;;;;;;;;;;;;;;;;;::::0;::::4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72667:76;72632:112;72628:146;;;72753:21;;-1:-1:-1::0;;;72753:21:0::4;;;;;;;;;;;72628:146;74944:47:::5;74959:7;74968:8;74978:12;74944:14;:47::i;:::-;74935:56;;75004:53;75017:7;75026:8;75036:12;75050:6;75004:12;:53::i;:::-;-1:-1:-1::0;38345:1:0;40614:21;;74688:377;;-1:-1:-1;;;74688:377:0:o;64110:429::-;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;;;40786:6;-1:-1:-1;;;;;40786:6:0::1;40772:10;:20;40768:44;;40801:11;;-1:-1:-1::0;;;40801:11:0::1;;;;;;;;;;;40768:44;-1:-1:-1::0;;;;;64242:18:0;::::2;::::0;;64241:47:::2;;-1:-1:-1::0;;;;;;64266:21:0;::::2;64282:4;64266:21;64241:47;64237:76;;;64297:16;;-1:-1:-1::0;;;64297:16:0::2;;;;;;;;;;;64237:76;64329:38;::::0;::::2;59442:1;64329:38;::::0;::::2;::::0;64328:80:::2;;-1:-1:-1::0;64373:34:0::2;::::0;::::2;59496:1;64373:34;;64328:80;64324:113;;;64417:20;;-1:-1:-1::0;;;64417:20:0::2;;;;;;;;;;;64324:113;-1:-1:-1::0;;;;;64450:28:0;::::2;;::::0;;;:22:::2;:28;::::0;;;;;;;;:42;;-1:-1:-1;;64450:42:0::2;;::::0;::::2;;::::0;;64508:23;;2415:51:1;;;64508:23:0::2;::::0;2388:18:1;64508:23:0::2;2269:203:1::0;103873:546:0;103988:20;104020:22;104076:55;104093:6;104101:29;104076:16;:55::i;:::-;104061:70;-1:-1:-1;104061:70:0;;-1:-1:-1;104182:21:0;104224:7;;104220:142;;104287:3;104265:18;104271:12;104265:3;:18;:::i;:::-;104264:26;;;;:::i;:::-;104248:42;-1:-1:-1;104322:28:0;104248:42;104322:12;:28;:::i;:::-;104305:45;;104220:142;104374:37;103873:546;;;;;:::o;10171:175::-;10231:12;;;10305:33;10317:20;9858:12;10317:2;:20;:::i;:::-;10305:11;:33::i;:::-;10284:54;;;;-1:-1:-1;10284:54:0;;-1:-1:-1;10171:175:0;-1:-1:-1;;10171:175:0:o;10826:306::-;10968:17;11118:6;11088:27;10067:2;11088:6;:27;:::i;:::-;11062:23;9963:7;11062:4;:23;:::i;:::-;9858:12;11010:31;11024:4;11030:5;11037:3;11010:13;:31::i;:::-;:49;;;;:::i;:::-;:75;;;;:::i;:::-;:105;;;;:::i;:::-;:114;;;;:::i;:::-;10998:126;10826:306;-1:-1:-1;;;;;;;10826:306:0:o;53238:216::-;53377:68;;-1:-1:-1;;;;;20917:32:1;;;53377:68:0;;;20899:51:1;20986:32;;20966:18;;;20959:60;21035:18;;;21028:34;;;53350:96:0;;53370:5;;-1:-1:-1;;;53400:27:0;20872:18:1;;53377:68:0;;;;-1:-1:-1;;53377:68:0;;;;;;;;;;;;;;-1:-1:-1;;;;;53377:68:0;-1:-1:-1;;;;;;53377:68:0;;;;;;;;;;53350:19;:96::i;:::-;53238:216;;;;:::o;85705:294::-;85905:22;;85878:113;;-1:-1:-1;;;85878:113:0;;-1:-1:-1;;;;;4750:32:1;;;85878:113:0;;;4732:51:1;4799:18;;;4792:34;;;85851:7:0;;85905:22;;85878:81;;4705:18:1;;85878:113:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;85871:120;85705:294;-1:-1:-1;;;85705:294:0:o;102020:1081::-;102155:20;102177:22;102249:31;102284:9;102283:50;;102320:13;;102283:50;;;102297:20;;102283:50;102249:84;;102377:51;102396:6;102404:23;102377:18;:51::i;:::-;102460:19;;102344:84;;-1:-1:-1;102344:84:0;-1:-1:-1;102445:34:0;;102441:71;;;102488:24;;-1:-1:-1;;;102488:24:0;;;;;;;;;;;102441:71;102544:1;102527:14;:18;102523:45;;;102554:14;;-1:-1:-1;;;102554:14:0;;;;;;;;;;;102523:45;102586:14;;;;102581:76;;102627:29;102642:14;102627:12;:29;:::i;:::-;102602:20;;:55;;;;;;;:::i;:::-;;;;-1:-1:-1;;102581:76:0;102713:70;;;5011:25:1;;;5067:2;5052:18;;5045:34;;;102748:10:0;;-1:-1:-1;;;;;102713:70:0;;;102748:10;;102713:70;;4984:18:1;102713:70:0;;;;;;;102885:14;;102867:58;;-1:-1:-1;;;102867:58:0;;102906:10;102867:58;;;4732:51:1;4799:18;;;4792:34;;;-1:-1:-1;;;;;102885:14:0;;;;102867:38;;4705:18:1;;102867:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;103046:15:0;;102994:99;;-1:-1:-1;;;;;;103046:15:0;;-1:-1:-1;103064:12:0;103078:14;102994:33;:99::i;:::-;102201:900;102020:1081;;;;;;:::o;116438:231::-;116487:7;116507:14;116561;;;;;;;;;-1:-1:-1;;;;;116561:14:0;-1:-1:-1;;;;;116535:50:0;;:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;116529:58;;:2;:58;:::i;:::-;116524:64;;:1;:64;:::i;:::-;116507:81;;116606:55;116623:6;116631:29;116606:16;:55::i;:::-;116599:62;;;116438:231;:::o;86513:183::-;86625:22;;86673:14;;86598:90;;-1:-1:-1;;;86598:90:0;;;;;1190:25:1;;;;86571:7:0;;-1:-1:-1;;;;;86625:22:0;;86598:74;;1163:18:1;;86598:90:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;52805:188::-;52926:58;;-1:-1:-1;;;;;4750:32:1;;52926:58:0;;;4732:51:1;4799:18;;;4792:34;;;52899:86:0;;52919:5;;-1:-1:-1;;;52949:23:0;4705:18:1;;52926:58:0;4558:274:1;52899:86:0;52805:188;;;:::o;53723:593::-;54064:10;;;54063:62;;-1:-1:-1;54080:39:0;;-1:-1:-1;;;54080:39:0;;54104:4;54080:39;;;21247:51:1;-1:-1:-1;;;;;21334:32:1;;;21314:18;;;21307:60;54080:15:0;;;;;21220:18:1;;54080:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;54063:62;54041:166;;;;-1:-1:-1;;;54041:166:0;;21580:2:1;54041:166:0;;;21562:21:1;21619:2;21599:18;;;21592:30;21658:34;21638:18;;;21631:62;-1:-1:-1;;;21709:18:1;;;21702:52;21771:19;;54041:166:0;21378:418:1;54041:166:0;54245:62;;-1:-1:-1;;;;;4750:32:1;;54245:62:0;;;4732:51:1;4799:18;;;4792:34;;;54218:90:0;;54238:5;;-1:-1:-1;;;54268:22:0;4705:18:1;;54245:62:0;4558:274:1;50789:182:0;38388:1;40287:7;;:18;40283:88;;40329:30;;-1:-1:-1;;;40329:30:0;;;;;;;;;;;40283:88;38388:1;40448:7;:17;50000:11:::1;::::0;-1:-1:-1;;;50000:11:0;::::1;;;49995:40;;50020:15;;-1:-1:-1::0;;;50020:15:0::1;;;;;;;;;;;49995:40;50872:13:::2;::::0;-1:-1:-1;;;;;50872:13:0::2;50889:10;50872:27;50868:54;;50908:14;;-1:-1:-1::0;;;50908:14:0::2;;;;;;;;;;;50868:54;50933:30;50952:10;50933:18;:30::i;:::-;38345:1:::0;40614:21;;50789:182::o;83112:781::-;83249:7;83284:1;83273:8;:12;83269:40;;;83294:15;;-1:-1:-1;;;83294:15:0;;;;;;;;;;;83269:40;-1:-1:-1;;;;;83324:26:0;;;;:59;;-1:-1:-1;;;;;;83354:29:0;;83378:4;83354:29;83324:59;83320:89;;;83392:17;;-1:-1:-1;;;83392:17:0;;;;;;;;;;;83320:89;83423:14;83439:38;83481:33;83496:7;83505:8;83481:14;:33::i;:::-;83422:92;;;;83538:1;83529:6;:10;83525:43;;;83548:20;;-1:-1:-1;;;83548:20:0;;;;;;;;;;;83525:43;83616:16;;83583:30;:49;83579:87;;;83641:25;;-1:-1:-1;;;83641:25:0;;;;;;;;;;;83579:87;83679:39;83754:17;:15;:17::i;:::-;83721:50;;:30;:50;:::i;:::-;83679:92;;83821:10;;83787:31;:44;83783:76;;;83840:19;;-1:-1:-1;;;83840:19:0;;;;;;;;;;;83783:76;-1:-1:-1;83879:6:0;;83112:781;-1:-1:-1;;;;;83112:781:0:o;82571:533::-;82759:60;;;-1:-1:-1;;;;;22021:32:1;;;22003:51;;22085:2;22070:18;;22063:34;;;22113:18;;;22106:34;;;82759:60:0;;;;82794:10;;82759:60;;21991:2:1;21976:18;82759:60:0;;;;;;;82870:102;82926:7;82936:10;82956:4;82963:8;82870:37;:102::i;:::-;83054:14;;83036:60;;-1:-1:-1;;;83036:60:0;;-1:-1:-1;;;;;4750:32:1;;;83036:60:0;;;4732:51:1;4799:18;;;4792:34;;;83054:14:0;;;;83036:38;;4705:18:1;;83036:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82571:533;;;;:::o;103109:756::-;103189:11;103203:30;;;:16;:30;;;;;;;;-1:-1:-1;;;;;103203:36:0;;;;;;;;;;:40;;103242:1;;103203:40;:::i;:::-;103254:28;103285:40;;;:26;:40;;;;;:47;;103189:54;;-1:-1:-1;103403:24:0;103426:1;103285:47;103403:24;:::i;:::-;103362:66;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;103362:66:0;;;;-1:-1:-1;103445:16:0;;;;103441:299;;103547:40;;;;:26;:40;;;;;:45;;103588:3;;103547:45;;;;;;:::i;:::-;;;;;;;;;;;;;103478:40;;;:26;:40;;;;;;;-1:-1:-1;;;;;103547:45:0;;;;103519:24;103547:45;103519:20;:24;:::i;:::-;103478:66;;;;;;;;:::i;:::-;;;;;;;;;:114;;;;;-1:-1:-1;;;;;103478:114:0;;;;;-1:-1:-1;;;;;103478:114:0;;;;;;103655:8;103607:26;:40;103634:12;103607:40;;;;;;;;;;;103648:3;103607:45;;;;;;;;:::i;:::-;;;;;;;;;;:56;;-1:-1:-1;;;;;;103607:56:0;-1:-1:-1;;;;;103607:56:0;;;;;;;;;;103721:7;:3;-1:-1:-1;103721:7:0;:::i;:::-;103678:30;;;;:16;:30;;;;;;;;-1:-1:-1;;;;;103678:40:0;;;;;;;;;:50;103441:299;103760:40;;;;:26;:40;;;;;:46;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;103760:46:0;;;;;-1:-1:-1;;;;;;103760:46:0;;;;;;;;;103817:30;;;:16;:30;;;;;;-1:-1:-1;;;;;103817:36:0;;;;;;;;;;-1:-1:-1;;;103817:36:0;;:40;103109:756::o;86111:287::-;86211:7;86231:15;86267:14;;;;;;;;;-1:-1:-1;;;;;86267:14:0;-1:-1:-1;;;;;86249:45:0;;:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;86231:65;;86325:1;86315:7;:11;86314:76;;86339:51;86353:17;:15;:17::i;:::-;86339:6;;86372:7;86381:8;86339:13;:51::i;:::-;86314:76;;;-1:-1:-1;86330:6:0;;86307:83;-1:-1:-1;;86111:287:0:o;67419:866::-;67522:13;;67493:25;;-1:-1:-1;;;;;67522:13:0;:27;67521:210;;67691:13;;67601:118;;-1:-1:-1;;;;;67691:13:0;;;67601:118;;;2415:51:1;2388:18;;67601:118:0;;;-1:-1:-1;;67601:118:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;67601:118:0;-1:-1:-1;;;67601:118:0;;;67576:154;;;;67601:118;67576:154;;:::i;:::-;;;;;;;;;;;;;67566:165;;;;;;67521:210;;;67561:1;67521:210;67883:113;;-1:-1:-1;;;;;2433:32:1;;67883:113:0;;;2415:51:1;67493:238:0;;-1:-1:-1;67818:27:0;;2388:18:1;;67883:113:0;;;-1:-1:-1;;67883:113:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;67883:113:0;-1:-1:-1;;;67883:113:0;;;67858:149;;;;67883:113;67858:149;;:::i;:::-;;;;;;;;;;;;;67848:160;;;;;;67818:190;;68021:35;68047:8;68021:25;:35::i;:::-;68073:31;;68069:115;;68135:22;;68106:78;;-1:-1:-1;;;68106:78:0;;;;;1190:25:1;;;-1:-1:-1;;;;;68135:22:0;;;;68106:59;;1163:18:1;;68106:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68069:115;68224:22;;68195:82;;-1:-1:-1;;;68195:82:0;;;;;1190:25:1;;;-1:-1:-1;;;;;68224:22:0;;;;68195:61;;1163:18:1;;68195:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67482:803;;67419:866;:::o;11644:665::-;11704:12;;;11780:5;11704:12;10155:7;11810:14;11780:5;11819;11810:14;:::i;:::-;:31;;;;:::i;:::-;11799:42;-1:-1:-1;11852:8:0;11871:6;11863:5;11799:42;11863:1;:5;:::i;:::-;:14;;;;:::i;:::-;11852:25;-1:-1:-1;11915:1:0;11897:10;11852:25;11897:6;:10;:::i;:::-;:14;;11910:1;11897:14;:::i;:::-;11896:20;;;;:::i;:::-;11892:24;;:1;:24;:::i;:::-;11888:28;-1:-1:-1;11927:12:0;11959:7;11950:5;11888:28;11954:1;11950:5;:::i;:::-;11942:14;;:4;:14;:::i;:::-;:24;;;;:::i;:::-;11927:39;-1:-1:-1;12000:1:0;11985:12;11927:39;11985:4;:12;:::i;:::-;:16;;;;:::i;:::-;11981:20;;:1;:20;:::i;:::-;:25;;12004:2;11981:25;:::i;:::-;11977:29;-1:-1:-1;12017:13:0;12042:4;12033:6;11977:29;12033:2;:6;:::i;:::-;:13;;;;:::i;:::-;12017:29;-1:-1:-1;12057:11:0;12091:2;12075:13;12017:29;12075:4;:13;:::i;:::-;:18;;;;:::i;:::-;12071:22;;:1;:22;:::i;:::-;12057:36;-1:-1:-1;12108:11:0;12117:2;12108:6;:11;:::i;:::-;12104:15;-1:-1:-1;12152:6:0;12104:15;12152:2;:6;:::i;:::-;12139:10;:6;12148:1;12139:10;:::i;:::-;:19;;;;:::i;:::-;12130:28;-1:-1:-1;12202:1:0;12194:5;12184:6;12188:2;12184:1;:6;:::i;:::-;12177:14;;:3;:14;:::i;:::-;:22;;;;:::i;:::-;:26;;;;:::i;:::-;12169:34;12264:6;;-1:-1:-1;12296:4:0;-1:-1:-1;11644:665:0;-1:-1:-1;;;;;;11644:665:0:o;12840:571::-;12929:13;12971:4;12963;:12;;12955:30;;;;-1:-1:-1;;;12955:30:0;;23219:2:1;12955:30:0;;;23201:21:1;23258:1;23238:18;;;23231:29;-1:-1:-1;;;23276:18:1;;;23269:35;23321:18;;12955:30:0;23017:328:1;12955:30:0;13018:4;13057:5;13095:3;12996:12;10155:7;13338:1;13331:3;13325:2;13310:11;13319:2;13057:5;13310:11;:::i;:::-;13309:18;;;;:::i;:::-;13294:12;:5;13302:4;13294:12;:::i;:::-;:33;;;;:::i;:::-;13293:41;;;;:::i;:::-;13288:47;;:1;:47;:::i;:::-;:51;;;;:::i;:::-;13272:2;;13246:11;13255:2;13246:6;:11;:::i;:::-;13245:18;;;;:::i;:::-;:23;;13266:2;13245:23;:::i;:::-;13232:10;13241:1;13232:6;:10;:::i;:::-;:36;;;;:::i;:::-;13225:44;;:3;:44;:::i;:::-;:49;;;;:::i;:::-;13210:1;13204:2;13189:11;13198:2;13189:6;:11;:::i;:::-;13188:18;;;;:::i;:::-;13173:12;:5;13181:4;13173:12;:::i;:::-;:33;;;;:::i;:::-;13165:42;;:4;:42;:::i;:::-;:46;;;;:::i;:::-;13128:23;13146:5;13128:4;:23;:::i;:::-;:83;;;;:::i;:::-;:146;;;;:::i;:::-;:211;;;;:::i;:::-;:239;;;;:::i;:::-;13112:255;12840:571;-1:-1:-1;;;;;;;;12840:571:0:o;57228:660::-;57663:23;57689:69;57717:4;57689:69;;;;;;;;;;;;;;;;;57697:5;-1:-1:-1;;;;;57689:27:0;;;:69;;;;;:::i;:::-;57663:95;;57777:10;:17;57798:1;57777:22;:56;;;;57814:10;57803:30;;;;;;;;;;;;:::i;:::-;57769:111;;;;-1:-1:-1;;;57769:111:0;;23552:2:1;57769:111:0;;;23534:21:1;23591:2;23571:18;;;23564:30;23630:34;23610:18;;;23603:62;-1:-1:-1;;;23681:18:1;;;23674:40;23731:19;;57769:111:0;23350:406:1;51429:156:0;51519:13;51512:20;;-1:-1:-1;;;;;;51512:20:0;;;51543:34;51568:8;51543:24;:34::i;:::-;51429:156;:::o;30261:305::-;30362:7;30382:14;30399:25;30406:1;30409;30412:11;30399:6;:25::i;:::-;30382:42;-1:-1:-1;30451:11:0;30439:8;:23;;;;;;;;:::i;:::-;;:56;;;;;30494:1;30479:11;30466:25;;;;;:::i;:::-;30476:1;30473;30466:25;:29;30439:56;30435:100;;;30512:11;30522:1;30512:11;;:::i;:::-;;;30435:100;30552:6;30261:305;-1:-1:-1;;;;;30261:305:0:o;50979:260::-;-1:-1:-1;;;;;51057:22:0;;;;51056:55;;-1:-1:-1;;;;;;51085:25:0;;51105:4;51085:25;51056:55;51052:84;;;51120:16;;-1:-1:-1;;;51120:16:0;;;;;;;;;;;51052:84;51149:13;:24;;-1:-1:-1;;;;;;51149:24:0;-1:-1:-1;;;;;51149:24:0;;;;;;;;;51214:6;;51189:42;;51149:24;;51214:6;;51189:42;;-1:-1:-1;;51189:42:0;50979:260;:::o;4318:229::-;4455:12;4487:52;4509:6;4517:4;4523:1;4526:12;4487:21;:52::i;41366:261::-;-1:-1:-1;;;;;41444:22:0;;41440:57;;41475:22;;-1:-1:-1;;;41475:22:0;;;;;;;;;;;41440:57;41529:6;;;-1:-1:-1;;;;;41546:17:0;;;-1:-1:-1;;;;;;41546:17:0;;;;;;;41579:40;;41529:6;;;41546:17;41529:6;;41579:40;;41510:16;;41579:40;41429:198;41366:261;:::o;25832:4292::-;25914:14;;;-1:-1:-1;;26459:1:0;26456;26449:20;26503:1;26500;26496:9;26487:18;;26559:5;26555:2;26552:13;26544:5;26540:2;26536:14;26532:34;26523:43;;;26665:5;26674:1;26665:10;26661:373;;27007:11;26999:5;:19;;;;;:::i;:::-;;26992:26;;;;;;26661:373;27161:5;27147:11;:19;27139:53;;;;-1:-1:-1;;;27139:53:0;;24095:2:1;27139:53:0;;;24077:21:1;24134:2;24114:18;;;24107:30;-1:-1:-1;;;24153:18:1;;;24146:51;24214:18;;27139:53:0;23893:345:1;27139:53:0;27455:17;27593:11;27590:1;27587;27580:25;29000:1;28152;28137:12;;:16;;28122:32;;28260:22;;;;28981:1;:15;;28980:21;;29237;;;29233:25;;29222:36;29307:21;;;29303:25;;29292:36;29378:21;;;29374:25;;29363:36;29449:21;;;29445:25;;29434:36;29520:21;;;29516:25;;29505:36;29592:21;;;29588:25;;;29577:36;;;28107:12;28511;;;28507:23;;;28503:31;;;27710:20;;;27699:32;;;28627:12;;;;27758:21;;28361:16;;;;28618:21;;;;30062:15;;;-1:-1:-1;;;;25832:4292:0:o;5404:455::-;5574:12;5632:5;5607:21;:30;;5599:81;;;;-1:-1:-1;;;5599:81:0;;24445:2:1;5599:81:0;;;24427:21:1;24484:2;24464:18;;;24457:30;24523:34;24503:18;;;24496:62;-1:-1:-1;;;24574:18:1;;;24567:36;24620:19;;5599:81:0;24243:402:1;5599:81:0;5692:12;5706:23;5733:6;-1:-1:-1;;;;;5733:11:0;5752:5;5759:4;5733:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5691:73;;;;5782:69;5809:6;5817:7;5826:10;5838:12;8162;8191:7;8187:427;;;8219:10;:17;8240:1;8219:22;8215:290;;-1:-1:-1;;;;;1858:19:0;;;8429:60;;;;-1:-1:-1;;;8429:60:0;;25158:2:1;8429:60:0;;;25140:21:1;25197:2;25177:18;;;25170:30;25236:31;25216:18;;;25209:59;25285:18;;8429:60:0;24956:353:1;8429:60:0;-1:-1:-1;8526:10:0;8519:17;;8187:427;8569:33;8577:10;8589:12;9324:17;;:21;9320:388;;9556:10;9550:17;9613:15;9600:10;9596:2;9592:19;9585:44;9320:388;9683:12;9676:20;;-1:-1:-1;;;9676:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:226:1:-;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;187:23:1;;14:226;-1:-1:-1;14:226:1:o;245:794::-;507:2;519:21;;;589:13;;492:18;;;611:22;;;459:4;;690:15;;;664:2;649:18;;;459:4;733:280;747:6;744:1;741:13;733:280;;;806:13;;848:9;;-1:-1:-1;;;;;844:35:1;832:48;;928:2;920:11;;;914:18;900:12;;;893:40;988:15;;;;962:2;953:12;;;;876:1;762:9;733:280;;1226:131;-1:-1:-1;;;;;1301:31:1;;1291:42;;1281:70;;1347:1;1344;1337:12;1362:134;1430:20;;1459:31;1430:20;1459:31;:::i;:::-;1362:134;;;:::o;1501:367::-;1569:6;1577;1630:2;1618:9;1609:7;1605:23;1601:32;1598:52;;;1646:1;1643;1636:12;1598:52;1691:23;;;-1:-1:-1;1790:2:1;1775:18;;1762:32;1803:33;1762:32;1803:33;:::i;:::-;1855:7;1845:17;;;1501:367;;;;;:::o;2477:648::-;2601:6;2609;2662:2;2650:9;2641:7;2637:23;2633:32;2630:52;;;2678:1;2675;2668:12;2630:52;2718:9;2705:23;2751:18;2743:6;2740:30;2737:50;;;2783:1;2780;2773:12;2737:50;2806:22;;2859:4;2851:13;;2847:27;-1:-1:-1;2837:55:1;;2888:1;2885;2878:12;2837:55;2928:2;2915:16;2954:18;2946:6;2943:30;2940:50;;;2986:1;2983;2976:12;2940:50;3039:7;3034:2;3024:6;3021:1;3017:14;3013:2;3009:23;3005:32;3002:45;2999:65;;;3060:1;3057;3050:12;2999:65;3091:2;3083:11;;;;;3113:6;;-1:-1:-1;2477:648:1;-1:-1:-1;;;2477:648:1:o;3130:508::-;3207:6;3215;3223;3276:2;3264:9;3255:7;3251:23;3247:32;3244:52;;;3292:1;3289;3282:12;3244:52;3331:9;3318:23;3350:31;3375:5;3350:31;:::i;:::-;3400:5;-1:-1:-1;3478:2:1;3463:18;;3450:32;;-1:-1:-1;3560:2:1;3545:18;;3532:32;3573:33;3532:32;3573:33;:::i;:::-;3625:7;3615:17;;;3130:508;;;;;:::o;3643:466::-;3720:6;3728;3736;3789:2;3777:9;3768:7;3764:23;3760:32;3757:52;;;3805:1;3802;3795:12;3757:52;-1:-1:-1;;3850:23:1;;;3970:2;3955:18;;3942:32;;-1:-1:-1;4073:2:1;4058:18;;;4045:32;;3643:466;-1:-1:-1;3643:466:1:o;4114:247::-;4173:6;4226:2;4214:9;4205:7;4201:23;4197:32;4194:52;;;4242:1;4239;4232:12;4194:52;4281:9;4268:23;4300:31;4325:5;4300:31;:::i;5090:118::-;5176:5;5169:13;5162:21;5155:5;5152:32;5142:60;;5198:1;5195;5188:12;5213:376;5275:6;5283;5336:2;5324:9;5315:7;5311:23;5307:32;5304:52;;;5352:1;5349;5342:12;5304:52;5391:9;5378:23;5410:28;5432:5;5410:28;:::i;:::-;5457:5;-1:-1:-1;5514:2:1;5499:18;;5486:32;5527:30;5486:32;5527:30;:::i;5594:114::-;5678:4;5671:5;5667:16;5660:5;5657:27;5647:55;;5698:1;5695;5688:12;5713:1009;5824:6;5832;5840;5848;5856;5864;5872;5925:3;5913:9;5904:7;5900:23;5896:33;5893:53;;;5942:1;5939;5932:12;5893:53;5981:9;5968:23;6000:31;6025:5;6000:31;:::i;:::-;6050:5;-1:-1:-1;6128:2:1;6113:18;;6100:32;;-1:-1:-1;6210:2:1;6195:18;;6182:32;6223:33;6182:32;6223:33;:::i;:::-;6275:7;-1:-1:-1;6355:2:1;6340:18;;6327:32;;-1:-1:-1;6458:3:1;6443:19;;6430:33;;-1:-1:-1;6562:3:1;6547:19;;6534:33;;-1:-1:-1;6645:3:1;6630:19;;6617:33;6659:31;6617:33;6659:31;:::i;:::-;6709:7;6699:17;;;5713:1009;;;;;;;;;;:::o;6727:361::-;6792:6;6800;6853:2;6841:9;6832:7;6828:23;6824:32;6821:52;;;6869:1;6866;6859:12;6821:52;6914:23;;;-1:-1:-1;7013:2:1;6998:18;;6985:32;7026:30;6985:32;7026:30;:::i;7093:608::-;7179:6;7187;7195;7203;7256:3;7244:9;7235:7;7231:23;7227:33;7224:53;;;7273:1;7270;7263:12;7224:53;7318:23;;;-1:-1:-1;7438:2:1;7423:18;;7410:32;;-1:-1:-1;7541:2:1;7526:18;;7513:32;;-1:-1:-1;7623:2:1;7608:18;;7595:32;7636:33;7595:32;7636:33;:::i;:::-;7093:608;;;;-1:-1:-1;7093:608:1;;-1:-1:-1;;7093:608:1:o;7706:367::-;7774:6;7782;7835:2;7823:9;7814:7;7810:23;7806:32;7803:52;;;7851:1;7848;7841:12;7803:52;7890:9;7877:23;7909:31;7934:5;7909:31;:::i;:::-;7959:5;8037:2;8022:18;;;;8009:32;;-1:-1:-1;;;7706:367:1:o;8267:127::-;8328:10;8323:3;8319:20;8316:1;8309:31;8359:4;8356:1;8349:15;8383:4;8380:1;8373:15;8399:252;8471:2;8465:9;8513:3;8501:16;;8547:18;8532:34;;8568:22;;;8529:62;8526:88;;;8594:18;;:::i;:::-;8630:2;8623:22;8399:252;:::o;8656:275::-;8727:2;8721:9;8792:2;8773:13;;-1:-1:-1;;8769:27:1;8757:40;;8827:18;8812:34;;8848:22;;;8809:62;8806:88;;;8874:18;;:::i;:::-;8910:2;8903:22;8656:275;;-1:-1:-1;8656:275:1:o;8936:1828::-;9023:6;9083:3;9071:9;9062:7;9058:23;9054:33;9099:2;9096:22;;;9114:1;9111;9104:12;9096:22;-1:-1:-1;9156:22:1;;:::i;:::-;9223:23;;9255:22;;9350:2;9335:18;;;9322:32;9370:14;;;9363:31;9467:2;9452:18;;;9439:32;9487:14;;;9480:31;9584:2;9569:18;;;9556:32;9604:14;;;9597:31;9701:3;9686:19;;;9673:33;9722:15;;;9715:32;9820:3;9805:19;;;9792:33;9841:15;;;9834:32;9939:3;9924:19;;;9911:33;9960:15;;;9953:32;10058:3;10043:19;;;10030:33;10079:15;;;10072:32;10177:3;10162:19;;;10149:33;10198:15;;;10191:32;10256:39;10290:3;10275:19;;10256:39;:::i;:::-;10250:3;10243:5;10239:15;10232:64;10329:39;10363:3;10352:9;10348:19;10329:39;:::i;:::-;10323:3;10316:5;10312:15;10305:64;10402:39;10436:3;10425:9;10421:19;10402:39;:::i;:::-;10396:3;10389:5;10385:15;10378:64;10475:39;10509:3;10498:9;10494:19;10475:39;:::i;:::-;10469:3;10462:5;10458:15;10451:64;10548:39;10582:3;10571:9;10567:19;10548:39;:::i;:::-;10542:3;10535:5;10531:15;10524:64;10621:39;10655:3;10644:9;10640:19;10621:39;:::i;:::-;10615:3;10608:5;10604:15;10597:64;10694:39;10728:3;10717:9;10713:19;10694:39;:::i;:::-;10688:3;10677:15;;10670:64;10681:5;8936:1828;-1:-1:-1;;;8936:1828:1:o;10769:587::-;10855:6;10863;10871;10879;10932:3;10920:9;10911:7;10907:23;10903:33;10900:53;;;10949:1;10946;10939:12;10900:53;-1:-1:-1;;10994:23:1;;;11114:2;11099:18;;11086:32;;-1:-1:-1;11217:2:1;11202:18;;11189:32;;11320:2;11305:18;11292:32;;-1:-1:-1;10769:587:1;-1:-1:-1;10769:587:1:o;11361:384::-;11427:6;11435;11488:2;11476:9;11467:7;11463:23;11459:32;11456:52;;;11504:1;11501;11494:12;11456:52;11543:9;11530:23;11562:31;11587:5;11562:31;:::i;:::-;11612:5;-1:-1:-1;11669:2:1;11654:18;;11641:32;11682:31;11641:32;11682:31;:::i;11750:288::-;11791:3;11829:5;11823:12;11856:6;11851:3;11844:19;11912:6;11905:4;11898:5;11894:16;11887:4;11882:3;11878:14;11872:47;11964:1;11957:4;11948:6;11943:3;11939:16;11935:27;11928:38;12027:4;12020:2;12016:7;12011:2;12003:6;11999:15;11995:29;11990:3;11986:39;11982:50;11975:57;;;11750:288;;;;:::o;12043:217::-;12190:2;12179:9;12172:21;12153:4;12210:44;12250:2;12239:9;12235:18;12227:6;12210:44;:::i;12447:245::-;12514:6;12567:2;12555:9;12546:7;12542:23;12538:32;12535:52;;;12583:1;12580;12573:12;12535:52;12615:9;12609:16;12634:28;12656:5;12634:28;:::i;12697:127::-;12758:10;12753:3;12749:20;12746:1;12739:31;12789:4;12786:1;12779:15;12813:4;12810:1;12803:15;12829:125;12894:9;;;12915:10;;;12912:36;;;12928:18;;:::i;13283:127::-;13344:10;13339:3;13335:20;13332:1;13325:31;13375:4;13372:1;13365:15;13399:4;13396:1;13389:15;13415:416;13602:5;13589:19;13617:33;13642:7;13617:33;:::i;:::-;13679:11;;-1:-1:-1;;;;;;13675:54:1;-1:-1:-1;;;;;13731:33:1;;;;13672:93;13659:107;;13820:2;13809:14;;;;13796:28;13761:1;13782:12;;;;13775:50;13415:416::o;13836:128::-;13903:9;;;13924:11;;;13921:37;;;13938:18;;:::i;14361:168::-;14434:9;;;14465;;14482:15;;;14476:22;;14462:37;14452:71;;14503:18;;:::i;14534:127::-;14595:10;14590:3;14586:20;14583:1;14576:31;14626:4;14623:1;14616:15;14650:4;14647:1;14640:15;14666:120;14706:1;14732;14722:35;;14737:18;;:::i;:::-;-1:-1:-1;14771:9:1;;14666:120::o;14791:251::-;14861:6;14914:2;14902:9;14893:7;14889:23;14885:32;14882:52;;;14930:1;14927;14920:12;14882:52;14962:9;14956:16;14981:31;15006:5;14981:31;:::i;15047:230::-;15117:6;15170:2;15158:9;15149:7;15145:23;15141:32;15138:52;;;15186:1;15183;15176:12;15138:52;-1:-1:-1;15231:16:1;;15047:230;-1:-1:-1;15047:230:1:o;15282:247::-;15350:6;15403:2;15391:9;15382:7;15378:23;15374:32;15371:52;;;15419:1;15416;15409:12;15371:52;15451:9;15445:16;15470:29;15493:5;15470:29;:::i;15534:375::-;15622:1;15640:5;15654:249;15675:1;15665:8;15662:15;15654:249;;;15725:4;15720:3;15716:14;15710:4;15707:24;15704:50;;;15734:18;;:::i;:::-;15784:1;15774:8;15770:16;15767:49;;;15798:16;;;;15767:49;15881:1;15877:16;;;;;15837:15;;15654:249;;;15534:375;;;;;;:::o;15914:902::-;15963:5;15993:8;15983:80;;-1:-1:-1;16034:1:1;16048:5;;15983:80;16082:4;16072:76;;-1:-1:-1;16119:1:1;16133:5;;16072:76;16164:4;16182:1;16177:59;;;;16250:1;16245:174;;;;16157:262;;16177:59;16207:1;16198:10;;16221:5;;;16245:174;16282:3;16272:8;16269:17;16266:43;;;16289:18;;:::i;:::-;-1:-1:-1;;16345:1:1;16331:16;;16404:5;;16157:262;;16503:2;16493:8;16490:16;16484:3;16478:4;16475:13;16471:36;16465:2;16455:8;16452:16;16447:2;16441:4;16438:12;16434:35;16431:77;16428:203;;;-1:-1:-1;16540:19:1;;;16616:5;;16428:203;16663:42;-1:-1:-1;;16688:8:1;16682:4;16663:42;:::i;:::-;16741:6;16737:1;16733:6;16729:19;16720:7;16717:32;16714:58;;;16752:18;;:::i;:::-;16790:20;;15914:902;-1:-1:-1;;;15914:902:1:o;16821:140::-;16879:5;16908:47;16949:4;16939:8;16935:19;16929:4;16908:47;:::i;16966:1001::-;17061:6;17114:2;17102:9;17093:7;17089:23;17085:32;17082:52;;;17130:1;17127;17120:12;17082:52;17163:9;17157:16;17196:18;17188:6;17185:30;17182:50;;;17228:1;17225;17218:12;17182:50;17251:22;;17304:4;17296:13;;17292:27;-1:-1:-1;17282:55:1;;17333:1;17330;17323:12;17282:55;17366:2;17360:9;17392:18;17384:6;17381:30;17378:56;;;17414:18;;:::i;:::-;17460:6;17457:1;17453:14;17487:28;17511:2;17507;17503:11;17487:28;:::i;:::-;17549:19;;;17593:2;17623:11;;;17619:20;;;17584:12;;;;17651:19;;;17648:39;;;17683:1;17680;17673:12;17648:39;17715:2;17711;17707:11;17696:22;;17727:210;17743:6;17738:3;17735:15;17727:210;;;17816:3;17810:10;17797:23;;17833:31;17858:5;17833:31;:::i;:::-;17877:18;;;17924:2;17760:12;;;;17915;;;;17727:210;;19462:343;19541:6;19549;19602:2;19590:9;19581:7;19577:23;19573:32;19570:52;;;19618:1;19615;19608:12;19570:52;-1:-1:-1;;19663:16:1;;19769:2;19754:18;;;19748:25;19663:16;;19748:25;;-1:-1:-1;19462:343:1:o;20424:136::-;20463:3;20491:5;20481:39;;20500:18;;:::i;:::-;-1:-1:-1;;;20536:18:1;;20424:136::o;20565:127::-;20626:10;20621:3;20617:20;20614:1;20607:31;20657:4;20654:1;20647:15;20681:4;20678:1;20671:15;22151:216;22215:9;;;22243:11;;;22190:3;22273:9;;22301:10;;22297:19;;22326:10;;22318:19;;22294:44;22291:70;;;22341:18;;:::i;:::-;22291:70;;22151:216;;;;:::o;22372:237::-;22444:9;;;22411:7;22469:9;;-1:-1:-1;;;22480:18:1;;22465:34;22462:60;;;22502:18;;:::i;:::-;22575:1;22566:7;22561:16;22558:1;22555:23;22551:1;22544:9;22541:38;22531:72;;22583:18;;:::i;22614:193::-;22653:1;22679;22669:35;;22684:18;;:::i;:::-;-1:-1:-1;;;22720:18:1;;-1:-1:-1;;22740:13:1;;22716:38;22713:64;;;22757:18;;:::i;:::-;-1:-1:-1;22791:10:1;;22614:193::o;22812:200::-;22878:9;;;22851:4;22906:9;;22934:10;;22946:12;;;22930:29;22969:12;;;22961:21;;22927:56;22924:82;;;22986:18;;:::i;:::-;22924:82;22812:200;;;;:::o;23761:127::-;23822:10;23817:3;23813:20;23810:1;23803:31;23853:4;23850:1;23843:15;23877:4;23874:1;23867:15;24650:301;24779:3;24817:6;24811:13;24863:6;24856:4;24848:6;24844:17;24839:3;24833:37;24925:1;24889:16;;24914:13;;;-1:-1:-1;24889:16:1;24650:301;-1:-1:-1;24650:301:1:o
Swarm Source
ipfs://3cfcf2e0022a02b0895fd09591f4c48f657caaa7f78c4e71c56e624254dc08fb
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in MON
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.