Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 1 from a total of 1 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Mint | 11663995 | 1863 days ago | IN | 0 ETH | 0.00088315 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Masset
Compiler Version
v0.5.16+commit.9c3226ce
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2020-12-10
*/
pragma solidity 0.5.16;
pragma experimental ABIEncoderV2;
interface MassetStructs {
/** @dev Stores high level basket info */
struct Basket {
/** @dev Array of Bassets currently active */
Basset[] bassets;
/** @dev Max number of bAssets that can be present in any Basket */
uint8 maxBassets;
/** @dev Some bAsset is undergoing re-collateralisation */
bool undergoingRecol;
/**
* @dev In the event that we do not raise enough funds from the auctioning of a failed Basset,
* The Basket is deemed as failed, and is undercollateralised to a certain degree.
* The collateralisation ratio is used to calc Masset burn rate.
*/
bool failed;
uint256 collateralisationRatio;
}
/** @dev Stores bAsset info. The struct takes 5 storage slots per Basset */
struct Basset {
/** @dev Address of the bAsset */
address addr;
/** @dev Status of the basset, */
BassetStatus status; // takes uint8 datatype (1 byte) in storage
/** @dev An ERC20 can charge transfer fee, for example USDT, DGX tokens. */
bool isTransferFeeCharged; // takes a byte in storage
/**
* @dev 1 Basset * ratio / ratioScale == x Masset (relative value)
* If ratio == 10e8 then 1 bAsset = 10 mAssets
* A ratio is divised as 10^(18-tokenDecimals) * measurementMultiple(relative value of 1 base unit)
*/
uint256 ratio;
/** @dev Target weights of the Basset (100% == 1e18) */
uint256 maxWeight;
/** @dev Amount of the Basset that is held in Collateral */
uint256 vaultBalance;
}
/** @dev Status of the Basset - has it broken its peg? */
enum BassetStatus {
Default,
Normal,
BrokenBelowPeg,
BrokenAbovePeg,
Blacklisted,
Liquidating,
Liquidated,
Failed
}
/** @dev Internal details on Basset */
struct BassetDetails {
Basset bAsset;
address integrator;
uint8 index;
}
/** @dev All details needed to Forge with multiple bAssets */
struct ForgePropsMulti {
bool isValid; // Flag to signify that forge bAssets have passed validity check
Basset[] bAssets;
address[] integrators;
uint8[] indexes;
}
/** @dev All details needed to Forge with multiple bAssets */
struct RedeemProps {
bool isValid;
Basset[] allBassets;
Basset[] bAssets;
address[] integrators;
uint8[] indexes;
}
/** @dev All details needed for proportionate Redemption */
struct RedeemPropsMulti {
uint256 colRatio;
Basset[] bAssets;
address[] integrators;
uint8[] indexes;
}
}
contract IForgeValidator is MassetStructs {
function validateMint(uint256 _totalVault, Basset calldata _basset, uint256 _bAssetQuantity)
external pure returns (bool, string memory);
function validateMintMulti(uint256 _totalVault, Basset[] calldata _bassets, uint256[] calldata _bAssetQuantities)
external pure returns (bool, string memory);
function validateSwap(uint256 _totalVault, Basset calldata _inputBasset, Basset calldata _outputBasset, uint256 _quantity)
external pure returns (bool, string memory, uint256, bool);
function validateRedemption(
bool basketIsFailed,
uint256 _totalVault,
Basset[] calldata _allBassets,
uint8[] calldata _indices,
uint256[] calldata _bassetQuantities) external pure returns (bool, string memory, bool);
function calculateRedemptionMulti(
uint256 _mAssetQuantity,
Basset[] calldata _allBassets) external pure returns (bool, string memory, uint256[] memory);
}
interface IPlatformIntegration {
/**
* @dev Deposit the given bAsset to Lending platform
* @param _bAsset bAsset address
* @param _amount Amount to deposit
*/
function deposit(address _bAsset, uint256 _amount, bool isTokenFeeCharged)
external returns (uint256 quantityDeposited);
/**
* @dev Withdraw given bAsset from Lending platform
*/
function withdraw(address _receiver, address _bAsset, uint256 _amount, bool _hasTxFee) external;
/**
* @dev Withdraw given bAsset from Lending platform
*/
function withdraw(address _receiver, address _bAsset, uint256 _amount, uint256 _totalAmount, bool _hasTxFee) external;
/**
* @dev Withdraw given bAsset from the cache
*/
function withdrawRaw(address _receiver, address _bAsset, uint256 _amount) external;
/**
* @dev Returns the current balance of the given bAsset
*/
function checkBalance(address _bAsset) external returns (uint256 balance);
/**
* @dev Returns the pToken
*/
function bAssetToPToken(address _bAsset) external returns (address pToken);
}
contract IBasketManager is MassetStructs {
/** @dev Setters for mAsset to update balances */
function increaseVaultBalance(
uint8 _bAsset,
address _integrator,
uint256 _increaseAmount) external;
function increaseVaultBalances(
uint8[] calldata _bAsset,
address[] calldata _integrator,
uint256[] calldata _increaseAmount) external;
function decreaseVaultBalance(
uint8 _bAsset,
address _integrator,
uint256 _decreaseAmount) external;
function decreaseVaultBalances(
uint8[] calldata _bAsset,
address[] calldata _integrator,
uint256[] calldata _decreaseAmount) external;
function collectInterest() external
returns (uint256 interestCollected, uint256[] memory gains);
/** @dev Setters for Gov to update Basket composition */
function addBasset(
address _basset,
address _integration,
bool _isTransferFeeCharged) external returns (uint8 index);
function setBasketWeights(address[] calldata _bassets, uint256[] calldata _weights) external;
function setTransferFeesFlag(address _bAsset, bool _flag) external;
/** @dev Getters to retrieve Basket information */
function getBasket() external view returns (Basket memory b);
function prepareForgeBasset(address _token, uint256 _amt, bool _mint) external
returns (bool isValid, BassetDetails memory bInfo);
function prepareSwapBassets(address _input, address _output, bool _isMint) external view
returns (bool, string memory, BassetDetails memory, BassetDetails memory);
function prepareForgeBassets(address[] calldata _bAssets, uint256[] calldata _amts, bool _mint) external
returns (ForgePropsMulti memory props);
function prepareRedeemBassets(address[] calldata _bAssets) external view
returns (RedeemProps memory props);
function prepareRedeemMulti() external view
returns (RedeemPropsMulti memory props);
function getBasset(address _token) external view
returns (Basset memory bAsset);
function getBassets() external view
returns (Basset[] memory bAssets, uint256 len);
function paused() external view returns (bool);
/** @dev Recollateralisation */
function handlePegLoss(address _basset, bool _belowPeg) external returns (bool actioned);
function negateIsolation(address _basset) external;
}
interface ISavingsManager {
/** @dev Admin privs */
function distributeUnallocatedInterest(address _mAsset) external;
/** @dev Liquidator */
function depositLiquidation(address _mAsset, uint256 _liquidation) external;
/** @dev Liquidator */
function collectAndStreamInterest(address _mAsset) external;
/** @dev Public privs */
function collectAndDistributeInterest(address _mAsset) external;
}
contract IMasset is MassetStructs {
/** @dev Calc interest */
function collectInterest() external returns (uint256 swapFeesGained, uint256 newTotalSupply);
function collectPlatformInterest() external returns (uint256 interestGained, uint256 newTotalSupply);
/** @dev Minting */
function mint(address _basset, uint256 _bassetQuantity)
external returns (uint256 massetMinted);
function mintTo(address _basset, uint256 _bassetQuantity, address _recipient)
external returns (uint256 massetMinted);
function mintMulti(address[] calldata _bAssets, uint256[] calldata _bassetQuantity, address _recipient)
external returns (uint256 massetMinted);
/** @dev Swapping */
function swap( address _input, address _output, uint256 _quantity, address _recipient)
external returns (uint256 output);
function getSwapOutput( address _input, address _output, uint256 _quantity)
external view returns (bool, string memory, uint256 output);
/** @dev Redeeming */
function redeem(address _basset, uint256 _bassetQuantity)
external returns (uint256 massetRedeemed);
function redeemTo(address _basset, uint256 _bassetQuantity, address _recipient)
external returns (uint256 massetRedeemed);
function redeemMulti(address[] calldata _bAssets, uint256[] calldata _bassetQuantities, address _recipient)
external returns (uint256 massetRedeemed);
function redeemMasset(uint256 _mAssetQuantity, address _recipient) external;
/** @dev Setters for the Manager or Gov to update module info */
function upgradeForgeValidator(address _newForgeValidator) external;
/** @dev Setters for Gov to set system params */
function setSwapFee(uint256 _swapFee) external;
/** @dev Getters */
function getBasketManager() external view returns(address);
function forgeValidator() external view returns (address);
function totalSupply() external view returns (uint256);
function swapFee() external view returns (uint256);
}
contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
*/
bool private initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private initializing;
/**
* @dev Modifier to use in the initializer function of a contract.
*/
modifier initializer() {
require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized");
bool isTopLevelCall = !initializing;
if (isTopLevelCall) {
initializing = true;
initialized = true;
}
_;
if (isTopLevelCall) {
initializing = false;
}
}
/// @dev Returns true if and only if the function is running in the constructor
function isConstructor() private view returns (bool) {
// extcodesize checks the size of the code stored in an address, and
// address returns the current address. Since the code is still not
// deployed when running a constructor, any checks on its code size will
// yield zero, making it an effective way to detect if a contract is
// under construction or not.
address self = address(this);
uint256 cs;
assembly { cs := extcodesize(self) }
return cs == 0;
}
// Reserved storage space to allow for layout changes in the future.
uint256[50] private ______gap;
}
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
contract Context {
// Empty internal constructor, to prevent people from mistakenly deploying
// an instance of this contract, which should be used via inheritance.
constructor () internal { }
// solhint-disable-previous-line no-empty-blocks
function _msgSender() internal view returns (address payable) {
return msg.sender;
}
function _msgData() internal view returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
/**
* @dev Interface of the ERC20 standard as defined in the EIP. Does not include
* the optional functions; to access them see {ERC20Detailed}.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*
* _Available since v2.4.0._
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
contract ERC20 is Context, IERC20 {
using SafeMath for uint256;
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `recipient` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address recipient, uint256 amount) public returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20};
*
* Requirements:
* - `sender` and `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
* - the caller must have allowance for `sender`'s tokens of at least
* `amount`.
*/
function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
return true;
}
/**
* @dev Moves tokens `amount` from `sender` to `recipient`.
*
* This is internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `sender` cannot be the zero address.
* - `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
*/
function _transfer(address sender, address recipient, uint256 amount) internal {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements
*
* - `to` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal {
require(account != address(0), "ERC20: mint to the zero address");
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal {
require(account != address(0), "ERC20: burn from the zero address");
_balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
_totalSupply = _totalSupply.sub(amount);
emit Transfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.
*
* This is internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(address owner, address spender, uint256 amount) internal {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Destroys `amount` tokens from `account`.`amount` is then deducted
* from the caller's allowance.
*
* See {_burn} and {_approve}.
*/
function _burnFrom(address account, uint256 amount) internal {
_burn(account, amount);
_approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "ERC20: burn amount exceeds allowance"));
}
}
contract InitializableERC20Detailed is IERC20 {
string private _name;
string private _symbol;
uint8 private _decimals;
/**
* @dev Sets the values for `name`, `symbol`, and `decimals`. All three of
* these values are immutable: they can only be set once during
* construction.
* @notice To avoid variable shadowing appended `Arg` after arguments name.
*/
function _initialize(string memory nameArg, string memory symbolArg, uint8 decimalsArg) internal {
_name = nameArg;
_symbol = symbolArg;
_decimals = decimalsArg;
}
/**
* @dev Returns the name of the token.
*/
function name() public view returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5,05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view returns (uint8) {
return _decimals;
}
}
contract InitializableToken is ERC20, InitializableERC20Detailed {
/**
* @dev Initialization function for implementing contract
* @notice To avoid variable shadowing appended `Arg` after arguments name.
*/
function _initialize(string memory _nameArg, string memory _symbolArg) internal {
InitializableERC20Detailed._initialize(_nameArg, _symbolArg, 18);
}
}
contract InitializableModuleKeys {
// Governance // Phases
bytes32 internal KEY_GOVERNANCE; // 2.x
bytes32 internal KEY_STAKING; // 1.2
bytes32 internal KEY_PROXY_ADMIN; // 1.0
// mStable
bytes32 internal KEY_ORACLE_HUB; // 1.2
bytes32 internal KEY_MANAGER; // 1.2
bytes32 internal KEY_RECOLLATERALISER; // 2.x
bytes32 internal KEY_META_TOKEN; // 1.1
bytes32 internal KEY_SAVINGS_MANAGER; // 1.0
/**
* @dev Initialize function for upgradable proxy contracts. This function should be called
* via Proxy to initialize constants in the Proxy contract.
*/
function _initialize() internal {
// keccak256() values are evaluated only once at the time of this function call.
// Hence, no need to assign hard-coded values to these variables.
KEY_GOVERNANCE = keccak256("Governance");
KEY_STAKING = keccak256("Staking");
KEY_PROXY_ADMIN = keccak256("ProxyAdmin");
KEY_ORACLE_HUB = keccak256("OracleHub");
KEY_MANAGER = keccak256("Manager");
KEY_RECOLLATERALISER = keccak256("Recollateraliser");
KEY_META_TOKEN = keccak256("MetaToken");
KEY_SAVINGS_MANAGER = keccak256("SavingsManager");
}
}
interface INexus {
function governor() external view returns (address);
function getModule(bytes32 key) external view returns (address);
function proposeModule(bytes32 _key, address _addr) external;
function cancelProposedModule(bytes32 _key) external;
function acceptProposedModule(bytes32 _key) external;
function acceptProposedModules(bytes32[] calldata _keys) external;
function requestLockModule(bytes32 _key) external;
function cancelLockModule(bytes32 _key) external;
function lockModule(bytes32 _key) external;
}
contract InitializableModule is InitializableModuleKeys {
INexus public nexus;
/**
* @dev Modifier to allow function calls only from the Governor.
*/
modifier onlyGovernor() {
require(msg.sender == _governor(), "Only governor can execute");
_;
}
/**
* @dev Modifier to allow function calls only from the Governance.
* Governance is either Governor address or Governance address.
*/
modifier onlyGovernance() {
require(
msg.sender == _governor() || msg.sender == _governance(),
"Only governance can execute"
);
_;
}
/**
* @dev Modifier to allow function calls only from the ProxyAdmin.
*/
modifier onlyProxyAdmin() {
require(
msg.sender == _proxyAdmin(), "Only ProxyAdmin can execute"
);
_;
}
/**
* @dev Modifier to allow function calls only from the Manager.
*/
modifier onlyManager() {
require(msg.sender == _manager(), "Only manager can execute");
_;
}
/**
* @dev Initialization function for upgradable proxy contracts
* @param _nexus Nexus contract address
*/
function _initialize(address _nexus) internal {
require(_nexus != address(0), "Nexus address is zero");
nexus = INexus(_nexus);
InitializableModuleKeys._initialize();
}
/**
* @dev Returns Governor address from the Nexus
* @return Address of Governor Contract
*/
function _governor() internal view returns (address) {
return nexus.governor();
}
/**
* @dev Returns Governance Module address from the Nexus
* @return Address of the Governance (Phase 2)
*/
function _governance() internal view returns (address) {
return nexus.getModule(KEY_GOVERNANCE);
}
/**
* @dev Return Staking Module address from the Nexus
* @return Address of the Staking Module contract
*/
function _staking() internal view returns (address) {
return nexus.getModule(KEY_STAKING);
}
/**
* @dev Return ProxyAdmin Module address from the Nexus
* @return Address of the ProxyAdmin Module contract
*/
function _proxyAdmin() internal view returns (address) {
return nexus.getModule(KEY_PROXY_ADMIN);
}
/**
* @dev Return MetaToken Module address from the Nexus
* @return Address of the MetaToken Module contract
*/
function _metaToken() internal view returns (address) {
return nexus.getModule(KEY_META_TOKEN);
}
/**
* @dev Return OracleHub Module address from the Nexus
* @return Address of the OracleHub Module contract
*/
function _oracleHub() internal view returns (address) {
return nexus.getModule(KEY_ORACLE_HUB);
}
/**
* @dev Return Manager Module address from the Nexus
* @return Address of the Manager Module contract
*/
function _manager() internal view returns (address) {
return nexus.getModule(KEY_MANAGER);
}
/**
* @dev Return SavingsManager Module address from the Nexus
* @return Address of the SavingsManager Module contract
*/
function _savingsManager() internal view returns (address) {
return nexus.getModule(KEY_SAVINGS_MANAGER);
}
/**
* @dev Return Recollateraliser Module address from the Nexus
* @return Address of the Recollateraliser Module contract (Phase 2)
*/
function _recollateraliser() internal view returns (address) {
return nexus.getModule(KEY_RECOLLATERALISER);
}
}
contract InitializableReentrancyGuard {
bool private _notEntered;
function _initialize() internal {
// Storing an initial 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 percetange 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.
_notEntered = true;
}
/**
* @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 make it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_notEntered, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_notEntered = false;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_notEntered = true;
}
}
library StableMath {
using SafeMath for uint256;
/**
* @dev Scaling unit for use in specific calculations,
* where 1 * 10**18, or 1e18 represents a unit '1'
*/
uint256 private constant FULL_SCALE = 1e18;
/**
* @notice Token Ratios are used when converting between units of bAsset, mAsset and MTA
* Reasoning: Takes into account token decimals, and difference in base unit (i.e. grams to Troy oz for gold)
* @dev bAsset ratio unit for use in exact calculations,
* where (1 bAsset unit * bAsset.ratio) / ratioScale == x mAsset unit
*/
uint256 private constant RATIO_SCALE = 1e8;
/**
* @dev Provides an interface to the scaling unit
* @return Scaling unit (1e18 or 1 * 10**18)
*/
function getFullScale() internal pure returns (uint256) {
return FULL_SCALE;
}
/**
* @dev Provides an interface to the ratio unit
* @return Ratio scale unit (1e8 or 1 * 10**8)
*/
function getRatioScale() internal pure returns (uint256) {
return RATIO_SCALE;
}
/**
* @dev Scales a given integer to the power of the full scale.
* @param x Simple uint256 to scale
* @return Scaled value a to an exact number
*/
function scaleInteger(uint256 x)
internal
pure
returns (uint256)
{
return x.mul(FULL_SCALE);
}
/***************************************
PRECISE ARITHMETIC
****************************************/
/**
* @dev Multiplies two precise units, and then truncates by the full scale
* @param x Left hand input to multiplication
* @param y Right hand input to multiplication
* @return Result after multiplying the two inputs and then dividing by the shared
* scale unit
*/
function mulTruncate(uint256 x, uint256 y)
internal
pure
returns (uint256)
{
return mulTruncateScale(x, y, FULL_SCALE);
}
/**
* @dev Multiplies two precise units, and then truncates by the given scale. For example,
* when calculating 90% of 10e18, (10e18 * 9e17) / 1e18 = (9e36) / 1e18 = 9e18
* @param x Left hand input to multiplication
* @param y Right hand input to multiplication
* @param scale Scale unit
* @return Result after multiplying the two inputs and then dividing by the shared
* scale unit
*/
function mulTruncateScale(uint256 x, uint256 y, uint256 scale)
internal
pure
returns (uint256)
{
// e.g. assume scale = fullScale
// z = 10e18 * 9e17 = 9e36
uint256 z = x.mul(y);
// return 9e38 / 1e18 = 9e18
return z.div(scale);
}
/**
* @dev Multiplies two precise units, and then truncates by the full scale, rounding up the result
* @param x Left hand input to multiplication
* @param y Right hand input to multiplication
* @return Result after multiplying the two inputs and then dividing by the shared
* scale unit, rounded up to the closest base unit.
*/
function mulTruncateCeil(uint256 x, uint256 y)
internal
pure
returns (uint256)
{
// e.g. 8e17 * 17268172638 = 138145381104e17
uint256 scaled = x.mul(y);
// e.g. 138145381104e17 + 9.99...e17 = 138145381113.99...e17
uint256 ceil = scaled.add(FULL_SCALE.sub(1));
// e.g. 13814538111.399...e18 / 1e18 = 13814538111
return ceil.div(FULL_SCALE);
}
/**
* @dev Precisely divides two units, by first scaling the left hand operand. Useful
* for finding percentage weightings, i.e. 8e18/10e18 = 80% (or 8e17)
* @param x Left hand input to division
* @param y Right hand input to division
* @return Result after multiplying the left operand by the scale, and
* executing the division on the right hand input.
*/
function divPrecisely(uint256 x, uint256 y)
internal
pure
returns (uint256)
{
// e.g. 8e18 * 1e18 = 8e36
uint256 z = x.mul(FULL_SCALE);
// e.g. 8e36 / 10e18 = 8e17
return z.div(y);
}
/***************************************
RATIO FUNCS
****************************************/
/**
* @dev Multiplies and truncates a token ratio, essentially flooring the result
* i.e. How much mAsset is this bAsset worth?
* @param x Left hand operand to multiplication (i.e Exact quantity)
* @param ratio bAsset ratio
* @return Result after multiplying the two inputs and then dividing by the ratio scale
*/
function mulRatioTruncate(uint256 x, uint256 ratio)
internal
pure
returns (uint256 c)
{
return mulTruncateScale(x, ratio, RATIO_SCALE);
}
/**
* @dev Multiplies and truncates a token ratio, rounding up the result
* i.e. How much mAsset is this bAsset worth?
* @param x Left hand input to multiplication (i.e Exact quantity)
* @param ratio bAsset ratio
* @return Result after multiplying the two inputs and then dividing by the shared
* ratio scale, rounded up to the closest base unit.
*/
function mulRatioTruncateCeil(uint256 x, uint256 ratio)
internal
pure
returns (uint256)
{
// e.g. How much mAsset should I burn for this bAsset (x)?
// 1e18 * 1e8 = 1e26
uint256 scaled = x.mul(ratio);
// 1e26 + 9.99e7 = 100..00.999e8
uint256 ceil = scaled.add(RATIO_SCALE.sub(1));
// return 100..00.999e8 / 1e8 = 1e18
return ceil.div(RATIO_SCALE);
}
/**
* @dev Precisely divides two ratioed units, by first scaling the left hand operand
* i.e. How much bAsset is this mAsset worth?
* @param x Left hand operand in division
* @param ratio bAsset ratio
* @return Result after multiplying the left operand by the scale, and
* executing the division on the right hand input.
*/
function divRatioPrecisely(uint256 x, uint256 ratio)
internal
pure
returns (uint256 c)
{
// e.g. 1e14 * 1e8 = 1e22
uint256 y = x.mul(RATIO_SCALE);
// return 1e22 / 1e12 = 1e10
return y.div(ratio);
}
/***************************************
HELPERS
****************************************/
/**
* @dev Calculates minimum of two numbers
* @param x Left hand input
* @param y Right hand input
* @return Minimum of the two inputs
*/
function min(uint256 x, uint256 y)
internal
pure
returns (uint256)
{
return x > y ? y : x;
}
/**
* @dev Calculated maximum of two numbers
* @param x Left hand input
* @param y Right hand input
* @return Maximum of the two inputs
*/
function max(uint256 x, uint256 y)
internal
pure
returns (uint256)
{
return x > y ? x : y;
}
/**
* @dev Clamps a value to an upper bound
* @param x Left hand input
* @param upperBound Maximum possible value to return
* @return Input x clamped to a maximum value, upperBound
*/
function clamp(uint256 x, uint256 upperBound)
internal
pure
returns (uint256)
{
return x > upperBound ? upperBound : x;
}
}
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
// for accounts without code, i.e. `keccak256('')`
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// solhint-disable-next-line no-inline-assembly
assembly { codehash := extcodehash(account) }
return (codehash != accountHash && codehash != 0x0);
}
/**
* @dev Converts an `address` into `address payable`. Note that this is
* simply a type cast: the actual underlying value is not changed.
*
* _Available since v2.4.0._
*/
function toPayable(address account) internal pure returns (address payable) {
return address(uint160(account));
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*
* _Available since v2.4.0._
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-call-value
(bool success, ) = recipient.call.value(amount)("");
require(success, "Address: unable to send value, recipient may have reverted");
}
}
library SafeERC20 {
using SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
// solhint-disable-next-line max-line-length
require((value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves.
// A Solidity high level call has three parts:
// 1. The target address is checked to verify it contains contract code
// 2. The call itself is made, and success asserted
// 3. The return value is decoded, which in turn checks the size of the returned data.
// solhint-disable-next-line max-line-length
require(address(token).isContract(), "SafeERC20: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = address(token).call(data);
require(success, "SafeERC20: low-level call failed");
if (returndata.length > 0) { // Return data is optional
// solhint-disable-next-line max-line-length
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
library MassetHelpers {
using StableMath for uint256;
using SafeMath for uint256;
using SafeERC20 for IERC20;
function transferReturnBalance(
address _sender,
address _recipient,
address _basset,
uint256 _qty
)
internal
returns (uint256 receivedQty, uint256 recipientBalance)
{
uint256 balBefore = IERC20(_basset).balanceOf(_recipient);
IERC20(_basset).safeTransferFrom(_sender, _recipient, _qty);
recipientBalance = IERC20(_basset).balanceOf(_recipient);
receivedQty = StableMath.min(_qty, recipientBalance.sub(balBefore));
}
function safeInfiniteApprove(address _asset, address _spender)
internal
{
IERC20(_asset).safeApprove(_spender, 0);
IERC20(_asset).safeApprove(_spender, uint256(-1));
}
}
// External
// Internal
// Libs
/**
* @title Masset
* @author Stability Labs Pty. Ltd.
* @notice The Masset is a token that allows minting and redemption at a 1:1 ratio
* for underlying basket assets (bAssets) of the same peg (i.e. USD,
* EUR, Gold). Composition and validation is enforced via the BasketManager.
* @dev VERSION: 2.0
* DATE: 2020-11-14
*/
contract Masset is
Initializable,
IMasset,
InitializableToken,
InitializableModule,
InitializableReentrancyGuard
{
using StableMath for uint256;
// Forging Events
event Minted(address indexed minter, address recipient, uint256 mAssetQuantity, address bAsset, uint256 bAssetQuantity);
event MintedMulti(address indexed minter, address recipient, uint256 mAssetQuantity, address[] bAssets, uint256[] bAssetQuantities);
event Swapped(address indexed swapper, address input, address output, uint256 outputAmount, address recipient);
event Redeemed(address indexed redeemer, address recipient, uint256 mAssetQuantity, address[] bAssets, uint256[] bAssetQuantities);
event RedeemedMasset(address indexed redeemer, address recipient, uint256 mAssetQuantity);
event PaidFee(address indexed payer, address asset, uint256 feeQuantity);
// State Events
event CacheSizeChanged(uint256 cacheSize);
event SwapFeeChanged(uint256 fee);
event RedemptionFeeChanged(uint256 fee);
event ForgeValidatorChanged(address forgeValidator);
// Modules and connectors
IForgeValidator public forgeValidator;
bool private forgeValidatorLocked;
IBasketManager private basketManager;
// Basic redemption fee information
uint256 public swapFee;
uint256 private MAX_FEE;
// RELEASE 1.1 VARS
uint256 public redemptionFee;
// RELEASE 2.0 VARS
uint256 public cacheSize;
uint256 public surplus;
/**
* @dev Constructor
* @notice To avoid variable shadowing appended `Arg` after arguments name.
*/
function initialize(
string calldata _nameArg,
string calldata _symbolArg,
address _nexus,
address _forgeValidator,
address _basketManager
)
external
initializer
{
InitializableToken._initialize(_nameArg, _symbolArg);
InitializableModule._initialize(_nexus);
InitializableReentrancyGuard._initialize();
forgeValidator = IForgeValidator(_forgeValidator);
basketManager = IBasketManager(_basketManager);
MAX_FEE = 2e16;
swapFee = 6e14;
redemptionFee = 3e14;
cacheSize = 1e17;
}
/**
* @dev Verifies that the caller is the Savings Manager contract
*/
modifier onlySavingsManager() {
require(_savingsManager() == msg.sender, "Must be savings manager");
_;
}
/***************************************
MINTING (PUBLIC)
****************************************/
/**
* @dev Mint a single bAsset, at a 1:1 ratio with the bAsset. This contract
* must have approval to spend the senders bAsset
* @param _bAsset Address of the bAsset to mint
* @param _bAssetQuantity Quantity in bAsset units
* @return massetMinted Number of newly minted mAssets
*/
function mint(
address _bAsset,
uint256 _bAssetQuantity
)
external
nonReentrant
returns (uint256 massetMinted)
{
return _mintTo(_bAsset, _bAssetQuantity, msg.sender);
}
/**
* @dev Mint a single bAsset, at a 1:1 ratio with the bAsset. This contract
* must have approval to spend the senders bAsset
* @param _bAsset Address of the bAsset to mint
* @param _bAssetQuantity Quantity in bAsset units
* @param _recipient receipient of the newly minted mAsset tokens
* @return massetMinted Number of newly minted mAssets
*/
function mintTo(
address _bAsset,
uint256 _bAssetQuantity,
address _recipient
)
external
nonReentrant
returns (uint256 massetMinted)
{
return _mintTo(_bAsset, _bAssetQuantity, _recipient);
}
/**
* @dev Mint with multiple bAssets, at a 1:1 ratio to mAsset. This contract
* must have approval to spend the senders bAssets
* @param _bAssets Non-duplicate address array of bAssets with which to mint
* @param _bAssetQuantity Quantity of each bAsset to mint. Order of array
* should mirror the above
* @param _recipient Address to receive the newly minted mAsset tokens
* @return massetMinted Number of newly minted mAssets
*/
function mintMulti(
address[] calldata _bAssets,
uint256[] calldata _bAssetQuantity,
address _recipient
)
external
nonReentrant
returns(uint256 massetMinted)
{
return _mintTo(_bAssets, _bAssetQuantity, _recipient);
}
/***************************************
MINTING (INTERNAL)
****************************************/
/** @dev Mint Single */
function _mintTo(
address _bAsset,
uint256 _bAssetQuantity,
address _recipient
)
internal
returns (uint256 massetMinted)
{
require(_recipient != address(0), "Must be a valid recipient");
require(_bAssetQuantity > 0, "Quantity must not be 0");
(bool isValid, BassetDetails memory bInfo) = basketManager.prepareForgeBasset(_bAsset, _bAssetQuantity, true);
if(!isValid) return 0;
Cache memory cache = _getCacheDetails();
// Transfer collateral to the platform integration address and call deposit
address integrator = bInfo.integrator;
(uint256 quantityDeposited, uint256 ratioedDeposit) =
_depositTokens(_bAsset, bInfo.bAsset.ratio, integrator, bInfo.bAsset.isTransferFeeCharged, _bAssetQuantity, cache.maxCache);
// Validation should be after token transfer, as bAssetQty is unknown before
(bool mintValid, string memory reason) = forgeValidator.validateMint(cache.vaultBalanceSum, bInfo.bAsset, quantityDeposited);
require(mintValid, reason);
// Log the Vault increase - can only be done when basket is healthy
basketManager.increaseVaultBalance(bInfo.index, integrator, quantityDeposited);
// Mint the Masset
_mint(_recipient, ratioedDeposit);
emit Minted(msg.sender, _recipient, ratioedDeposit, _bAsset, quantityDeposited);
return ratioedDeposit;
}
/** @dev Mint Multi */
function _mintTo(
address[] memory _bAssets,
uint256[] memory _bAssetQuantities,
address _recipient
)
internal
returns (uint256 massetMinted)
{
require(_recipient != address(0), "Must be a valid recipient");
uint256 len = _bAssetQuantities.length;
require(len > 0 && len == _bAssets.length, "Input array mismatch");
// Load only needed bAssets in array
ForgePropsMulti memory props
= basketManager.prepareForgeBassets(_bAssets, _bAssetQuantities, true);
if(!props.isValid) return 0;
Cache memory cache = _getCacheDetails();
uint256 mAssetQuantity = 0;
uint256[] memory receivedQty = new uint256[](len);
// Transfer the Bassets to the integrator, update storage and calc MassetQ
for(uint256 i = 0; i < len; i++){
uint256 bAssetQuantity = _bAssetQuantities[i];
if(bAssetQuantity > 0){
// bAsset == bAssets[i] == basket.bassets[indexes[i]]
Basset memory bAsset = props.bAssets[i];
(uint256 quantityDeposited, uint256 ratioedDeposit) =
_depositTokens(bAsset.addr, bAsset.ratio, props.integrators[i], bAsset.isTransferFeeCharged, bAssetQuantity, cache.maxCache);
receivedQty[i] = quantityDeposited;
mAssetQuantity = mAssetQuantity.add(ratioedDeposit);
}
}
require(mAssetQuantity > 0, "No masset quantity to mint");
basketManager.increaseVaultBalances(props.indexes, props.integrators, receivedQty);
// Validate the proposed mint, after token transfer
(bool mintValid, string memory reason) = forgeValidator.validateMintMulti(cache.vaultBalanceSum, props.bAssets, receivedQty);
require(mintValid, reason);
// Mint the Masset
_mint(_recipient, mAssetQuantity);
emit MintedMulti(msg.sender, _recipient, mAssetQuantity, _bAssets, _bAssetQuantities);
return mAssetQuantity;
}
/**
* @dev Deposits a given asset to the system. If there is sufficient room for the asset
* in the cache, then just transfer, otherwise reset the cache to the desired mid level by
* depositing the delta in the platform
*/
function _depositTokens(
address _bAsset,
uint256 _bAssetRatio,
address _integrator,
bool _hasTxFee,
uint256 _quantity,
uint256 _maxCache
)
internal
returns (uint256 quantityDeposited, uint256 ratioedDeposit)
{
// 1 - Send all to PI, using the opportunity to get the cache balance and net amount transferred
(uint256 transferred, uint256 cacheBal) = MassetHelpers.transferReturnBalance(msg.sender, _integrator, _bAsset, _quantity);
// 2 - Deposit X if necessary
// - Can account here for non-lending market integrated bAssets by simply checking for
// integrator == address(0) || address(this) and then keeping entirely in cache
// 2.1 - Deposit if xfer fees
if(_hasTxFee){
uint256 deposited = IPlatformIntegration(_integrator).deposit(_bAsset, transferred, true);
quantityDeposited = StableMath.min(deposited, _quantity);
}
// 2.2 - Else Deposit X if Cache > %
else {
// This check is in place to ensure that any token with a txFee is rejected
// Audit notes: Assumption made that if no fee is collected here then there is no txfee
require(transferred == _quantity, "Asset not fully transferred");
quantityDeposited = transferred;
uint256 relativeMaxCache = _maxCache.divRatioPrecisely(_bAssetRatio);
if(cacheBal > relativeMaxCache){
uint256 delta = cacheBal.sub(relativeMaxCache.div(2));
IPlatformIntegration(_integrator).deposit(_bAsset, delta, false);
}
}
ratioedDeposit = quantityDeposited.mulRatioTruncate(_bAssetRatio);
}
/***************************************
SWAP (PUBLIC)
****************************************/
struct SwapArgs {
address input;
address output;
address recipient;
}
/**
* @dev Simply swaps one bAsset for another bAsset or this mAsset at a 1:1 ratio.
* bAsset <> bAsset swaps will incur a small fee (swapFee()). Swap
* is valid if it does not result in the input asset exceeding its maximum weight.
* @param _input bAsset to deposit
* @param _output Asset to receive - either a bAsset or mAsset(this)
* @param _quantity Units of input bAsset to swap
* @param _recipient Address to credit output asset
* @return output Units of output asset returned
*/
function swap(
address _input,
address _output,
uint256 _quantity,
address _recipient
)
external
nonReentrant
returns (uint256 output)
{
// Struct created to avoid Stack Too Deep errors. Minor gas cost increase.
SwapArgs memory args = SwapArgs(_input, _output, _recipient);
require(args.input != address(0) && args.output != address(0), "Invalid swap asset addresses");
require(args.input != args.output, "Cannot swap the same asset");
require(args.recipient != address(0), "Missing recipient address");
require(_quantity > 0, "Invalid quantity");
// 1. If the output is this mAsset, just mint
if(args.output == address(this)){
return _mintTo(args.input, _quantity, args.recipient);
}
// 2. Grab all relevant info from the Manager
(bool isValid, string memory reason, BassetDetails memory inputDetails, BassetDetails memory outputDetails) =
basketManager.prepareSwapBassets(args.input, args.output, false);
require(isValid, reason);
Cache memory cache = _getCacheDetails();
// 3. Deposit the input tokens
(uint256 amnountIn, ) =
_depositTokens(args.input, inputDetails.bAsset.ratio, inputDetails.integrator, inputDetails.bAsset.isTransferFeeCharged, _quantity, cache.maxCache);
// 3.1. Update the input balance
basketManager.increaseVaultBalance(inputDetails.index, inputDetails.integrator, amnountIn);
// 4. Validate the swap
(bool swapValid, string memory swapValidityReason, uint256 swapOutput, bool applySwapFee) =
forgeValidator.validateSwap(cache.vaultBalanceSum, inputDetails.bAsset, outputDetails.bAsset, amnountIn);
require(swapValid, swapValidityReason);
require(swapOutput > 0, "Must withdraw something");
// 5. Settle the swap
// 5.0. Redeclare recipient to avoid stack depth error
address recipient = args.recipient;
// 5.1. Decrease output bal
Amount memory amt = _withdrawTokens(
WithdrawArgs({
quantity: swapOutput,
bAsset: args.output,
integrator: outputDetails.integrator,
feeRate: applySwapFee ? swapFee : 0,
hasTxFee: outputDetails.bAsset.isTransferFeeCharged,
recipient: recipient,
ratio: outputDetails.bAsset.ratio,
maxCache: cache.maxCache,
vaultBalance: outputDetails.bAsset.vaultBalance
})
);
basketManager.decreaseVaultBalance(outputDetails.index, outputDetails.integrator, amt.net);
surplus = cache.surplus.add(amt.scaledFee);
emit Swapped(msg.sender, args.input, args.output, amt.net, recipient);
return amt.net;
}
/**
* @dev Determines both if a trade is valid, and the expected fee or output.
* Swap is valid if it does not result in the input asset exceeding its maximum weight.
* @param _input bAsset to deposit
* @param _output Asset to receive - bAsset or mAsset(this)
* @param _quantity Units of input bAsset to swap
* @return valid Bool to signify that swap is current valid
* @return reason If swap is invalid, this is the reason
* @return output Units of _output asset the trade would return
*/
function getSwapOutput(
address _input,
address _output,
uint256 _quantity
)
external
view
returns (bool, string memory, uint256 output)
{
require(_input != address(0) && _output != address(0), "Invalid swap asset addresses");
require(_input != _output, "Cannot swap the same asset");
bool isMint = _output == address(this);
uint256 quantity = _quantity;
// 1. Get relevant asset data
(bool isValid, string memory reason, BassetDetails memory inputDetails, BassetDetails memory outputDetails) =
basketManager.prepareSwapBassets(_input, _output, isMint);
if(!isValid){
return (false, reason, 0);
}
Cache memory cache = _getCacheDetails();
// 2. check if trade is valid
// 2.1. If output is mAsset(this), then calculate a simple mint
if(isMint){
// Validate mint
(isValid, reason) = forgeValidator.validateMint(cache.vaultBalanceSum, inputDetails.bAsset, quantity);
if(!isValid) return (false, reason, 0);
// Simply cast the quantity to mAsset
output = quantity.mulRatioTruncate(inputDetails.bAsset.ratio);
return(true, "", output);
}
// 2.2. If a bAsset swap, calculate the validity, output and fee
else {
(bool swapValid, string memory swapValidityReason, uint256 swapOutput, bool applySwapFee) =
forgeValidator.validateSwap(cache.vaultBalanceSum, inputDetails.bAsset, outputDetails.bAsset, quantity);
if(!swapValid){
return (false, swapValidityReason, 0);
}
// 3. Return output and fee, if any
if(applySwapFee){
(, swapOutput) = _calcSwapFee(swapOutput, swapFee);
}
return (true, "", swapOutput);
}
}
/***************************************
REDEMPTION (PUBLIC)
****************************************/
/**
* @dev Credits the sender with a certain quantity of selected bAsset, in exchange for burning the
* relative mAsset quantity from the sender. Sender also incurs a small mAsset fee, if any.
* @param _bAsset Address of the bAsset to redeem
* @param _bAssetQuantity Units of the bAsset to redeem
* @return massetMinted Relative number of mAsset units burned to pay for the bAssets
*/
function redeem(
address _bAsset,
uint256 _bAssetQuantity
)
external
nonReentrant
returns (uint256 massetRedeemed)
{
return _redeemTo(_bAsset, _bAssetQuantity, msg.sender);
}
/**
* @dev Credits a recipient with a certain quantity of selected bAsset, in exchange for burning the
* relative Masset quantity from the sender. Sender also incurs a small fee, if any.
* @param _bAsset Address of the bAsset to redeem
* @param _bAssetQuantity Units of the bAsset to redeem
* @param _recipient Address to credit with withdrawn bAssets
* @return massetMinted Relative number of mAsset units burned to pay for the bAssets
*/
function redeemTo(
address _bAsset,
uint256 _bAssetQuantity,
address _recipient
)
external
nonReentrant
returns (uint256 massetRedeemed)
{
return _redeemTo(_bAsset, _bAssetQuantity, _recipient);
}
/**
* @dev Credits a recipient with a certain quantity of selected bAssets, in exchange for burning the
* relative Masset quantity from the sender. Sender also incurs a small fee on the outgoing asset.
* @param _bAssets Address of the bAssets to redeem
* @param _bAssetQuantities Units of the bAssets to redeem
* @param _recipient Address to credit with withdrawn bAssets
* @return massetMinted Relative number of mAsset units burned to pay for the bAssets
*/
function redeemMulti(
address[] calldata _bAssets,
uint256[] calldata _bAssetQuantities,
address _recipient
)
external
nonReentrant
returns (uint256 massetRedeemed)
{
return _redeemTo(_bAssets, _bAssetQuantities, _recipient);
}
/**
* @dev Credits a recipient with a proportionate amount of bAssets, relative to current vault
* balance levels and desired mAsset quantity. Burns the mAsset as payment.
* @param _mAssetQuantity Quantity of mAsset to redeem
* @param _recipient Address to credit the withdrawn bAssets
*/
function redeemMasset(
uint256 _mAssetQuantity,
address _recipient
)
external
nonReentrant
{
_redeemMasset(_mAssetQuantity, _recipient);
}
/***************************************
REDEMPTION (INTERNAL)
****************************************/
/** @dev Casting to arrays for use in redeemMulti func */
function _redeemTo(
address _bAsset,
uint256 _bAssetQuantity,
address _recipient
)
internal
returns (uint256 massetRedeemed)
{
address[] memory bAssets = new address[](1);
uint256[] memory quantities = new uint256[](1);
bAssets[0] = _bAsset;
quantities[0] = _bAssetQuantity;
return _redeemTo(bAssets, quantities, _recipient);
}
/** @dev Redeem mAsset for one or more bAssets */
function _redeemTo(
address[] memory _bAssets,
uint256[] memory _bAssetQuantities,
address _recipient
)
internal
returns (uint256 massetRedeemed)
{
require(_recipient != address(0), "Must be a valid recipient");
uint256 bAssetCount = _bAssetQuantities.length;
require(bAssetCount > 0 && bAssetCount == _bAssets.length, "Input array mismatch");
// Prepare relevant data
RedeemProps memory props = basketManager.prepareRedeemBassets(_bAssets);
if(!props.isValid) return 0;
Cache memory cache = _getCacheDetails();
// Validate redemption
(bool redemptionValid, string memory reason, bool applyFee) =
forgeValidator.validateRedemption(false, cache.vaultBalanceSum, props.allBassets, props.indexes, _bAssetQuantities);
require(redemptionValid, reason);
uint256 mAssetQuantity = 0;
// Calc total redeemed mAsset quantity
for(uint256 i = 0; i < bAssetCount; i++){
uint256 bAssetQuantity = _bAssetQuantities[i];
if(bAssetQuantity > 0){
// Calc equivalent mAsset amount
uint256 ratioedBasset = bAssetQuantity.mulRatioTruncateCeil(props.bAssets[i].ratio);
mAssetQuantity = mAssetQuantity.add(ratioedBasset);
}
}
require(mAssetQuantity > 0, "Must redeem some bAssets");
// Redemption has fee? Fetch the rate
uint256 fee = applyFee ? swapFee : 0;
// Apply fees, burn mAsset and return bAsset to recipient
_settleRedemption(
RedemptionSettlement({
recipient: _recipient,
mAssetQuantity: mAssetQuantity,
bAssetQuantities: _bAssetQuantities,
indices: props.indexes,
integrators: props.integrators,
feeRate: fee,
bAssets: props.bAssets,
cache: cache
})
);
emit Redeemed(msg.sender, _recipient, mAssetQuantity, _bAssets, _bAssetQuantities);
return mAssetQuantity;
}
/** @dev Redeem mAsset for a multiple bAssets */
function _redeemMasset(
uint256 _mAssetQuantity,
address _recipient
)
internal
{
require(_recipient != address(0), "Must be a valid recipient");
require(_mAssetQuantity > 0, "Invalid redemption quantity");
// Fetch high level details
RedeemPropsMulti memory props = basketManager.prepareRedeemMulti();
uint256 colRatio = StableMath.min(props.colRatio, StableMath.getFullScale());
// Ensure payout is related to the collateralised mAsset quantity
uint256 collateralisedMassetQuantity = _mAssetQuantity.mulTruncate(colRatio);
// Calculate redemption quantities
(bool redemptionValid, string memory reason, uint256[] memory bAssetQuantities) =
forgeValidator.calculateRedemptionMulti(collateralisedMassetQuantity, props.bAssets);
require(redemptionValid, reason);
// Apply fees, burn mAsset and return bAsset to recipient
_settleRedemption(
RedemptionSettlement({
recipient: _recipient,
mAssetQuantity: _mAssetQuantity,
bAssetQuantities: bAssetQuantities,
indices: props.indexes,
integrators: props.integrators,
feeRate: redemptionFee,
bAssets: props.bAssets,
cache: _getCacheDetails()
})
);
emit RedeemedMasset(msg.sender, _recipient, _mAssetQuantity);
}
/**
* @param _recipient Recipient of the bAssets
* @param _mAssetQuantity Total amount of mAsset to burn from sender
* @param _bAssetQuantities Array of bAsset quantities
* @param _indices Matching indices for the bAsset array
* @param _integrators Matching integrators for the bAsset array
* @param _feeRate Fee rate to be applied to this redemption
* @param _bAssets Array of bAssets to redeem
*/
struct RedemptionSettlement {
address recipient;
uint256 mAssetQuantity;
uint256[] bAssetQuantities;
uint8[] indices;
address[] integrators;
uint256 feeRate;
Basset[] bAssets;
Cache cache;
}
/**
* @dev Internal func to update contract state post-redemption,
* burning sufficient mAsset before withdrawing all tokens
*/
function _settleRedemption(
RedemptionSettlement memory args
) internal {
// 1.0. Burn the full amount of Masset
_burn(msg.sender, args.mAssetQuantity);
// 2.0. Transfer the Bassets to the recipient and count fees
uint256 bAssetCount = args.bAssets.length;
uint256[] memory netAmounts = new uint256[](bAssetCount);
uint256 fees = 0;
for(uint256 i = 0; i < bAssetCount; i++){
Amount memory amt = _withdrawTokens(
WithdrawArgs({
quantity: args.bAssetQuantities[i],
bAsset: args.bAssets[i].addr,
integrator: args.integrators[i],
feeRate: args.feeRate,
hasTxFee: args.bAssets[i].isTransferFeeCharged,
recipient: args.recipient,
ratio: args.bAssets[i].ratio,
maxCache: args.cache.maxCache,
vaultBalance: args.bAssets[i].vaultBalance
})
);
// 2.1. Log the net amounts (output - fee)
netAmounts[i] = amt.net;
// 2.2. Accumulate scaled fees
fees = fees.add(amt.scaledFee);
}
// 2.3. Log the collected fees to the surplus
surplus = args.cache.surplus.add(fees);
// 3.0. Reduce the vaultBalances by the **net** amount
basketManager.decreaseVaultBalances(args.indices, args.integrators, netAmounts);
}
struct WithdrawArgs {
uint256 quantity;
address bAsset;
address integrator;
uint256 feeRate;
bool hasTxFee;
address recipient;
uint256 ratio;
uint256 maxCache;
uint256 vaultBalance;
}
/**
* @dev Withdraws a given asset from its platformIntegration. If there is sufficient liquidity
* in the cache, then withdraw from there, otherwise withdraw from the lending market and reset the
* cache to the mid level.
* @param args All args needed for a full withdrawal
* @return amount Struct containing the desired output, output-fee, and the scaled fee
*/
function _withdrawTokens(WithdrawArgs memory args) internal returns (Amount memory amount) {
if(args.quantity > 0){
// 1. Deduct the redemption fee, if any, and log quantities
amount = _deductSwapFee(args.bAsset, args.quantity, args.feeRate, args.ratio);
// 2. If txFee then short circuit - there is no cache
if(args.hasTxFee){
IPlatformIntegration(args.integrator).withdraw(args.recipient, args.bAsset, amount.net, amount.net, true);
}
// 3. Else, withdraw from either cache or main vault
else {
uint256 cacheBal = IERC20(args.bAsset).balanceOf(args.integrator);
// 3.1 - If balance b in cache, simply withdraw
if(cacheBal >= amount.net) {
IPlatformIntegration(args.integrator).withdrawRaw(args.recipient, args.bAsset, amount.net);
}
// 3.2 - Else reset the cache to X, or as far as possible
// - Withdraw X+b from platform
// - Send b to user
else {
uint256 relativeMidCache = args.maxCache.divRatioPrecisely(args.ratio).div(2);
uint256 totalWithdrawal = StableMath.min(relativeMidCache.add(amount.net).sub(cacheBal), args.vaultBalance.sub(cacheBal));
IPlatformIntegration(args.integrator).withdraw(
args.recipient,
args.bAsset,
amount.net,
totalWithdrawal,
false
);
}
}
}
}
/***************************************
INTERNAL
****************************************/
struct Amount {
uint256 gross;
uint256 net;
uint256 scaledFee;
}
/**
* @dev Calculates the output amount from a given bAsset quantity and fee, and returns in a helpful struct
* @param _asset Asset upon which the fee is being deducted
* @param _bAssetQuantity Exact amount of the bAsset
* @param _feeRate Percentage fee rate
* @param _ratio bAsset ratio, to calculate the scaled fee
* @return struct containing input, input-fee, and a scaled fee
*/
function _deductSwapFee(address _asset, uint256 _bAssetQuantity, uint256 _feeRate, uint256 _ratio)
private
returns (Amount memory)
{
if(_feeRate > 0){
(uint256 fee, uint256 output) = _calcSwapFee(_bAssetQuantity, _feeRate);
emit PaidFee(msg.sender, _asset, fee);
return Amount(_bAssetQuantity, output, fee.mulRatioTruncate(_ratio));
}
return Amount(_bAssetQuantity, _bAssetQuantity, 0);
}
/**
* @dev Calculates the output amount from a given bAsset quantity and fee
* @param _bAssetQuantity Exact amount of bAsset being swapped out
* @param _feeRate Percentage rate of fee
* @return feeAmount Fee in output asset units
* @return outputMinusFee Input minus fee
*/
function _calcSwapFee(uint256 _bAssetQuantity, uint256 _feeRate)
private
pure
returns (uint256 feeAmount, uint256 outputMinusFee)
{
// e.g. for 500 massets.
// feeRate == 1% == 1e16. _quantity == 5e20.
// (5e20 * 1e16) / 1e18 = 5e18
feeAmount = _bAssetQuantity.mulTruncate(_feeRate);
outputMinusFee = _bAssetQuantity.sub(feeAmount);
}
/**
* vaultBalanceSum = totalSupply + 'surplus'
* maxCache = vaultBalanceSum * (cacheSize / 1e18)
* surplus is simply surplus, to reduce SLOADs
*/
struct Cache {
uint256 vaultBalanceSum;
uint256 maxCache;
uint256 surplus;
}
/**
* @dev Gets the supply and cache details for the mAsset, taking into account the surplus
* @return Cache containing (tracked) sum of vault balances, ideal cache size and surplus
*/
function _getCacheDetails() internal view returns (Cache memory) {
uint256 _surplus = surplus;
uint256 sum = totalSupply().add(_surplus);
return Cache(sum, sum.mulTruncate(cacheSize), _surplus);
}
/***************************************
STATE
****************************************/
/**
* @dev Sets the MAX cache size for each bAsset. The cache will actually revolve around
* _cacheSize * totalSupply / 2 under normal circumstances.
* @param _cacheSize Maximum percent of total mAsset supply to hold for each bAsset
*/
function setCacheSize(uint256 _cacheSize)
external
onlyGovernance
{
require(_cacheSize <= 2e17, "Must be <= 20%");
cacheSize = _cacheSize;
emit CacheSizeChanged(_cacheSize);
}
/**
* @dev Upgrades the version of ForgeValidator protocol. Governor can do this
* only while ForgeValidator is unlocked.
* @param _newForgeValidator Address of the new ForgeValidator
*/
function upgradeForgeValidator(address _newForgeValidator)
external
onlyGovernor
{
require(!forgeValidatorLocked, "Must be allowed to upgrade");
require(_newForgeValidator != address(0), "Must be non null address");
forgeValidator = IForgeValidator(_newForgeValidator);
emit ForgeValidatorChanged(_newForgeValidator);
}
/**
* @dev Locks the ForgeValidator into it's final form. Called by Governor
*/
function lockForgeValidator()
external
onlyGovernor
{
forgeValidatorLocked = true;
}
/**
* @dev Set the ecosystem fee for redeeming a mAsset
* @param _swapFee Fee calculated in (%/100 * 1e18)
*/
function setSwapFee(uint256 _swapFee)
external
onlyGovernor
{
require(_swapFee <= MAX_FEE, "Rate must be within bounds");
swapFee = _swapFee;
emit SwapFeeChanged(_swapFee);
}
/**
* @dev Set the ecosystem fee for redeeming a mAsset
* @param _redemptionFee Fee calculated in (%/100 * 1e18)
*/
function setRedemptionFee(uint256 _redemptionFee)
external
onlyGovernor
{
require(_redemptionFee <= MAX_FEE, "Rate must be within bounds");
redemptionFee = _redemptionFee;
emit RedemptionFeeChanged(_redemptionFee);
}
/**
* @dev Gets the address of the BasketManager for this mAsset
* @return basketManager Address
*/
function getBasketManager()
external
view
returns (address)
{
return address(basketManager);
}
/***************************************
INFLATION
****************************************/
/**
* @dev Converts recently accrued swap fees into mAsset
* @return swapFeesGained Equivalent amount of mAsset units that have been generated
* @return newSupply New total mAsset supply
*/
function collectInterest()
external
onlySavingsManager
nonReentrant
returns (uint256 swapFeesGained, uint256 newSupply)
{
uint256 toMint = 0;
// Set the surplus variable to 1 to optimise for SSTORE costs.
// If setting to 0 here, it would save 5k per savings deposit, but cost 20k for the
// first surplus call (a SWAP or REDEEM).
if(surplus > 1){
toMint = surplus.sub(1);
surplus = 1;
// mint new mAsset to savings manager
_mint(msg.sender, toMint);
emit MintedMulti(address(this), address(this), toMint, new address[](0), new uint256[](0));
}
return (toMint, totalSupply());
}
/**
* @dev Collects the interest generated from the Basket, minting a relative
* amount of mAsset and sending it over to the SavingsManager.
* @return interestGained Lending market interest collected
* @return newSupply New total mAsset supply
*/
function collectPlatformInterest()
external
onlySavingsManager
nonReentrant
returns (uint256 interestGained, uint256 newSupply)
{
// 1. Collect interest from Basket
(uint256 interestCollected, uint256[] memory gains) = basketManager.collectInterest();
// 2. Mint to SM
_mint(msg.sender, interestCollected);
emit MintedMulti(address(this), address(this), interestCollected, new address[](0), gains);
return (interestCollected, totalSupply());
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"cacheSize","type":"uint256"}],"name":"CacheSizeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"forgeValidator","type":"address"}],"name":"ForgeValidatorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"mAssetQuantity","type":"uint256"},{"indexed":false,"internalType":"address","name":"bAsset","type":"address"},{"indexed":false,"internalType":"uint256","name":"bAssetQuantity","type":"uint256"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"mAssetQuantity","type":"uint256"},{"indexed":false,"internalType":"address[]","name":"bAssets","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"bAssetQuantities","type":"uint256[]"}],"name":"MintedMulti","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"payer","type":"address"},{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"feeQuantity","type":"uint256"}],"name":"PaidFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"redeemer","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"mAssetQuantity","type":"uint256"},{"indexed":false,"internalType":"address[]","name":"bAssets","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"bAssetQuantities","type":"uint256[]"}],"name":"Redeemed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"redeemer","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"mAssetQuantity","type":"uint256"}],"name":"RedeemedMasset","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"RedemptionFeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"SwapFeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"swapper","type":"address"},{"indexed":false,"internalType":"address","name":"input","type":"address"},{"indexed":false,"internalType":"address","name":"output","type":"address"},{"indexed":false,"internalType":"uint256","name":"outputAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"}],"name":"Swapped","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cacheSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"collectInterest","outputs":[{"internalType":"uint256","name":"swapFeesGained","type":"uint256"},{"internalType":"uint256","name":"newSupply","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"collectPlatformInterest","outputs":[{"internalType":"uint256","name":"interestGained","type":"uint256"},{"internalType":"uint256","name":"newSupply","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"forgeValidator","outputs":[{"internalType":"contract IForgeValidator","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBasketManager","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_input","type":"address"},{"internalType":"address","name":"_output","type":"address"},{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"getSwapOutput","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"string","name":"","type":"string"},{"internalType":"uint256","name":"output","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"_nameArg","type":"string"},{"internalType":"string","name":"_symbolArg","type":"string"},{"internalType":"address","name":"_nexus","type":"address"},{"internalType":"address","name":"_forgeValidator","type":"address"},{"internalType":"address","name":"_basketManager","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"lockForgeValidator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_bAsset","type":"address"},{"internalType":"uint256","name":"_bAssetQuantity","type":"uint256"}],"name":"mint","outputs":[{"internalType":"uint256","name":"massetMinted","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"_bAssets","type":"address[]"},{"internalType":"uint256[]","name":"_bAssetQuantity","type":"uint256[]"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"mintMulti","outputs":[{"internalType":"uint256","name":"massetMinted","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_bAsset","type":"address"},{"internalType":"uint256","name":"_bAssetQuantity","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"mintTo","outputs":[{"internalType":"uint256","name":"massetMinted","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"nexus","outputs":[{"internalType":"contract INexus","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_bAsset","type":"address"},{"internalType":"uint256","name":"_bAssetQuantity","type":"uint256"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"massetRedeemed","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_mAssetQuantity","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"redeemMasset","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"_bAssets","type":"address[]"},{"internalType":"uint256[]","name":"_bAssetQuantities","type":"uint256[]"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"redeemMulti","outputs":[{"internalType":"uint256","name":"massetRedeemed","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_bAsset","type":"address"},{"internalType":"uint256","name":"_bAssetQuantity","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"redeemTo","outputs":[{"internalType":"uint256","name":"massetRedeemed","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"redemptionFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_cacheSize","type":"uint256"}],"name":"setCacheSize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_redemptionFee","type":"uint256"}],"name":"setRedemptionFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_swapFee","type":"uint256"}],"name":"setSwapFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"surplus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_input","type":"address"},{"internalType":"address","name":"_output","type":"address"},{"internalType":"uint256","name":"_quantity","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"swap","outputs":[{"internalType":"uint256","name":"output","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"swapFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_newForgeValidator","type":"address"}],"name":"upgradeForgeValidator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6080604052615bc6806100136000396000f3fe608060405234801561001057600080fd5b50600436106102115760003560e01c8063674a64e011610125578063a457c2d7116100ad578063d7d522661161007c578063d7d5226614610435578063db0ed6a01461043d578063dd62ed3e14610450578063eeea5d3614610463578063fb2c92231461047857610211565b8063a457c2d7146103e9578063a9059cbb146103fc578063aa3053b01461040f578063abe743ff1461042257610211565b80637dbc1df0116100f45780637dbc1df01461039e5780637e8901ea146103b157806384f9378a146103b957806395d89b41146103cc578063a3f5c1d2146103d457610211565b8063674a64e01461034e5780636e81221c1461035657806370a082311461036957806372ea90761461037c57610211565b80632a2fab22116101a857806340c10f191161017757806340c10f1914610310578063438b1b4b14610323578063458f58151461033657806354cf2aeb1461033e5780635d864ced1461034657610211565b80632a2fab22146102bf578063313ce567146102d557806334e19907146102ea57806339509351146102fd57610211565b80631820783d116101e45780631820783d146102715780631e9a69501461028657806323b872dd1461029957806326bbe60a146102ac57610211565b806306fdde0314610216578063095ea7b314610234578063138885651461025457806318160ddd14610269575b600080fd5b61021e61048b565b60405161022b91906156c5565b60405180910390f35b610247610242366004614227565b610522565b60405161022b919061560c565b61025c610540565b60405161022b91906156a9565b61025c610546565b61028461027f3660046146a0565b61054c565b005b61025c610294366004614227565b610618565b6102476102a7366004614179565b610677565b6102846102ba366004614103565b610705565b6102c76107d8565b60405161022b929190615986565b6102dd6108eb565b60405161022b9190615994565b6102846102f83660046146a0565b6108f4565b61024761030b366004614227565b610983565b61025c61031e366004614227565b6109d7565b61025c610331366004614257565b610a1b565b61025c610a7b565b61025c610a81565b610284610a87565b61025c610ad4565b61025c6103643660046141c6565b610ada565b61025c610377366004614103565b611039565b61038f61038a366004614179565b611058565b60405161022b9392919061561a565b6102846103ac3660046146a0565b6113ae565b6102c761143d565b61025c6103c736600461429a565b6115ab565b61021e61166e565b6103dc6116cf565b60405161022b91906156b7565b6102476103f7366004614227565b6116de565b61024761040a366004614227565b61174c565b61025c61041d36600461429a565b611760565b6102846104303660046146dc565b611805565b6103dc61185c565b61028461044b366004614559565b61186b565b61025c61045e36600461413f565b6119d6565b61046b611a01565b60405161022b919061539f565b61025c610486366004614257565b611a10565b60368054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156105175780601f106104ec57610100808354040283529160200191610517565b820191906000526020600020905b8154815290600101906020018083116104fa57829003601f168201915b505050505090505b90565b600061053661052f611a54565b8484611a58565b5060015b92915050565b60485481565b60355490565b610554611b0c565b6001600160a01b0316336001600160a01b0316148061058b5750610576611b8e565b6001600160a01b0316336001600160a01b0316145b6105b05760405162461bcd60e51b81526004016105a7906156f6565b60405180910390fd5b6702c68af0bb1400008111156105d85760405162461bcd60e51b81526004016105a7906157d6565b60478190556040517f2f5a6b1defeafd30e7568ea5c176aa0702b0af5b00ba41fa20e58b2c72e8afe79061060d9083906156a9565b60405180910390a150565b604154600090600160a01b900460ff166106445760405162461bcd60e51b81526004016105a7906158a6565b6041805460ff60a01b1916905561065c838333611bd9565b90506041805460ff60a01b1916600160a01b17905592915050565b6000610684848484611c7f565b6106fa84610690611a54565b6106f585604051806060016040528060288152602001615b37602891396001600160a01b038a166000908152603460205260408120906106ce611a54565b6001600160a01b03168152602081019190915260400160002054919063ffffffff611d9516565b611a58565b5060015b9392505050565b61070d611b0c565b6001600160a01b0316336001600160a01b03161461073d5760405162461bcd60e51b81526004016105a790615786565b604254600160a01b900460ff16156107675760405162461bcd60e51b81526004016105a7906157f6565b6001600160a01b03811661078d5760405162461bcd60e51b81526004016105a7906157a6565b604280546001600160a01b0319166001600160a01b0383161790556040517f2e137a82d7f7fe8a4c453313f3d08557c162ad9d78219a2e937e318b41e12f7a9061060d90839061539f565b600080336107e4611dc1565b6001600160a01b03161461080a5760405162461bcd60e51b81526004016105a790615756565b604154600160a01b900460ff166108335760405162461bcd60e51b81526004016105a7906158a6565b6041805460ff60a01b19169055604854600090600110156108c65760485461086290600163ffffffff611df416565b600160485590506108733382611e36565b604080516000808252602082019081528183019283905230927f7d3ff197e9071095bd36b627028ef523ecf46fcbf17cbde745a4b65aec88b6bc926108bd92859287929190615505565b60405180910390a25b806108cf610546565b92509250506041805460ff60a01b1916600160a01b1790559091565b60385460ff1690565b6108fc611b0c565b6001600160a01b0316336001600160a01b03161461092c5760405162461bcd60e51b81526004016105a790615786565b60455481111561094e5760405162461bcd60e51b81526004016105a790615826565b60448190556040517f9cabc14d438714dbcd9292df9b3f89c42f98acd93a675ad72cd6033777e9b8e79061060d9083906156a9565b6000610536610990611a54565b846106f585603460006109a1611a54565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff611ef616565b604154600090600160a01b900460ff16610a035760405162461bcd60e51b81526004016105a7906158a6565b6041805460ff60a01b1916905561065c838333611f1b565b604154600090600160a01b900460ff16610a475760405162461bcd60e51b81526004016105a7906158a6565b6041805460ff60a01b19169055610a5f848484611f1b565b90506041805460ff60a01b1916600160a01b1790559392505050565b60465481565b60445481565b610a8f611b0c565b6001600160a01b0316336001600160a01b031614610abf5760405162461bcd60e51b81526004016105a790615786565b6042805460ff60a01b1916600160a01b179055565b60475481565b604154600090600160a01b900460ff16610b065760405162461bcd60e51b81526004016105a7906158a6565b6041805460ff60a01b19169055610b1b6139a1565b50604080516060810182526001600160a01b038088168083528782166020840152908516928201929092529015801590610b61575060208101516001600160a01b031615155b610b7d5760405162461bcd60e51b81526004016105a790615806565b80602001516001600160a01b031681600001516001600160a01b03161415610bb75760405162461bcd60e51b81526004016105a790615776565b60408101516001600160a01b0316610be15760405162461bcd60e51b81526004016105a790615726565b60008411610c015760405162461bcd60e51b81526004016105a790615796565b60208101516001600160a01b0316301415610c3157610c298160000151858360400151611f1b565b91505061101e565b60006060610c3d6139c1565b610c456139c1565b60435485516020870151604051632bf596cf60e01b81526001600160a01b0390931692632bf596cf92610c7f9290916000906004016153ad565b60006040518083038186803b158015610c9757600080fd5b505afa158015610cab573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cd3919081019061444e565b9350935093509350838390610cfb5760405162461bcd60e51b81526004016105a791906156c5565b50610d046139e8565b610d0c6121cf565b90506000610d3a876000015185600001516060015186602001518760000151604001518e876020015161222b565b506043546040808701516020880151915163371a1b2360e21b81529394506001600160a01b039092169263dc686c8c92610d7a92909186906004016159a2565b600060405180830381600087803b158015610d9457600080fd5b505af1158015610da8573d6000803e3d6000fd5b5050604254845187518751604051638da25c0960e01b81526000965060609550869485946001600160a01b0390911693638da25c0993610dec938b90600401615926565b60006040518083038186803b158015610e0457600080fd5b505afa158015610e18573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e4091908101906144bc565b9350935093509350838390610e685760405162461bcd60e51b81526004016105a791906156c5565b5060008211610e895760405162461bcd60e51b81526004016105a7906158b6565b60408b0151610e966139e8565b610f2e6040518061012001604052808681526020018f602001516001600160a01b031681526020018b602001516001600160a01b0316815260200185610edd576000610ee1565b6044545b81526020018b600001516040015115158152602001846001600160a01b031681526020018b600001516060015181526020018a6020015181526020018b6000015160a001518152506123ee565b6043546040808c01516020808e0151908501519251632e8b67a160e11b81529495506001600160a01b0390931693635d16cf4293610f709390916004016159a2565b600060405180830381600087803b158015610f8a57600080fd5b505af1158015610f9e573d6000803e3d6000fd5b50505050610fbd81604001518960400151611ef690919063ffffffff16565b6048558c516020808f01519083015160405133937f202522f7dbbb826f03c2adf78dedea2ede1e5cf8a67a041843a7b43e529011d49361100393919290919088906153fd565b60405180910390a2602001519c505050505050505050505050505b6041805460ff60a01b1916600160a01b179055949350505050565b6001600160a01b0381166000908152603360205260409020545b919050565b60006060816001600160a01b0386161580159061107d57506001600160a01b03851615155b6110995760405162461bcd60e51b81526004016105a790615806565b846001600160a01b0316866001600160a01b031614156110cb5760405162461bcd60e51b81526004016105a790615776565b6001600160a01b038516301484600060606110e46139c1565b6110ec6139c1565b604354604051632bf596cf60e01b81526001600160a01b0390911690632bf596cf90611120908f908f908b906004016153ad565b60006040518083038186803b15801561113857600080fd5b505afa15801561114c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611174919081019061444e565b9350935093509350836111965750600097509095508694506113a59350505050565b61119e6139e8565b6111a66121cf565b90508615611293576042548151845160405163df95633560e01b81526001600160a01b039093169263df956335926111e49290918b9060040161595d565b60006040518083038186803b1580156111fc57600080fd5b505afa158015611210573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611238919081019061433c565b9095509350846112585750600098509196508795506113a5945050505050565b82516060015161126f90879063ffffffff6126a616565b60408051602081019091526000815260019b50995097506113a59650505050505050565b60006060600080604260009054906101000a90046001600160a01b03166001600160a01b0316638da25c098660000151896000015189600001518e6040518563ffffffff1660e01b81526004016112ed9493929190615926565b60006040518083038186803b15801561130557600080fd5b505afa158015611319573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261134191908101906144bc565b935093509350935083611368575060009c50909a508b99506113a598505050505050505050565b801561137e5761137a826044546126b7565b9250505b5060408051602081019091526000815260019d509b5099506113a598505050505050505050565b93509350939050565b6113b6611b0c565b6001600160a01b0316336001600160a01b0316146113e65760405162461bcd60e51b81526004016105a790615786565b6045548111156114085760405162461bcd60e51b81526004016105a790615826565b60468190556040517f4dbf9634a3aaf3bc15ab627faeaac7c6b0a4754ead77206f1c11277356f2878f9061060d9083906156a9565b60008033611449611dc1565b6001600160a01b03161461146f5760405162461bcd60e51b81526004016105a790615756565b604154600160a01b900460ff166114985760405162461bcd60e51b81526004016105a7906158a6565b6041805460ff60a01b1916905560435460408051631517d59160e11b815290516000926060926001600160a01b0390911691632a2fab2291600480820192879290919082900301818387803b1580156114f057600080fd5b505af1158015611504573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261152c91908101906146fb565b9150915061153a3383611e36565b6040805160008152602081019182905230917f7d3ff197e9071095bd36b627028ef523ecf46fcbf17cbde745a4b65aec88b6bc9161157d91849187918790615546565b60405180910390a28161158e610546565b9350935050506041805460ff60a01b1916600160a01b1790559091565b604154600090600160a01b900460ff166115d75760405162461bcd60e51b81526004016105a7906158a6565b6041805460ff60a01b1916905560408051602080880282810182019093528782526116509289918991829185019084908082843760009201919091525050604080516020808a028281018201909352898252909350899250889182918501908490808284376000920191909152508792506126e5915050565b90506041805460ff60a01b1916600160a01b17905595945050505050565b60378054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156105175780601f106104ec57610100808354040283529160200191610517565b6041546001600160a01b031681565b60006105366116eb611a54565b846106f585604051806060016040528060258152602001615b5f6025913960346000611715611a54565b6001600160a01b03908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff611d9516565b6000610536611759611a54565b8484611c7f565b604154600090600160a01b900460ff1661178c5760405162461bcd60e51b81526004016105a7906158a6565b6041805460ff60a01b1916905560408051602080880282810182019093528782526116509289918991829185019084908082843760009201919091525050604080516020808a02828101820190935289825290935089925088918291850190849080828437600092019190915250879250612a8f915050565b604154600160a01b900460ff1661182e5760405162461bcd60e51b81526004016105a7906158a6565b6041805460ff60a01b191690556118458282612dcb565b50506041805460ff60a01b1916600160a01b179055565b6042546001600160a01b031681565b600054610100900460ff16806118845750611884613032565b80611892575060005460ff16155b6118ae5760405162461bcd60e51b81526004016105a790615836565b600054610100900460ff161580156118d9576000805460ff1961ff0019909116610100171660011790555b61194c88888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a915089908190840183828082843760009201919091525061303892505050565b61195584613048565b61195d613094565b604280546001600160a01b038086166001600160a01b031992831617909255604380549285169290911691909117905566470de4df820000604555660221b262dd8000604455660110d9316ec00060465567016345785d8a000060475580156119cc576000805461ff00191690555b5050505050505050565b6001600160a01b03918216600090815260346020908152604080832093909416825291909152205490565b6043546001600160a01b031690565b604154600090600160a01b900460ff16611a3c5760405162461bcd60e51b81526004016105a7906158a6565b6041805460ff60a01b19169055610a5f848484611bd9565b3390565b6001600160a01b038316611a7e5760405162461bcd60e51b81526004016105a790615866565b6001600160a01b038216611aa45760405162461bcd60e51b81526004016105a790615706565b6001600160a01b0380841660008181526034602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590611aff9085906156a9565b60405180910390a3505050565b6041546040805163030d028960e21b815290516000926001600160a01b031691630c340a24916004808301926020929190829003018186803b158015611b5157600080fd5b505afa158015611b65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611b899190810190614121565b905090565b6041546039546040516385acd64160e01b81526000926001600160a01b0316916385acd64191611bc191906004016156a9565b60206040518083038186803b158015611b5157600080fd5b604080516001808252818301909252600091606091906020808301908038833950506040805160018082528183019092529293506060929150602080830190803883390190505090508582600081518110611c3057fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508481600081518110611c5e57fe5b602002602001018181525050611c75828286612a8f565b9695505050505050565b6001600160a01b038316611ca55760405162461bcd60e51b81526004016105a790615856565b6001600160a01b038216611ccb5760405162461bcd60e51b81526004016105a7906156d6565b611d0e81604051806060016040528060268152602001615b11602691396001600160a01b038616600090815260336020526040902054919063ffffffff611d9516565b6001600160a01b038085166000908152603360205260408082209390935590841681522054611d43908263ffffffff611ef616565b6001600160a01b0380841660008181526033602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611aff9085906156a9565b60008184841115611db95760405162461bcd60e51b81526004016105a791906156c5565b505050900390565b6041546040805490516385acd64160e01b81526000926001600160a01b0316916385acd64191611bc191906004016156a9565b60006106fe83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611d95565b6001600160a01b038216611e5c5760405162461bcd60e51b81526004016105a7906158d6565b603554611e6f908263ffffffff611ef616565b6035556001600160a01b038216600090815260336020526040902054611e9b908263ffffffff611ef616565b6001600160a01b0383166000818152603360205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611eea9085906156a9565b60405180910390a35050565b6000828201838110156106fe5760405162461bcd60e51b81526004016105a790615716565b60006001600160a01b038216611f435760405162461bcd60e51b81526004016105a790615896565b60008311611f635760405162461bcd60e51b81526004016105a7906157e6565b6000611f6d6139c1565b60435460405163bf9ca02d60e01b81526001600160a01b039091169063bf9ca02d90611fa29089908990600190600401615573565b61012060405180830381600087803b158015611fbd57600080fd5b505af1158015611fd1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611ff59190810190614528565b9150915081612009576000925050506106fe565b6120116139e8565b6120196121cf565b90506000826020015190506000806120498a866000015160600151858860000151604001518d896020015161222b565b6042548651885160405163df95633560e01b81529496509294506000936060936001600160a01b039093169263df9563359261208c92909190899060040161595d565b60006040518083038186803b1580156120a457600080fd5b505afa1580156120b8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526120e0919081019061433c565b915091508181906121045760405162461bcd60e51b81526004016105a791906156c5565b50604354604080890151905163371a1b2360e21b81526001600160a01b039092169163dc686c8c9161213c91899089906004016159a2565b600060405180830381600087803b15801561215657600080fd5b505af115801561216a573d6000803e3d6000fd5b505050506121788a84611e36565b336001600160a01b03167f30873c596f54a2e2e09894670d7e1a48b2433c00204f81fbedf557353c36e7c78b858f886040516121b7949392919061548f565b60405180910390a250909a9950505050505050505050565b6121d76139e8565b60485460006121f4826121e8610546565b9063ffffffff611ef616565b9050604051806060016040528082815260200161221c604754846130a990919063ffffffff16565b81526020019290925250905090565b60008060008061223d33898c896130be565b9150915086156122e1576040516307dba22560e31b81526000906001600160a01b038a1690633edd11289061227b908e908790600190600401615573565b602060405180830381600087803b15801561229557600080fd5b505af11580156122a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506122cd91908101906146be565b90506122d981886131fa565b9450506123cf565b8582146123005760405162461bcd60e51b81526004016105a7906157c6565b90925082906000612317868b63ffffffff61320916565b9050808211156123cd57600061234461233783600263ffffffff61323a16565b849063ffffffff611df416565b6040516307dba22560e31b81529091506001600160a01b038b1690633edd112890612378908f908590600090600401615573565b602060405180830381600087803b15801561239257600080fd5b505af11580156123a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506123ca91908101906146be565b50505b505b6123df848a63ffffffff6126a616565b92505050965096945050505050565b6123f66139e8565b815115611053576124198260200151836000015184606001518560c0015161327c565b90508160800151156124a35760408083015160a084015160208086015190850151935163c89fc72f60e01b81526001600160a01b039093169363c89fc72f9361246c939291908190600190600401615432565b600060405180830381600087803b15801561248657600080fd5b505af115801561249a573d6000803e3d6000fd5b50505050611053565b600082602001516001600160a01b03166370a0823184604001516040518263ffffffff1660e01b81526004016124d9919061539f565b60206040518083038186803b1580156124f157600080fd5b505afa158015612505573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061252991908101906146be565b9050816020015181106125ad5782604001516001600160a01b031663a4e285958460a00151856020015185602001516040518463ffffffff1660e01b8152600401612576939291906153d5565b600060405180830381600087803b15801561259057600080fd5b505af11580156125a4573d6000803e3d6000fd5b505050506126a0565b60006125db60026125cf8660c001518760e0015161320990919063ffffffff16565b9063ffffffff61323a16565b90506000612624612609846125fd876020015186611ef690919063ffffffff16565b9063ffffffff611df416565b61010087015161261f908663ffffffff611df416565b6131fa565b905084604001516001600160a01b031663c89fc72f8660a00151876020015187602001518560006040518663ffffffff1660e01b815260040161266b959493929190615432565b600060405180830381600087803b15801561268557600080fd5b505af1158015612699573d6000803e3d6000fd5b5050505050505b50919050565b60006106fe83836305f5e100613334565b6000806126ca848463ffffffff6130a916565b91506126dc848363ffffffff611df416565b90509250929050565b60006001600160a01b03821661270d5760405162461bcd60e51b81526004016105a790615896565b8251801580159061271e5750845181145b61273a5760405162461bcd60e51b81526004016105a790615736565b612742613a09565b604354604051639d01cd3560e01b81526001600160a01b0390911690639d01cd3590612777908990899060019060040161559f565b600060405180830381600087803b15801561279157600080fd5b505af11580156127a5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526127cd9190810190614604565b80519091506127e1576000925050506106fe565b6127e96139e8565b6127f16121cf565b90506000809050606084604051908082528060200260200182016040528015612824578160200160208202803883390190505b50905060005b858110156128e857600089828151811061284057fe5b6020026020010151905060008111156128df5761285b613a33565b8660200151838151811061286b57fe5b602002602001015190506000806128ad836000015184606001518b60400151888151811061289557fe5b60200260200101518660400151888d6020015161222b565b91509150818686815181106128be57fe5b60209081029190910101526128d9878263ffffffff611ef616565b96505050505b5060010161282a565b50600082116129095760405162461bcd60e51b81526004016105a790615766565b6043546060850151604080870151905163d5e1d27960e01b81526001600160a01b039093169263d5e1d2799261294592909186906004016155d3565b600060405180830381600087803b15801561295f57600080fd5b505af1158015612973573d6000803e3d6000fd5b505060425485516020880151604051634566eb0960e01b815260009550606094506001600160a01b0390931692634566eb09926129b69290918890600401615906565b60006040518083038186803b1580156129ce57600080fd5b505afa1580156129e2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612a0a919081019061433c565b91509150818190612a2e5760405162461bcd60e51b81526004016105a791906156c5565b50612a398985611e36565b336001600160a01b03167f7d3ff197e9071095bd36b627028ef523ecf46fcbf17cbde745a4b65aec88b6bc8a868e8e604051612a7894939291906154c4565b60405180910390a250919998505050505050505050565b60006001600160a01b038216612ab75760405162461bcd60e51b81526004016105a790615896565b82518015801590612ac85750845181145b612ae45760405162461bcd60e51b81526004016105a790615736565b612aec613a6c565b60435460405163c0e46a2f60e01b81526001600160a01b039091169063c0e46a2f90612b1c90899060040161558e565b60006040518083038186803b158015612b3457600080fd5b505afa158015612b48573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612b70919081019061466c565b8051909150612b84576000925050506106fe565b612b8c6139e8565b612b946121cf565b9050600060606000604260009054906101000a90046001600160a01b03166001600160a01b0316638fb1860b60008660000151886020015189608001518e6040518663ffffffff1660e01b8152600401612bf2959493929190615649565b60006040518083038186803b158015612c0a57600080fd5b505afa158015612c1e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612c4691908101906143f4565b925092509250828290612c6c5760405162461bcd60e51b81526004016105a791906156c5565b506000805b87811015612ce95760008b8281518110612c8757fe5b602002602001015190506000811115612ce0576000612cca89604001518481518110612caf57fe5b6020026020010151606001518361336290919063ffffffff16565b9050612cdc848263ffffffff611ef616565b9350505b50600101612c71565b5060008111612d0a5760405162461bcd60e51b81526004016105a7906157b6565b600082612d18576000612d1c565b6044545b9050612d756040518061010001604052808c6001600160a01b031681526020018481526020018d8152602001896080015181526020018960600151815260200183815260200189604001518152602001888152506133b4565b336001600160a01b03167f93fc955b3f6c5e7b37fbb64f39e6f4d9050f82ed17cec724743f95a50da7df1c8b848f8f604051612db494939291906154c4565b60405180910390a2509a9950505050505050505050565b6001600160a01b038116612df15760405162461bcd60e51b81526004016105a790615896565b60008211612e115760405162461bcd60e51b81526004016105a790615886565b612e19613a9d565b604360009054906101000a90046001600160a01b03166001600160a01b03166343ae78be6040518163ffffffff1660e01b815260040160006040518083038186803b158015612e6757600080fd5b505afa158015612e7b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612ea39190810190614638565b90506000612eb7826000015161261f6135e0565b90506000612ecb858363ffffffff6130a916565b604254602085015160405162201e2d60e41b815292935060009260609283926001600160a01b0390911691630201e2d091612f0b918891906004016158e6565b60006040518083038186803b158015612f2357600080fd5b505afa158015612f37573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612f5f9190810190614383565b925092509250828290612f855760405162461bcd60e51b81526004016105a791906156c5565b50612fe5604051806101000160405280896001600160a01b031681526020018a81526020018381526020018860600151815260200188604001518152602001604654815260200188602001518152602001612fde6121cf565b90526133b4565b336001600160a01b03167f6e8e3f900293b89801cb29bf5dc5c402c685e66d588bed50a3d83ffbf0bb9034888a604051613020929190615474565b60405180910390a25050505050505050565b303b1590565b613044828260126135ec565b5050565b6001600160a01b03811661306e5760405162461bcd60e51b81526004016105a7906156e6565b604180546001600160a01b0319166001600160a01b03831617905561309161362c565b50565b6041805460ff60a01b1916600160a01b179055565b60006106fe8383670de0b6b3a7640000613334565b6000806000846001600160a01b03166370a08231876040518263ffffffff1660e01b81526004016130ef919061539f565b60206040518083038186803b15801561310757600080fd5b505afa15801561311b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061313f91908101906146be565b905061315c6001600160a01b03861688888763ffffffff6136db16565b6040516370a0823160e01b81526001600160a01b038616906370a082319061318890899060040161539f565b60206040518083038186803b1580156131a057600080fd5b505afa1580156131b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506131d891908101906146be565b91506131ee8461261f848463ffffffff611df416565b92505094509492505050565b60008183116126a057826106fe565b600080613220846305f5e10063ffffffff61373c16565b9050613232818463ffffffff61323a16565b949350505050565b60006106fe83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613776565b6132846139e8565b82156133115760008061329786866126b7565b91509150336001600160a01b03167f02f19ecb5bbcd7b0f0cb034005563f7ad115132d0beb073b5d32697ca94bbaa188846040516132d6929190615474565b60405180910390a26040805160608101825287815260208101839052908101613305848763ffffffff6126a616565b81525092505050613232565b505060408051606081018252838152602081019390935260009083015250919050565b600080613347858563ffffffff61373c16565b9050613359818463ffffffff61323a16565b95945050505050565b600080613375848463ffffffff61373c16565b9050600061339e6133916305f5e100600163ffffffff611df416565b839063ffffffff611ef616565b9050613359816305f5e10063ffffffff61323a16565b6133c23382602001516137ad565b60c0810151516040805182815260208084028201019091526060908280156133f4578160200160208202803883390190505b5090506000805b838110156135595761340b6139e8565b61351a6040518061012001604052808860400151858151811061342a57fe5b602002602001015181526020018860c00151858151811061344757fe5b6020026020010151600001516001600160a01b031681526020018860800151858151811061347157fe5b60200260200101516001600160a01b031681526020018860a0015181526020018860c0015185815181106134a157fe5b6020026020010151604001511515815260200188600001516001600160a01b031681526020018860c0015185815181106134d757fe5b60200260200101516060015181526020018860e001516020015181526020018860c00151858151811061350657fe5b602002602001015160a001518152506123ee565b9050806020015184838151811061352d57fe5b6020908102919091010152604081015161354e90849063ffffffff611ef616565b9250506001016133fb565b5060e084015160400151613573908263ffffffff611ef616565b604855604354606085015160808601516040516388a90f5160e01b81526001600160a01b03909316926388a90f51926135b292909187906004016155d3565b600060405180830381600087803b1580156135cc57600080fd5b505af11580156119cc573d6000803e3d6000fd5b670de0b6b3a764000090565b82516135ff906036906020860190613ac5565b508151613613906037906020850190613ac5565b506038805460ff191660ff929092169190911790555050565b6040516136389061537e565b60405190819003812060395561364d90615352565b604051908190038120603a5561366290615389565b604051908190038120603b5561367790615373565b604051908190038120603c5561368c90615368565b604051908190038120603d556136a19061535d565b604051908190038120603e556136b690615394565b604051908190038120603f556136cb90615347565b6040518091039020604081905550565b6040516137369085906323b872dd60e01b906136ff908790879087906024016153d5565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613883565b50505050565b60008261374b5750600061053a565b8282028284828161375857fe5b04146106fe5760405162461bcd60e51b81526004016105a790615816565b600081836137975760405162461bcd60e51b81526004016105a791906156c5565b5060008385816137a357fe5b0495945050505050565b6001600160a01b0382166137d35760405162461bcd60e51b81526004016105a790615846565b61381681604051806060016040528060228152602001615aef602291396001600160a01b038516600090815260336020526040902054919063ffffffff611d9516565b6001600160a01b038316600090815260336020526040902055603554613842908263ffffffff611df416565b6035556040516000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611eea9085906156a9565b613895826001600160a01b0316613968565b6138b15760405162461bcd60e51b81526004016105a7906158c6565b60006060836001600160a01b0316836040516138cd919061533b565b6000604051808303816000865af19150503d806000811461390a576040519150601f19603f3d011682016040523d82523d6000602084013e61390f565b606091505b5091509150816139315760405162461bcd60e51b81526004016105a790615746565b805115613736578080602001905161394c919081019061431e565b6137365760405162461bcd60e51b81526004016105a790615876565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590613232575050151592915050565b604080516060810182526000808252602082018190529181019190915290565b60405180606001604052806139d4613a33565b815260006020820181905260409091015290565b60405180606001604052806000815260200160008152602001600081525090565b60405180608001604052806000151581526020016060815260200160608152602001606081525090565b6040805160c081019091526000808252602082019081526020016000151581526020016000815260200160008152602001600081525090565b6040518060a00160405280600015158152602001606081526020016060815260200160608152602001606081525090565b6040518060800160405280600081526020016060815260200160608152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613b0657805160ff1916838001178555613b33565b82800160010185558215613b33579182015b82811115613b33578251825591602001919060010190613b18565b50613b3f929150613b43565b5090565b61051f91905b80821115613b3f5760008155600101613b49565b803561053a81615ab2565b805161053a81615ab2565b60008083601f840112613b8557600080fd5b5081356001600160401b03811115613b9c57600080fd5b602083019150836020820283011115613bb457600080fd5b9250929050565b600082601f830112613bcc57600080fd5b8151613bdf613bda826159d6565b6159b0565b91508181835260208401935060208101905083856020840282011115613c0457600080fd5b60005b83811015613c305781613c1a8882613b68565b8452506020928301929190910190600101613c07565b5050505092915050565b600082601f830112613c4b57600080fd5b8151613c59613bda826159d6565b915081818352602084019350602081019050838560c0840282011115613c7e57600080fd5b60005b83811015613c305781613c948882613e8e565b84525060209092019160c09190910190600101613c81565b600082601f830112613cbd57600080fd5b8151613ccb613bda826159d6565b91508181835260208401935060208101905083856020840282011115613cf057600080fd5b60005b83811015613c305781613d0688826140ed565b8452506020928301929190910190600101613cf3565b600082601f830112613d2d57600080fd5b8151613d3b613bda826159d6565b91508181835260208401935060208101905083856020840282011115613d6057600080fd5b60005b83811015613c305781613d7688826140f8565b8452506020928301929190910190600101613d63565b805161053a81615ac6565b805161053a81615acf565b60008083601f840112613db457600080fd5b5081356001600160401b03811115613dcb57600080fd5b602083019150836001820283011115613bb457600080fd5b600082601f830112613df457600080fd5b8151613e02613bda826159f6565b91508082526020830160208301858383011115613e1e57600080fd5b613e29838284615a72565b50505092915050565b60006101008284031215613e4557600080fd5b613e4f60606159b0565b90506000613e5d8484613e8e565b82525060c0613e6e84848301613b68565b60208301525060e0613e82848285016140f8565b60408301525092915050565b600060c08284031215613ea057600080fd5b613eaa60c06159b0565b90506000613eb88484613b68565b8252506020613ec984848301613d97565b6020830152506040613edd84828501613d8c565b6040830152506060613ef1848285016140ed565b6060830152506080613f05848285016140ed565b60808301525060a0613f19848285016140ed565b60a08301525092915050565b600060808284031215613f3757600080fd5b613f4160806159b0565b90506000613f4f8484613d8c565b82525060208201516001600160401b03811115613f6b57600080fd5b613f7784828501613c3a565b60208301525060408201516001600160401b03811115613f9657600080fd5b613fa284828501613bbb565b60408301525060608201516001600160401b03811115613fc157600080fd5b613fcd84828501613d1c565b60608301525092915050565b600060808284031215613feb57600080fd5b613ff560806159b0565b90506000613f4f84846140ed565b600060a0828403121561401557600080fd5b61401f60a06159b0565b9050600061402d8484613d8c565b82525060208201516001600160401b0381111561404957600080fd5b61405584828501613c3a565b60208301525060408201516001600160401b0381111561407457600080fd5b61408084828501613c3a565b60408301525060608201516001600160401b0381111561409f57600080fd5b6140ab84828501613bbb565b60608301525060808201516001600160401b038111156140ca57600080fd5b6140d684828501613d1c565b60808301525092915050565b803561053a81615adc565b805161053a81615adc565b805161053a81615ae5565b60006020828403121561411557600080fd5b60006132328484613b5d565b60006020828403121561413357600080fd5b60006132328484613b68565b6000806040838503121561415257600080fd5b600061415e8585613b5d565b925050602061416f85828601613b5d565b9150509250929050565b60008060006060848603121561418e57600080fd5b600061419a8686613b5d565b93505060206141ab86828701613b5d565b92505060406141bc868287016140e2565b9150509250925092565b600080600080608085870312156141dc57600080fd5b60006141e88787613b5d565b94505060206141f987828801613b5d565b935050604061420a878288016140e2565b925050606061421b87828801613b5d565b91505092959194509250565b6000806040838503121561423a57600080fd5b60006142468585613b5d565b925050602061416f858286016140e2565b60008060006060848603121561426c57600080fd5b60006142788686613b5d565b9350506020614289868287016140e2565b92505060406141bc86828701613b5d565b6000806000806000606086880312156142b257600080fd5b85356001600160401b038111156142c857600080fd5b6142d488828901613b73565b955095505060208601356001600160401b038111156142f257600080fd5b6142fe88828901613b73565b9350935050604061431188828901613b5d565b9150509295509295909350565b60006020828403121561433057600080fd5b60006132328484613d8c565b6000806040838503121561434f57600080fd5b600061435b8585613d8c565b92505060208301516001600160401b0381111561437757600080fd5b61416f85828601613de3565b60008060006060848603121561439857600080fd5b60006143a48686613d8c565b93505060208401516001600160401b038111156143c057600080fd5b6143cc86828701613de3565b92505060408401516001600160401b038111156143e857600080fd5b6141bc86828701613cac565b60008060006060848603121561440957600080fd5b60006144158686613d8c565b93505060208401516001600160401b0381111561443157600080fd5b61443d86828701613de3565b92505060406141bc86828701613d8c565b600080600080610240858703121561446557600080fd5b60006144718787613d8c565b94505060208501516001600160401b0381111561448d57600080fd5b61449987828801613de3565b93505060406144aa87828801613e32565b92505061014061421b87828801613e32565b600080600080608085870312156144d257600080fd5b60006144de8787613d8c565b94505060208501516001600160401b038111156144fa57600080fd5b61450687828801613de3565b9350506040614517878288016140ed565b925050606061421b87828801613d8c565b600080610120838503121561453c57600080fd5b60006145488585613d8c565b925050602061416f85828601613e32565b600080600080600080600060a0888a03121561457457600080fd5b87356001600160401b0381111561458a57600080fd5b6145968a828b01613da2565b975097505060208801356001600160401b038111156145b457600080fd5b6145c08a828b01613da2565b955095505060406145d38a828b01613b5d565b93505060606145e48a828b01613b5d565b92505060806145f58a828b01613b5d565b91505092959891949750929550565b60006020828403121561461657600080fd5b81516001600160401b0381111561462c57600080fd5b61323284828501613f25565b60006020828403121561464a57600080fd5b81516001600160401b0381111561466057600080fd5b61323284828501613fd9565b60006020828403121561467e57600080fd5b81516001600160401b0381111561469457600080fd5b61323284828501614003565b6000602082840312156146b257600080fd5b600061323284846140e2565b6000602082840312156146d057600080fd5b600061323284846140ed565b600080604083850312156146ef57600080fd5b600061415e85856140e2565b6000806040838503121561470e57600080fd5b600061471a85856140ed565b92505060208301516001600160401b0381111561473657600080fd5b61416f85828601613cac565b600061474e8383614782565b505060200190565b600061476283836152c2565b505060c00190565b600061474e8383614979565b600061474e8383615332565b61478b81615a30565b82525050565b600061479c82615a23565b6147a68185615a27565b93506147b183615a1d565b8060005b838110156147df5781516147c98882614742565b97506147d483615a1d565b9250506001016147b5565b509495945050505050565b60006147f582615a23565b6147ff8185615a27565b935061480a83615a1d565b8060005b838110156147df5781516148228882614742565b975061482d83615a1d565b92505060010161480e565b600061484382615a23565b61484d8185615a27565b935061485883615a1d565b8060005b838110156147df5781516148708882614756565b975061487b83615a1d565b92505060010161485c565b600061489182615a23565b61489b8185615a27565b93506148a683615a1d565b8060005b838110156147df5781516148be888261476a565b97506148c983615a1d565b9250506001016148aa565b60006148df82615a23565b6148e98185615a27565b93506148f483615a1d565b8060005b838110156147df57815161490c888261476a565b975061491783615a1d565b9250506001016148f8565b600061492d82615a23565b6149378185615a27565b935061494283615a1d565b8060005b838110156147df57815161495a8882614776565b975061496583615a1d565b925050600101614946565b61478b81615a3b565b61478b8161051f565b600061498d82615a23565b6149978185611053565b93506149a7818560208601615a72565b9290920192915050565b61478b81615a5c565b61478b81615a67565b60006149ce82615a23565b6149d88185615a27565b93506149e8818560208601615a72565b6149f181615a9e565b9093019392505050565b6000614a08602383615a27565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647281526265737360e81b602082015260400192915050565b6000614a4d601583615a27565b744e657875732061646472657373206973207a65726f60581b815260200192915050565b6000614a7e600e83611053565b6d29b0bb34b733b9a6b0b730b3b2b960911b8152600e0192915050565b6000614aa8601b83615a27565b7f4f6e6c7920676f7665726e616e63652063616e20657865637574650000000000815260200192915050565b6000614ae1600783611053565b665374616b696e6760c81b815260070192915050565b6000614b04602283615a27565b7f45524332303a20617070726f766520746f20746865207a65726f206164647265815261737360f01b602082015260400192915050565b6000614b48601b83615a27565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000614b81601083611053565b6f2932b1b7b63630ba32b930b634b9b2b960811b815260100192915050565b6000614bad601983615a27565b7f4d697373696e6720726563697069656e74206164647265737300000000000000815260200192915050565b6000614be6601483615a27565b73092dce0eae840c2e4e4c2f240dad2e6dac2e8c6d60631b815260200192915050565b6000614c16602083615a27565b7f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815260200192915050565b6000614c4f601783615a27565b7f4d75737420626520736176696e6773206d616e61676572000000000000000000815260200192915050565b6000614c88601a83615a27565b7f4e6f206d6173736574207175616e7469747920746f206d696e74000000000000815260200192915050565b6000614cc1601a83615a27565b7f43616e6e6f742073776170207468652073616d65206173736574000000000000815260200192915050565b6000614cfa601983615a27565b7f4f6e6c7920676f7665726e6f722063616e206578656375746500000000000000815260200192915050565b6000614d33600783611053565b6626b0b730b3b2b960c91b815260070192915050565b6000614d56601083615a27565b6f496e76616c6964207175616e7469747960801b815260200192915050565b6000614d82601883615a27565b7f4d757374206265206e6f6e206e756c6c20616464726573730000000000000000815260200192915050565b6000614dbb601883615a27565b7f4d7573742072656465656d20736f6d6520624173736574730000000000000000815260200192915050565b6000614df4601b83615a27565b7f4173736574206e6f742066756c6c79207472616e736665727265640000000000815260200192915050565b6000614e2d600e83615a27565b6d4d757374206265203c3d2032302560901b815260200192915050565b6000614e57601683615a27565b7505175616e74697479206d757374206e6f7420626520360541b815260200192915050565b6000614e89601a83615a27565b7f4d75737420626520616c6c6f77656420746f2075706772616465000000000000815260200192915050565b6000614ec2600983611053565b6827b930b1b632a43ab160b91b815260090192915050565b6000614ee7601c83615a27565b7f496e76616c696420737761702061737365742061646472657373657300000000815260200192915050565b6000614f20602183615a27565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000614f63600a83611053565b69476f7665726e616e636560b01b8152600a0192915050565b6000614f89600a83611053565b69283937bc3ca0b236b4b760b11b8152600a0192915050565b6000614faf601a83615a27565b7f52617465206d7573742062652077697468696e20626f756e6473000000000000815260200192915050565b6000614fe8602e83615a27565b7f436f6e747261637420696e7374616e63652068617320616c726561647920626581526d195b881a5b9a5d1a585b1a5e995960921b602082015260400192915050565b6000615038602183615a27565b7f45524332303a206275726e2066726f6d20746865207a65726f206164647265738152607360f81b602082015260400192915050565b600061507b602583615a27565b7f45524332303a207472616e736665722066726f6d20746865207a65726f206164815264647265737360d81b602082015260400192915050565b60006150c2602483615a27565b7f45524332303a20617070726f76652066726f6d20746865207a65726f206164648152637265737360e01b602082015260400192915050565b6000615108602a83615a27565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e8152691bdd081cdd58d8d9595960b21b602082015260400192915050565b6000615154601b83615a27565b7f496e76616c696420726564656d7074696f6e207175616e746974790000000000815260200192915050565b600061518d601983615a27565b7f4d75737420626520612076616c696420726563697069656e7400000000000000815260200192915050565b60006151c6600983611053565b6826b2ba30aa37b5b2b760b91b815260090192915050565b60006151eb601f83615a27565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00815260200192915050565b6000615224601783615a27565b7f4d75737420776974686472617720736f6d657468696e67000000000000000000815260200192915050565b600061525d601f83615a27565b7f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400815260200192915050565b6000615296601f83615a27565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300815260200192915050565b805160c08301906152d38482614782565b5060208201516152e660208501826149ba565b5060408201516152f96040850182614970565b50606082015161530c6060850182614979565b50608082015161531f6080850182614979565b5060a082015161373660a0850182614979565b61478b81615a56565b60006106fe8284614982565b600061053a82614a71565b600061053a82614ad4565b600061053a82614b74565b600061053a82614d26565b600061053a82614eb5565b600061053a82614f56565b600061053a82614f7c565b600061053a826151b9565b6020810161053a8284614782565b606081016153bb8286614782565b6153c86020830185614782565b6132326040830184614970565b606081016153e38286614782565b6153f06020830185614782565b6132326040830184614979565b6080810161540b8287614782565b6154186020830186614782565b6154256040830185614979565b6133596060830184614782565b60a081016154408288614782565b61544d6020830187614782565b61545a6040830186614979565b6154676060830185614979565b611c756080830184614970565b604081016154828285614782565b6106fe6020830184614979565b6080810161549d8287614782565b6154aa6020830186614979565b6154b76040830185614782565b6133596060830184614979565b608081016154d28287614782565b6154df6020830186614979565b81810360408301526154f18185614791565b90508181036060830152611c758184614886565b608081016155138287614782565b6155206020830186614979565b818103604083015261553281856147ea565b90508181036060830152611c7581846148d4565b608081016155548287614782565b6155616020830186614979565b81810360408301526154f181856147ea565b606081016155818286614782565b6153c86020830185614979565b602080825281016106fe8184614791565b606080825281016155b08186614791565b905081810360208301526155c48185614886565b90506132326040830184614970565b606080825281016155e48186614922565b905081810360208301526155f881856147ea565b905081810360408301526133598184614886565b6020810161053a8284614970565b606081016156288286614970565b818103602083015261563a81856149c3565b90506132326040830184614979565b60a081016156578288614970565b6156646020830187614979565b81810360408301526156768186614838565b9050818103606083015261568a8185614922565b9050818103608083015261569e8184614886565b979650505050505050565b6020810161053a8284614979565b6020810161053a82846149b1565b602080825281016106fe81846149c3565b6020808252810161053a816149fb565b6020808252810161053a81614a40565b6020808252810161053a81614a9b565b6020808252810161053a81614af7565b6020808252810161053a81614b3b565b6020808252810161053a81614ba0565b6020808252810161053a81614bd9565b6020808252810161053a81614c09565b6020808252810161053a81614c42565b6020808252810161053a81614c7b565b6020808252810161053a81614cb4565b6020808252810161053a81614ced565b6020808252810161053a81614d49565b6020808252810161053a81614d75565b6020808252810161053a81614dae565b6020808252810161053a81614de7565b6020808252810161053a81614e20565b6020808252810161053a81614e4a565b6020808252810161053a81614e7c565b6020808252810161053a81614eda565b6020808252810161053a81614f13565b6020808252810161053a81614fa2565b6020808252810161053a81614fdb565b6020808252810161053a8161502b565b6020808252810161053a8161506e565b6020808252810161053a816150b5565b6020808252810161053a816150fb565b6020808252810161053a81615147565b6020808252810161053a81615180565b6020808252810161053a816151de565b6020808252810161053a81615217565b6020808252810161053a81615250565b6020808252810161053a81615289565b604081016158f48285614979565b81810360208301526132328184614838565b606081016159148286614979565b81810360208301526155f88185614838565b6101c081016159358287614979565b61594260208301866152c2565b61594f60e08301856152c2565b6133596101a0830184614979565b610100810161596c8286614979565b61597960208301856152c2565b61323260e0830184614979565b604081016154828285614979565b6020810161053a8284615332565b606081016153e38286615332565b6040518181016001600160401b03811182821017156159ce57600080fd5b604052919050565b60006001600160401b038211156159ec57600080fd5b5060209081020190565b60006001600160401b03821115615a0c57600080fd5b506020601f91909101601f19160190565b60200190565b5190565b90815260200190565b600061053a82615a4a565b151590565b8061105381615aa8565b6001600160a01b031690565b60ff1690565b600061053a82615a30565b600061053a82615a40565b60005b83811015615a8d578181015183820152602001615a75565b838111156137365750506000910152565b601f01601f191690565b6008811061309157fe5b615abb81615a30565b811461309157600080fd5b615abb81615a3b565b6008811061309157600080fd5b615abb8161051f565b615abb81615a5656fe45524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa365627a7a72315820f5ed41c5aeed2ab4675d2568bba346b7c92a0e8ad5807d86520159ec0cc290a76c6578706572696d656e74616cf564736f6c63430005100040
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102115760003560e01c8063674a64e011610125578063a457c2d7116100ad578063d7d522661161007c578063d7d5226614610435578063db0ed6a01461043d578063dd62ed3e14610450578063eeea5d3614610463578063fb2c92231461047857610211565b8063a457c2d7146103e9578063a9059cbb146103fc578063aa3053b01461040f578063abe743ff1461042257610211565b80637dbc1df0116100f45780637dbc1df01461039e5780637e8901ea146103b157806384f9378a146103b957806395d89b41146103cc578063a3f5c1d2146103d457610211565b8063674a64e01461034e5780636e81221c1461035657806370a082311461036957806372ea90761461037c57610211565b80632a2fab22116101a857806340c10f191161017757806340c10f1914610310578063438b1b4b14610323578063458f58151461033657806354cf2aeb1461033e5780635d864ced1461034657610211565b80632a2fab22146102bf578063313ce567146102d557806334e19907146102ea57806339509351146102fd57610211565b80631820783d116101e45780631820783d146102715780631e9a69501461028657806323b872dd1461029957806326bbe60a146102ac57610211565b806306fdde0314610216578063095ea7b314610234578063138885651461025457806318160ddd14610269575b600080fd5b61021e61048b565b60405161022b91906156c5565b60405180910390f35b610247610242366004614227565b610522565b60405161022b919061560c565b61025c610540565b60405161022b91906156a9565b61025c610546565b61028461027f3660046146a0565b61054c565b005b61025c610294366004614227565b610618565b6102476102a7366004614179565b610677565b6102846102ba366004614103565b610705565b6102c76107d8565b60405161022b929190615986565b6102dd6108eb565b60405161022b9190615994565b6102846102f83660046146a0565b6108f4565b61024761030b366004614227565b610983565b61025c61031e366004614227565b6109d7565b61025c610331366004614257565b610a1b565b61025c610a7b565b61025c610a81565b610284610a87565b61025c610ad4565b61025c6103643660046141c6565b610ada565b61025c610377366004614103565b611039565b61038f61038a366004614179565b611058565b60405161022b9392919061561a565b6102846103ac3660046146a0565b6113ae565b6102c761143d565b61025c6103c736600461429a565b6115ab565b61021e61166e565b6103dc6116cf565b60405161022b91906156b7565b6102476103f7366004614227565b6116de565b61024761040a366004614227565b61174c565b61025c61041d36600461429a565b611760565b6102846104303660046146dc565b611805565b6103dc61185c565b61028461044b366004614559565b61186b565b61025c61045e36600461413f565b6119d6565b61046b611a01565b60405161022b919061539f565b61025c610486366004614257565b611a10565b60368054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156105175780601f106104ec57610100808354040283529160200191610517565b820191906000526020600020905b8154815290600101906020018083116104fa57829003601f168201915b505050505090505b90565b600061053661052f611a54565b8484611a58565b5060015b92915050565b60485481565b60355490565b610554611b0c565b6001600160a01b0316336001600160a01b0316148061058b5750610576611b8e565b6001600160a01b0316336001600160a01b0316145b6105b05760405162461bcd60e51b81526004016105a7906156f6565b60405180910390fd5b6702c68af0bb1400008111156105d85760405162461bcd60e51b81526004016105a7906157d6565b60478190556040517f2f5a6b1defeafd30e7568ea5c176aa0702b0af5b00ba41fa20e58b2c72e8afe79061060d9083906156a9565b60405180910390a150565b604154600090600160a01b900460ff166106445760405162461bcd60e51b81526004016105a7906158a6565b6041805460ff60a01b1916905561065c838333611bd9565b90506041805460ff60a01b1916600160a01b17905592915050565b6000610684848484611c7f565b6106fa84610690611a54565b6106f585604051806060016040528060288152602001615b37602891396001600160a01b038a166000908152603460205260408120906106ce611a54565b6001600160a01b03168152602081019190915260400160002054919063ffffffff611d9516565b611a58565b5060015b9392505050565b61070d611b0c565b6001600160a01b0316336001600160a01b03161461073d5760405162461bcd60e51b81526004016105a790615786565b604254600160a01b900460ff16156107675760405162461bcd60e51b81526004016105a7906157f6565b6001600160a01b03811661078d5760405162461bcd60e51b81526004016105a7906157a6565b604280546001600160a01b0319166001600160a01b0383161790556040517f2e137a82d7f7fe8a4c453313f3d08557c162ad9d78219a2e937e318b41e12f7a9061060d90839061539f565b600080336107e4611dc1565b6001600160a01b03161461080a5760405162461bcd60e51b81526004016105a790615756565b604154600160a01b900460ff166108335760405162461bcd60e51b81526004016105a7906158a6565b6041805460ff60a01b19169055604854600090600110156108c65760485461086290600163ffffffff611df416565b600160485590506108733382611e36565b604080516000808252602082019081528183019283905230927f7d3ff197e9071095bd36b627028ef523ecf46fcbf17cbde745a4b65aec88b6bc926108bd92859287929190615505565b60405180910390a25b806108cf610546565b92509250506041805460ff60a01b1916600160a01b1790559091565b60385460ff1690565b6108fc611b0c565b6001600160a01b0316336001600160a01b03161461092c5760405162461bcd60e51b81526004016105a790615786565b60455481111561094e5760405162461bcd60e51b81526004016105a790615826565b60448190556040517f9cabc14d438714dbcd9292df9b3f89c42f98acd93a675ad72cd6033777e9b8e79061060d9083906156a9565b6000610536610990611a54565b846106f585603460006109a1611a54565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff611ef616565b604154600090600160a01b900460ff16610a035760405162461bcd60e51b81526004016105a7906158a6565b6041805460ff60a01b1916905561065c838333611f1b565b604154600090600160a01b900460ff16610a475760405162461bcd60e51b81526004016105a7906158a6565b6041805460ff60a01b19169055610a5f848484611f1b565b90506041805460ff60a01b1916600160a01b1790559392505050565b60465481565b60445481565b610a8f611b0c565b6001600160a01b0316336001600160a01b031614610abf5760405162461bcd60e51b81526004016105a790615786565b6042805460ff60a01b1916600160a01b179055565b60475481565b604154600090600160a01b900460ff16610b065760405162461bcd60e51b81526004016105a7906158a6565b6041805460ff60a01b19169055610b1b6139a1565b50604080516060810182526001600160a01b038088168083528782166020840152908516928201929092529015801590610b61575060208101516001600160a01b031615155b610b7d5760405162461bcd60e51b81526004016105a790615806565b80602001516001600160a01b031681600001516001600160a01b03161415610bb75760405162461bcd60e51b81526004016105a790615776565b60408101516001600160a01b0316610be15760405162461bcd60e51b81526004016105a790615726565b60008411610c015760405162461bcd60e51b81526004016105a790615796565b60208101516001600160a01b0316301415610c3157610c298160000151858360400151611f1b565b91505061101e565b60006060610c3d6139c1565b610c456139c1565b60435485516020870151604051632bf596cf60e01b81526001600160a01b0390931692632bf596cf92610c7f9290916000906004016153ad565b60006040518083038186803b158015610c9757600080fd5b505afa158015610cab573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cd3919081019061444e565b9350935093509350838390610cfb5760405162461bcd60e51b81526004016105a791906156c5565b50610d046139e8565b610d0c6121cf565b90506000610d3a876000015185600001516060015186602001518760000151604001518e876020015161222b565b506043546040808701516020880151915163371a1b2360e21b81529394506001600160a01b039092169263dc686c8c92610d7a92909186906004016159a2565b600060405180830381600087803b158015610d9457600080fd5b505af1158015610da8573d6000803e3d6000fd5b5050604254845187518751604051638da25c0960e01b81526000965060609550869485946001600160a01b0390911693638da25c0993610dec938b90600401615926565b60006040518083038186803b158015610e0457600080fd5b505afa158015610e18573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e4091908101906144bc565b9350935093509350838390610e685760405162461bcd60e51b81526004016105a791906156c5565b5060008211610e895760405162461bcd60e51b81526004016105a7906158b6565b60408b0151610e966139e8565b610f2e6040518061012001604052808681526020018f602001516001600160a01b031681526020018b602001516001600160a01b0316815260200185610edd576000610ee1565b6044545b81526020018b600001516040015115158152602001846001600160a01b031681526020018b600001516060015181526020018a6020015181526020018b6000015160a001518152506123ee565b6043546040808c01516020808e0151908501519251632e8b67a160e11b81529495506001600160a01b0390931693635d16cf4293610f709390916004016159a2565b600060405180830381600087803b158015610f8a57600080fd5b505af1158015610f9e573d6000803e3d6000fd5b50505050610fbd81604001518960400151611ef690919063ffffffff16565b6048558c516020808f01519083015160405133937f202522f7dbbb826f03c2adf78dedea2ede1e5cf8a67a041843a7b43e529011d49361100393919290919088906153fd565b60405180910390a2602001519c505050505050505050505050505b6041805460ff60a01b1916600160a01b179055949350505050565b6001600160a01b0381166000908152603360205260409020545b919050565b60006060816001600160a01b0386161580159061107d57506001600160a01b03851615155b6110995760405162461bcd60e51b81526004016105a790615806565b846001600160a01b0316866001600160a01b031614156110cb5760405162461bcd60e51b81526004016105a790615776565b6001600160a01b038516301484600060606110e46139c1565b6110ec6139c1565b604354604051632bf596cf60e01b81526001600160a01b0390911690632bf596cf90611120908f908f908b906004016153ad565b60006040518083038186803b15801561113857600080fd5b505afa15801561114c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611174919081019061444e565b9350935093509350836111965750600097509095508694506113a59350505050565b61119e6139e8565b6111a66121cf565b90508615611293576042548151845160405163df95633560e01b81526001600160a01b039093169263df956335926111e49290918b9060040161595d565b60006040518083038186803b1580156111fc57600080fd5b505afa158015611210573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611238919081019061433c565b9095509350846112585750600098509196508795506113a5945050505050565b82516060015161126f90879063ffffffff6126a616565b60408051602081019091526000815260019b50995097506113a59650505050505050565b60006060600080604260009054906101000a90046001600160a01b03166001600160a01b0316638da25c098660000151896000015189600001518e6040518563ffffffff1660e01b81526004016112ed9493929190615926565b60006040518083038186803b15801561130557600080fd5b505afa158015611319573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261134191908101906144bc565b935093509350935083611368575060009c50909a508b99506113a598505050505050505050565b801561137e5761137a826044546126b7565b9250505b5060408051602081019091526000815260019d509b5099506113a598505050505050505050565b93509350939050565b6113b6611b0c565b6001600160a01b0316336001600160a01b0316146113e65760405162461bcd60e51b81526004016105a790615786565b6045548111156114085760405162461bcd60e51b81526004016105a790615826565b60468190556040517f4dbf9634a3aaf3bc15ab627faeaac7c6b0a4754ead77206f1c11277356f2878f9061060d9083906156a9565b60008033611449611dc1565b6001600160a01b03161461146f5760405162461bcd60e51b81526004016105a790615756565b604154600160a01b900460ff166114985760405162461bcd60e51b81526004016105a7906158a6565b6041805460ff60a01b1916905560435460408051631517d59160e11b815290516000926060926001600160a01b0390911691632a2fab2291600480820192879290919082900301818387803b1580156114f057600080fd5b505af1158015611504573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261152c91908101906146fb565b9150915061153a3383611e36565b6040805160008152602081019182905230917f7d3ff197e9071095bd36b627028ef523ecf46fcbf17cbde745a4b65aec88b6bc9161157d91849187918790615546565b60405180910390a28161158e610546565b9350935050506041805460ff60a01b1916600160a01b1790559091565b604154600090600160a01b900460ff166115d75760405162461bcd60e51b81526004016105a7906158a6565b6041805460ff60a01b1916905560408051602080880282810182019093528782526116509289918991829185019084908082843760009201919091525050604080516020808a028281018201909352898252909350899250889182918501908490808284376000920191909152508792506126e5915050565b90506041805460ff60a01b1916600160a01b17905595945050505050565b60378054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156105175780601f106104ec57610100808354040283529160200191610517565b6041546001600160a01b031681565b60006105366116eb611a54565b846106f585604051806060016040528060258152602001615b5f6025913960346000611715611a54565b6001600160a01b03908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff611d9516565b6000610536611759611a54565b8484611c7f565b604154600090600160a01b900460ff1661178c5760405162461bcd60e51b81526004016105a7906158a6565b6041805460ff60a01b1916905560408051602080880282810182019093528782526116509289918991829185019084908082843760009201919091525050604080516020808a02828101820190935289825290935089925088918291850190849080828437600092019190915250879250612a8f915050565b604154600160a01b900460ff1661182e5760405162461bcd60e51b81526004016105a7906158a6565b6041805460ff60a01b191690556118458282612dcb565b50506041805460ff60a01b1916600160a01b179055565b6042546001600160a01b031681565b600054610100900460ff16806118845750611884613032565b80611892575060005460ff16155b6118ae5760405162461bcd60e51b81526004016105a790615836565b600054610100900460ff161580156118d9576000805460ff1961ff0019909116610100171660011790555b61194c88888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a915089908190840183828082843760009201919091525061303892505050565b61195584613048565b61195d613094565b604280546001600160a01b038086166001600160a01b031992831617909255604380549285169290911691909117905566470de4df820000604555660221b262dd8000604455660110d9316ec00060465567016345785d8a000060475580156119cc576000805461ff00191690555b5050505050505050565b6001600160a01b03918216600090815260346020908152604080832093909416825291909152205490565b6043546001600160a01b031690565b604154600090600160a01b900460ff16611a3c5760405162461bcd60e51b81526004016105a7906158a6565b6041805460ff60a01b19169055610a5f848484611bd9565b3390565b6001600160a01b038316611a7e5760405162461bcd60e51b81526004016105a790615866565b6001600160a01b038216611aa45760405162461bcd60e51b81526004016105a790615706565b6001600160a01b0380841660008181526034602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590611aff9085906156a9565b60405180910390a3505050565b6041546040805163030d028960e21b815290516000926001600160a01b031691630c340a24916004808301926020929190829003018186803b158015611b5157600080fd5b505afa158015611b65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611b899190810190614121565b905090565b6041546039546040516385acd64160e01b81526000926001600160a01b0316916385acd64191611bc191906004016156a9565b60206040518083038186803b158015611b5157600080fd5b604080516001808252818301909252600091606091906020808301908038833950506040805160018082528183019092529293506060929150602080830190803883390190505090508582600081518110611c3057fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508481600081518110611c5e57fe5b602002602001018181525050611c75828286612a8f565b9695505050505050565b6001600160a01b038316611ca55760405162461bcd60e51b81526004016105a790615856565b6001600160a01b038216611ccb5760405162461bcd60e51b81526004016105a7906156d6565b611d0e81604051806060016040528060268152602001615b11602691396001600160a01b038616600090815260336020526040902054919063ffffffff611d9516565b6001600160a01b038085166000908152603360205260408082209390935590841681522054611d43908263ffffffff611ef616565b6001600160a01b0380841660008181526033602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611aff9085906156a9565b60008184841115611db95760405162461bcd60e51b81526004016105a791906156c5565b505050900390565b6041546040805490516385acd64160e01b81526000926001600160a01b0316916385acd64191611bc191906004016156a9565b60006106fe83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611d95565b6001600160a01b038216611e5c5760405162461bcd60e51b81526004016105a7906158d6565b603554611e6f908263ffffffff611ef616565b6035556001600160a01b038216600090815260336020526040902054611e9b908263ffffffff611ef616565b6001600160a01b0383166000818152603360205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611eea9085906156a9565b60405180910390a35050565b6000828201838110156106fe5760405162461bcd60e51b81526004016105a790615716565b60006001600160a01b038216611f435760405162461bcd60e51b81526004016105a790615896565b60008311611f635760405162461bcd60e51b81526004016105a7906157e6565b6000611f6d6139c1565b60435460405163bf9ca02d60e01b81526001600160a01b039091169063bf9ca02d90611fa29089908990600190600401615573565b61012060405180830381600087803b158015611fbd57600080fd5b505af1158015611fd1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611ff59190810190614528565b9150915081612009576000925050506106fe565b6120116139e8565b6120196121cf565b90506000826020015190506000806120498a866000015160600151858860000151604001518d896020015161222b565b6042548651885160405163df95633560e01b81529496509294506000936060936001600160a01b039093169263df9563359261208c92909190899060040161595d565b60006040518083038186803b1580156120a457600080fd5b505afa1580156120b8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526120e0919081019061433c565b915091508181906121045760405162461bcd60e51b81526004016105a791906156c5565b50604354604080890151905163371a1b2360e21b81526001600160a01b039092169163dc686c8c9161213c91899089906004016159a2565b600060405180830381600087803b15801561215657600080fd5b505af115801561216a573d6000803e3d6000fd5b505050506121788a84611e36565b336001600160a01b03167f30873c596f54a2e2e09894670d7e1a48b2433c00204f81fbedf557353c36e7c78b858f886040516121b7949392919061548f565b60405180910390a250909a9950505050505050505050565b6121d76139e8565b60485460006121f4826121e8610546565b9063ffffffff611ef616565b9050604051806060016040528082815260200161221c604754846130a990919063ffffffff16565b81526020019290925250905090565b60008060008061223d33898c896130be565b9150915086156122e1576040516307dba22560e31b81526000906001600160a01b038a1690633edd11289061227b908e908790600190600401615573565b602060405180830381600087803b15801561229557600080fd5b505af11580156122a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506122cd91908101906146be565b90506122d981886131fa565b9450506123cf565b8582146123005760405162461bcd60e51b81526004016105a7906157c6565b90925082906000612317868b63ffffffff61320916565b9050808211156123cd57600061234461233783600263ffffffff61323a16565b849063ffffffff611df416565b6040516307dba22560e31b81529091506001600160a01b038b1690633edd112890612378908f908590600090600401615573565b602060405180830381600087803b15801561239257600080fd5b505af11580156123a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506123ca91908101906146be565b50505b505b6123df848a63ffffffff6126a616565b92505050965096945050505050565b6123f66139e8565b815115611053576124198260200151836000015184606001518560c0015161327c565b90508160800151156124a35760408083015160a084015160208086015190850151935163c89fc72f60e01b81526001600160a01b039093169363c89fc72f9361246c939291908190600190600401615432565b600060405180830381600087803b15801561248657600080fd5b505af115801561249a573d6000803e3d6000fd5b50505050611053565b600082602001516001600160a01b03166370a0823184604001516040518263ffffffff1660e01b81526004016124d9919061539f565b60206040518083038186803b1580156124f157600080fd5b505afa158015612505573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061252991908101906146be565b9050816020015181106125ad5782604001516001600160a01b031663a4e285958460a00151856020015185602001516040518463ffffffff1660e01b8152600401612576939291906153d5565b600060405180830381600087803b15801561259057600080fd5b505af11580156125a4573d6000803e3d6000fd5b505050506126a0565b60006125db60026125cf8660c001518760e0015161320990919063ffffffff16565b9063ffffffff61323a16565b90506000612624612609846125fd876020015186611ef690919063ffffffff16565b9063ffffffff611df416565b61010087015161261f908663ffffffff611df416565b6131fa565b905084604001516001600160a01b031663c89fc72f8660a00151876020015187602001518560006040518663ffffffff1660e01b815260040161266b959493929190615432565b600060405180830381600087803b15801561268557600080fd5b505af1158015612699573d6000803e3d6000fd5b5050505050505b50919050565b60006106fe83836305f5e100613334565b6000806126ca848463ffffffff6130a916565b91506126dc848363ffffffff611df416565b90509250929050565b60006001600160a01b03821661270d5760405162461bcd60e51b81526004016105a790615896565b8251801580159061271e5750845181145b61273a5760405162461bcd60e51b81526004016105a790615736565b612742613a09565b604354604051639d01cd3560e01b81526001600160a01b0390911690639d01cd3590612777908990899060019060040161559f565b600060405180830381600087803b15801561279157600080fd5b505af11580156127a5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526127cd9190810190614604565b80519091506127e1576000925050506106fe565b6127e96139e8565b6127f16121cf565b90506000809050606084604051908082528060200260200182016040528015612824578160200160208202803883390190505b50905060005b858110156128e857600089828151811061284057fe5b6020026020010151905060008111156128df5761285b613a33565b8660200151838151811061286b57fe5b602002602001015190506000806128ad836000015184606001518b60400151888151811061289557fe5b60200260200101518660400151888d6020015161222b565b91509150818686815181106128be57fe5b60209081029190910101526128d9878263ffffffff611ef616565b96505050505b5060010161282a565b50600082116129095760405162461bcd60e51b81526004016105a790615766565b6043546060850151604080870151905163d5e1d27960e01b81526001600160a01b039093169263d5e1d2799261294592909186906004016155d3565b600060405180830381600087803b15801561295f57600080fd5b505af1158015612973573d6000803e3d6000fd5b505060425485516020880151604051634566eb0960e01b815260009550606094506001600160a01b0390931692634566eb09926129b69290918890600401615906565b60006040518083038186803b1580156129ce57600080fd5b505afa1580156129e2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612a0a919081019061433c565b91509150818190612a2e5760405162461bcd60e51b81526004016105a791906156c5565b50612a398985611e36565b336001600160a01b03167f7d3ff197e9071095bd36b627028ef523ecf46fcbf17cbde745a4b65aec88b6bc8a868e8e604051612a7894939291906154c4565b60405180910390a250919998505050505050505050565b60006001600160a01b038216612ab75760405162461bcd60e51b81526004016105a790615896565b82518015801590612ac85750845181145b612ae45760405162461bcd60e51b81526004016105a790615736565b612aec613a6c565b60435460405163c0e46a2f60e01b81526001600160a01b039091169063c0e46a2f90612b1c90899060040161558e565b60006040518083038186803b158015612b3457600080fd5b505afa158015612b48573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612b70919081019061466c565b8051909150612b84576000925050506106fe565b612b8c6139e8565b612b946121cf565b9050600060606000604260009054906101000a90046001600160a01b03166001600160a01b0316638fb1860b60008660000151886020015189608001518e6040518663ffffffff1660e01b8152600401612bf2959493929190615649565b60006040518083038186803b158015612c0a57600080fd5b505afa158015612c1e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612c4691908101906143f4565b925092509250828290612c6c5760405162461bcd60e51b81526004016105a791906156c5565b506000805b87811015612ce95760008b8281518110612c8757fe5b602002602001015190506000811115612ce0576000612cca89604001518481518110612caf57fe5b6020026020010151606001518361336290919063ffffffff16565b9050612cdc848263ffffffff611ef616565b9350505b50600101612c71565b5060008111612d0a5760405162461bcd60e51b81526004016105a7906157b6565b600082612d18576000612d1c565b6044545b9050612d756040518061010001604052808c6001600160a01b031681526020018481526020018d8152602001896080015181526020018960600151815260200183815260200189604001518152602001888152506133b4565b336001600160a01b03167f93fc955b3f6c5e7b37fbb64f39e6f4d9050f82ed17cec724743f95a50da7df1c8b848f8f604051612db494939291906154c4565b60405180910390a2509a9950505050505050505050565b6001600160a01b038116612df15760405162461bcd60e51b81526004016105a790615896565b60008211612e115760405162461bcd60e51b81526004016105a790615886565b612e19613a9d565b604360009054906101000a90046001600160a01b03166001600160a01b03166343ae78be6040518163ffffffff1660e01b815260040160006040518083038186803b158015612e6757600080fd5b505afa158015612e7b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612ea39190810190614638565b90506000612eb7826000015161261f6135e0565b90506000612ecb858363ffffffff6130a916565b604254602085015160405162201e2d60e41b815292935060009260609283926001600160a01b0390911691630201e2d091612f0b918891906004016158e6565b60006040518083038186803b158015612f2357600080fd5b505afa158015612f37573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612f5f9190810190614383565b925092509250828290612f855760405162461bcd60e51b81526004016105a791906156c5565b50612fe5604051806101000160405280896001600160a01b031681526020018a81526020018381526020018860600151815260200188604001518152602001604654815260200188602001518152602001612fde6121cf565b90526133b4565b336001600160a01b03167f6e8e3f900293b89801cb29bf5dc5c402c685e66d588bed50a3d83ffbf0bb9034888a604051613020929190615474565b60405180910390a25050505050505050565b303b1590565b613044828260126135ec565b5050565b6001600160a01b03811661306e5760405162461bcd60e51b81526004016105a7906156e6565b604180546001600160a01b0319166001600160a01b03831617905561309161362c565b50565b6041805460ff60a01b1916600160a01b179055565b60006106fe8383670de0b6b3a7640000613334565b6000806000846001600160a01b03166370a08231876040518263ffffffff1660e01b81526004016130ef919061539f565b60206040518083038186803b15801561310757600080fd5b505afa15801561311b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061313f91908101906146be565b905061315c6001600160a01b03861688888763ffffffff6136db16565b6040516370a0823160e01b81526001600160a01b038616906370a082319061318890899060040161539f565b60206040518083038186803b1580156131a057600080fd5b505afa1580156131b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506131d891908101906146be565b91506131ee8461261f848463ffffffff611df416565b92505094509492505050565b60008183116126a057826106fe565b600080613220846305f5e10063ffffffff61373c16565b9050613232818463ffffffff61323a16565b949350505050565b60006106fe83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613776565b6132846139e8565b82156133115760008061329786866126b7565b91509150336001600160a01b03167f02f19ecb5bbcd7b0f0cb034005563f7ad115132d0beb073b5d32697ca94bbaa188846040516132d6929190615474565b60405180910390a26040805160608101825287815260208101839052908101613305848763ffffffff6126a616565b81525092505050613232565b505060408051606081018252838152602081019390935260009083015250919050565b600080613347858563ffffffff61373c16565b9050613359818463ffffffff61323a16565b95945050505050565b600080613375848463ffffffff61373c16565b9050600061339e6133916305f5e100600163ffffffff611df416565b839063ffffffff611ef616565b9050613359816305f5e10063ffffffff61323a16565b6133c23382602001516137ad565b60c0810151516040805182815260208084028201019091526060908280156133f4578160200160208202803883390190505b5090506000805b838110156135595761340b6139e8565b61351a6040518061012001604052808860400151858151811061342a57fe5b602002602001015181526020018860c00151858151811061344757fe5b6020026020010151600001516001600160a01b031681526020018860800151858151811061347157fe5b60200260200101516001600160a01b031681526020018860a0015181526020018860c0015185815181106134a157fe5b6020026020010151604001511515815260200188600001516001600160a01b031681526020018860c0015185815181106134d757fe5b60200260200101516060015181526020018860e001516020015181526020018860c00151858151811061350657fe5b602002602001015160a001518152506123ee565b9050806020015184838151811061352d57fe5b6020908102919091010152604081015161354e90849063ffffffff611ef616565b9250506001016133fb565b5060e084015160400151613573908263ffffffff611ef616565b604855604354606085015160808601516040516388a90f5160e01b81526001600160a01b03909316926388a90f51926135b292909187906004016155d3565b600060405180830381600087803b1580156135cc57600080fd5b505af11580156119cc573d6000803e3d6000fd5b670de0b6b3a764000090565b82516135ff906036906020860190613ac5565b508151613613906037906020850190613ac5565b506038805460ff191660ff929092169190911790555050565b6040516136389061537e565b60405190819003812060395561364d90615352565b604051908190038120603a5561366290615389565b604051908190038120603b5561367790615373565b604051908190038120603c5561368c90615368565b604051908190038120603d556136a19061535d565b604051908190038120603e556136b690615394565b604051908190038120603f556136cb90615347565b6040518091039020604081905550565b6040516137369085906323b872dd60e01b906136ff908790879087906024016153d5565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613883565b50505050565b60008261374b5750600061053a565b8282028284828161375857fe5b04146106fe5760405162461bcd60e51b81526004016105a790615816565b600081836137975760405162461bcd60e51b81526004016105a791906156c5565b5060008385816137a357fe5b0495945050505050565b6001600160a01b0382166137d35760405162461bcd60e51b81526004016105a790615846565b61381681604051806060016040528060228152602001615aef602291396001600160a01b038516600090815260336020526040902054919063ffffffff611d9516565b6001600160a01b038316600090815260336020526040902055603554613842908263ffffffff611df416565b6035556040516000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611eea9085906156a9565b613895826001600160a01b0316613968565b6138b15760405162461bcd60e51b81526004016105a7906158c6565b60006060836001600160a01b0316836040516138cd919061533b565b6000604051808303816000865af19150503d806000811461390a576040519150601f19603f3d011682016040523d82523d6000602084013e61390f565b606091505b5091509150816139315760405162461bcd60e51b81526004016105a790615746565b805115613736578080602001905161394c919081019061431e565b6137365760405162461bcd60e51b81526004016105a790615876565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590613232575050151592915050565b604080516060810182526000808252602082018190529181019190915290565b60405180606001604052806139d4613a33565b815260006020820181905260409091015290565b60405180606001604052806000815260200160008152602001600081525090565b60405180608001604052806000151581526020016060815260200160608152602001606081525090565b6040805160c081019091526000808252602082019081526020016000151581526020016000815260200160008152602001600081525090565b6040518060a00160405280600015158152602001606081526020016060815260200160608152602001606081525090565b6040518060800160405280600081526020016060815260200160608152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613b0657805160ff1916838001178555613b33565b82800160010185558215613b33579182015b82811115613b33578251825591602001919060010190613b18565b50613b3f929150613b43565b5090565b61051f91905b80821115613b3f5760008155600101613b49565b803561053a81615ab2565b805161053a81615ab2565b60008083601f840112613b8557600080fd5b5081356001600160401b03811115613b9c57600080fd5b602083019150836020820283011115613bb457600080fd5b9250929050565b600082601f830112613bcc57600080fd5b8151613bdf613bda826159d6565b6159b0565b91508181835260208401935060208101905083856020840282011115613c0457600080fd5b60005b83811015613c305781613c1a8882613b68565b8452506020928301929190910190600101613c07565b5050505092915050565b600082601f830112613c4b57600080fd5b8151613c59613bda826159d6565b915081818352602084019350602081019050838560c0840282011115613c7e57600080fd5b60005b83811015613c305781613c948882613e8e565b84525060209092019160c09190910190600101613c81565b600082601f830112613cbd57600080fd5b8151613ccb613bda826159d6565b91508181835260208401935060208101905083856020840282011115613cf057600080fd5b60005b83811015613c305781613d0688826140ed565b8452506020928301929190910190600101613cf3565b600082601f830112613d2d57600080fd5b8151613d3b613bda826159d6565b91508181835260208401935060208101905083856020840282011115613d6057600080fd5b60005b83811015613c305781613d7688826140f8565b8452506020928301929190910190600101613d63565b805161053a81615ac6565b805161053a81615acf565b60008083601f840112613db457600080fd5b5081356001600160401b03811115613dcb57600080fd5b602083019150836001820283011115613bb457600080fd5b600082601f830112613df457600080fd5b8151613e02613bda826159f6565b91508082526020830160208301858383011115613e1e57600080fd5b613e29838284615a72565b50505092915050565b60006101008284031215613e4557600080fd5b613e4f60606159b0565b90506000613e5d8484613e8e565b82525060c0613e6e84848301613b68565b60208301525060e0613e82848285016140f8565b60408301525092915050565b600060c08284031215613ea057600080fd5b613eaa60c06159b0565b90506000613eb88484613b68565b8252506020613ec984848301613d97565b6020830152506040613edd84828501613d8c565b6040830152506060613ef1848285016140ed565b6060830152506080613f05848285016140ed565b60808301525060a0613f19848285016140ed565b60a08301525092915050565b600060808284031215613f3757600080fd5b613f4160806159b0565b90506000613f4f8484613d8c565b82525060208201516001600160401b03811115613f6b57600080fd5b613f7784828501613c3a565b60208301525060408201516001600160401b03811115613f9657600080fd5b613fa284828501613bbb565b60408301525060608201516001600160401b03811115613fc157600080fd5b613fcd84828501613d1c565b60608301525092915050565b600060808284031215613feb57600080fd5b613ff560806159b0565b90506000613f4f84846140ed565b600060a0828403121561401557600080fd5b61401f60a06159b0565b9050600061402d8484613d8c565b82525060208201516001600160401b0381111561404957600080fd5b61405584828501613c3a565b60208301525060408201516001600160401b0381111561407457600080fd5b61408084828501613c3a565b60408301525060608201516001600160401b0381111561409f57600080fd5b6140ab84828501613bbb565b60608301525060808201516001600160401b038111156140ca57600080fd5b6140d684828501613d1c565b60808301525092915050565b803561053a81615adc565b805161053a81615adc565b805161053a81615ae5565b60006020828403121561411557600080fd5b60006132328484613b5d565b60006020828403121561413357600080fd5b60006132328484613b68565b6000806040838503121561415257600080fd5b600061415e8585613b5d565b925050602061416f85828601613b5d565b9150509250929050565b60008060006060848603121561418e57600080fd5b600061419a8686613b5d565b93505060206141ab86828701613b5d565b92505060406141bc868287016140e2565b9150509250925092565b600080600080608085870312156141dc57600080fd5b60006141e88787613b5d565b94505060206141f987828801613b5d565b935050604061420a878288016140e2565b925050606061421b87828801613b5d565b91505092959194509250565b6000806040838503121561423a57600080fd5b60006142468585613b5d565b925050602061416f858286016140e2565b60008060006060848603121561426c57600080fd5b60006142788686613b5d565b9350506020614289868287016140e2565b92505060406141bc86828701613b5d565b6000806000806000606086880312156142b257600080fd5b85356001600160401b038111156142c857600080fd5b6142d488828901613b73565b955095505060208601356001600160401b038111156142f257600080fd5b6142fe88828901613b73565b9350935050604061431188828901613b5d565b9150509295509295909350565b60006020828403121561433057600080fd5b60006132328484613d8c565b6000806040838503121561434f57600080fd5b600061435b8585613d8c565b92505060208301516001600160401b0381111561437757600080fd5b61416f85828601613de3565b60008060006060848603121561439857600080fd5b60006143a48686613d8c565b93505060208401516001600160401b038111156143c057600080fd5b6143cc86828701613de3565b92505060408401516001600160401b038111156143e857600080fd5b6141bc86828701613cac565b60008060006060848603121561440957600080fd5b60006144158686613d8c565b93505060208401516001600160401b0381111561443157600080fd5b61443d86828701613de3565b92505060406141bc86828701613d8c565b600080600080610240858703121561446557600080fd5b60006144718787613d8c565b94505060208501516001600160401b0381111561448d57600080fd5b61449987828801613de3565b93505060406144aa87828801613e32565b92505061014061421b87828801613e32565b600080600080608085870312156144d257600080fd5b60006144de8787613d8c565b94505060208501516001600160401b038111156144fa57600080fd5b61450687828801613de3565b9350506040614517878288016140ed565b925050606061421b87828801613d8c565b600080610120838503121561453c57600080fd5b60006145488585613d8c565b925050602061416f85828601613e32565b600080600080600080600060a0888a03121561457457600080fd5b87356001600160401b0381111561458a57600080fd5b6145968a828b01613da2565b975097505060208801356001600160401b038111156145b457600080fd5b6145c08a828b01613da2565b955095505060406145d38a828b01613b5d565b93505060606145e48a828b01613b5d565b92505060806145f58a828b01613b5d565b91505092959891949750929550565b60006020828403121561461657600080fd5b81516001600160401b0381111561462c57600080fd5b61323284828501613f25565b60006020828403121561464a57600080fd5b81516001600160401b0381111561466057600080fd5b61323284828501613fd9565b60006020828403121561467e57600080fd5b81516001600160401b0381111561469457600080fd5b61323284828501614003565b6000602082840312156146b257600080fd5b600061323284846140e2565b6000602082840312156146d057600080fd5b600061323284846140ed565b600080604083850312156146ef57600080fd5b600061415e85856140e2565b6000806040838503121561470e57600080fd5b600061471a85856140ed565b92505060208301516001600160401b0381111561473657600080fd5b61416f85828601613cac565b600061474e8383614782565b505060200190565b600061476283836152c2565b505060c00190565b600061474e8383614979565b600061474e8383615332565b61478b81615a30565b82525050565b600061479c82615a23565b6147a68185615a27565b93506147b183615a1d565b8060005b838110156147df5781516147c98882614742565b97506147d483615a1d565b9250506001016147b5565b509495945050505050565b60006147f582615a23565b6147ff8185615a27565b935061480a83615a1d565b8060005b838110156147df5781516148228882614742565b975061482d83615a1d565b92505060010161480e565b600061484382615a23565b61484d8185615a27565b935061485883615a1d565b8060005b838110156147df5781516148708882614756565b975061487b83615a1d565b92505060010161485c565b600061489182615a23565b61489b8185615a27565b93506148a683615a1d565b8060005b838110156147df5781516148be888261476a565b97506148c983615a1d565b9250506001016148aa565b60006148df82615a23565b6148e98185615a27565b93506148f483615a1d565b8060005b838110156147df57815161490c888261476a565b975061491783615a1d565b9250506001016148f8565b600061492d82615a23565b6149378185615a27565b935061494283615a1d565b8060005b838110156147df57815161495a8882614776565b975061496583615a1d565b925050600101614946565b61478b81615a3b565b61478b8161051f565b600061498d82615a23565b6149978185611053565b93506149a7818560208601615a72565b9290920192915050565b61478b81615a5c565b61478b81615a67565b60006149ce82615a23565b6149d88185615a27565b93506149e8818560208601615a72565b6149f181615a9e565b9093019392505050565b6000614a08602383615a27565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647281526265737360e81b602082015260400192915050565b6000614a4d601583615a27565b744e657875732061646472657373206973207a65726f60581b815260200192915050565b6000614a7e600e83611053565b6d29b0bb34b733b9a6b0b730b3b2b960911b8152600e0192915050565b6000614aa8601b83615a27565b7f4f6e6c7920676f7665726e616e63652063616e20657865637574650000000000815260200192915050565b6000614ae1600783611053565b665374616b696e6760c81b815260070192915050565b6000614b04602283615a27565b7f45524332303a20617070726f766520746f20746865207a65726f206164647265815261737360f01b602082015260400192915050565b6000614b48601b83615a27565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000614b81601083611053565b6f2932b1b7b63630ba32b930b634b9b2b960811b815260100192915050565b6000614bad601983615a27565b7f4d697373696e6720726563697069656e74206164647265737300000000000000815260200192915050565b6000614be6601483615a27565b73092dce0eae840c2e4e4c2f240dad2e6dac2e8c6d60631b815260200192915050565b6000614c16602083615a27565b7f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815260200192915050565b6000614c4f601783615a27565b7f4d75737420626520736176696e6773206d616e61676572000000000000000000815260200192915050565b6000614c88601a83615a27565b7f4e6f206d6173736574207175616e7469747920746f206d696e74000000000000815260200192915050565b6000614cc1601a83615a27565b7f43616e6e6f742073776170207468652073616d65206173736574000000000000815260200192915050565b6000614cfa601983615a27565b7f4f6e6c7920676f7665726e6f722063616e206578656375746500000000000000815260200192915050565b6000614d33600783611053565b6626b0b730b3b2b960c91b815260070192915050565b6000614d56601083615a27565b6f496e76616c6964207175616e7469747960801b815260200192915050565b6000614d82601883615a27565b7f4d757374206265206e6f6e206e756c6c20616464726573730000000000000000815260200192915050565b6000614dbb601883615a27565b7f4d7573742072656465656d20736f6d6520624173736574730000000000000000815260200192915050565b6000614df4601b83615a27565b7f4173736574206e6f742066756c6c79207472616e736665727265640000000000815260200192915050565b6000614e2d600e83615a27565b6d4d757374206265203c3d2032302560901b815260200192915050565b6000614e57601683615a27565b7505175616e74697479206d757374206e6f7420626520360541b815260200192915050565b6000614e89601a83615a27565b7f4d75737420626520616c6c6f77656420746f2075706772616465000000000000815260200192915050565b6000614ec2600983611053565b6827b930b1b632a43ab160b91b815260090192915050565b6000614ee7601c83615a27565b7f496e76616c696420737761702061737365742061646472657373657300000000815260200192915050565b6000614f20602183615a27565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000614f63600a83611053565b69476f7665726e616e636560b01b8152600a0192915050565b6000614f89600a83611053565b69283937bc3ca0b236b4b760b11b8152600a0192915050565b6000614faf601a83615a27565b7f52617465206d7573742062652077697468696e20626f756e6473000000000000815260200192915050565b6000614fe8602e83615a27565b7f436f6e747261637420696e7374616e63652068617320616c726561647920626581526d195b881a5b9a5d1a585b1a5e995960921b602082015260400192915050565b6000615038602183615a27565b7f45524332303a206275726e2066726f6d20746865207a65726f206164647265738152607360f81b602082015260400192915050565b600061507b602583615a27565b7f45524332303a207472616e736665722066726f6d20746865207a65726f206164815264647265737360d81b602082015260400192915050565b60006150c2602483615a27565b7f45524332303a20617070726f76652066726f6d20746865207a65726f206164648152637265737360e01b602082015260400192915050565b6000615108602a83615a27565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e8152691bdd081cdd58d8d9595960b21b602082015260400192915050565b6000615154601b83615a27565b7f496e76616c696420726564656d7074696f6e207175616e746974790000000000815260200192915050565b600061518d601983615a27565b7f4d75737420626520612076616c696420726563697069656e7400000000000000815260200192915050565b60006151c6600983611053565b6826b2ba30aa37b5b2b760b91b815260090192915050565b60006151eb601f83615a27565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00815260200192915050565b6000615224601783615a27565b7f4d75737420776974686472617720736f6d657468696e67000000000000000000815260200192915050565b600061525d601f83615a27565b7f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400815260200192915050565b6000615296601f83615a27565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300815260200192915050565b805160c08301906152d38482614782565b5060208201516152e660208501826149ba565b5060408201516152f96040850182614970565b50606082015161530c6060850182614979565b50608082015161531f6080850182614979565b5060a082015161373660a0850182614979565b61478b81615a56565b60006106fe8284614982565b600061053a82614a71565b600061053a82614ad4565b600061053a82614b74565b600061053a82614d26565b600061053a82614eb5565b600061053a82614f56565b600061053a82614f7c565b600061053a826151b9565b6020810161053a8284614782565b606081016153bb8286614782565b6153c86020830185614782565b6132326040830184614970565b606081016153e38286614782565b6153f06020830185614782565b6132326040830184614979565b6080810161540b8287614782565b6154186020830186614782565b6154256040830185614979565b6133596060830184614782565b60a081016154408288614782565b61544d6020830187614782565b61545a6040830186614979565b6154676060830185614979565b611c756080830184614970565b604081016154828285614782565b6106fe6020830184614979565b6080810161549d8287614782565b6154aa6020830186614979565b6154b76040830185614782565b6133596060830184614979565b608081016154d28287614782565b6154df6020830186614979565b81810360408301526154f18185614791565b90508181036060830152611c758184614886565b608081016155138287614782565b6155206020830186614979565b818103604083015261553281856147ea565b90508181036060830152611c7581846148d4565b608081016155548287614782565b6155616020830186614979565b81810360408301526154f181856147ea565b606081016155818286614782565b6153c86020830185614979565b602080825281016106fe8184614791565b606080825281016155b08186614791565b905081810360208301526155c48185614886565b90506132326040830184614970565b606080825281016155e48186614922565b905081810360208301526155f881856147ea565b905081810360408301526133598184614886565b6020810161053a8284614970565b606081016156288286614970565b818103602083015261563a81856149c3565b90506132326040830184614979565b60a081016156578288614970565b6156646020830187614979565b81810360408301526156768186614838565b9050818103606083015261568a8185614922565b9050818103608083015261569e8184614886565b979650505050505050565b6020810161053a8284614979565b6020810161053a82846149b1565b602080825281016106fe81846149c3565b6020808252810161053a816149fb565b6020808252810161053a81614a40565b6020808252810161053a81614a9b565b6020808252810161053a81614af7565b6020808252810161053a81614b3b565b6020808252810161053a81614ba0565b6020808252810161053a81614bd9565b6020808252810161053a81614c09565b6020808252810161053a81614c42565b6020808252810161053a81614c7b565b6020808252810161053a81614cb4565b6020808252810161053a81614ced565b6020808252810161053a81614d49565b6020808252810161053a81614d75565b6020808252810161053a81614dae565b6020808252810161053a81614de7565b6020808252810161053a81614e20565b6020808252810161053a81614e4a565b6020808252810161053a81614e7c565b6020808252810161053a81614eda565b6020808252810161053a81614f13565b6020808252810161053a81614fa2565b6020808252810161053a81614fdb565b6020808252810161053a8161502b565b6020808252810161053a8161506e565b6020808252810161053a816150b5565b6020808252810161053a816150fb565b6020808252810161053a81615147565b6020808252810161053a81615180565b6020808252810161053a816151de565b6020808252810161053a81615217565b6020808252810161053a81615250565b6020808252810161053a81615289565b604081016158f48285614979565b81810360208301526132328184614838565b606081016159148286614979565b81810360208301526155f88185614838565b6101c081016159358287614979565b61594260208301866152c2565b61594f60e08301856152c2565b6133596101a0830184614979565b610100810161596c8286614979565b61597960208301856152c2565b61323260e0830184614979565b604081016154828285614979565b6020810161053a8284615332565b606081016153e38286615332565b6040518181016001600160401b03811182821017156159ce57600080fd5b604052919050565b60006001600160401b038211156159ec57600080fd5b5060209081020190565b60006001600160401b03821115615a0c57600080fd5b506020601f91909101601f19160190565b60200190565b5190565b90815260200190565b600061053a82615a4a565b151590565b8061105381615aa8565b6001600160a01b031690565b60ff1690565b600061053a82615a30565b600061053a82615a40565b60005b83811015615a8d578181015183820152602001615a75565b838111156137365750506000910152565b601f01601f191690565b6008811061309157fe5b615abb81615a30565b811461309157600080fd5b615abb81615a3b565b6008811061309157600080fd5b615abb8161051f565b615abb81615a5656fe45524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa365627a7a72315820f5ed41c5aeed2ab4675d2568bba346b7c92a0e8ad5807d86520159ec0cc290a76c6578706572696d656e74616cf564736f6c63430005100040
Deployed Bytecode Sourcemap
52402:36471:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52402:36471:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28564:83;;;:::i;:::-;;;;;;;;;;;;;;;;22144:152;;;;;;;;;:::i;:::-;;;;;;;;53898:22;;;:::i;:::-;;;;;;;;21165:91;;;:::i;84734:234::-;;;;;;;;;:::i;:::-;;69904:243;;;;;;;;;:::i;22768:304::-;;;;;;;;;:::i;85203:383::-;;;;;;;;;:::i;87258:756::-;;;:::i;:::-;;;;;;;;;29416:83;;;:::i;:::-;;;;;;;;85958:231;;;;;;;;;:::i;23481:210::-;;;;;;;;;:::i;55396:237::-;;;;;;;;;:::i;56050:268::-;;;;;;;;;:::i;53805:28::-;;;:::i;53719:22::-;;;:::i;85693:121::-;;;:::i;53867:24::-;;;:::i;63804:2950::-;;;;;;;;;:::i;21319:110::-;;;;;;;;;:::i;67347:1970::-;;;;;;;;;:::i;:::-;;;;;;;;;;86339:273;;;;;;;;;:::i;88323:547::-;;;:::i;56862:294::-;;;;;;;;;:::i;28766:87::-;;;:::i;31916:19::-;;;:::i;:::-;;;;;;;;24194:261;;;;;;;;;:::i;21642:158::-;;;;;;;;;:::i;71484:305::-;;;;;;;;;:::i;72130:198::-;;;;;;;;;:::i;53549:37::-;;;:::i;54053:640::-;;;;;;;;;:::i;21863:134::-;;;;;;;;;:::i;86746:140::-;;;:::i;:::-;;;;;;;;70670:274;;;;;;;;;:::i;28564:83::-;28634:5;28627:12;;;;;;;;-1:-1:-1;;28627:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28601:13;;28627:12;;28634:5;;28627:12;;28634:5;28627:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28564:83;;:::o;22144:152::-;22210:4;22227:39;22236:12;:10;:12::i;:::-;22250:7;22259:6;22227:8;:39::i;:::-;-1:-1:-1;22284:4:0;22144:152;;;;;:::o;53898:22::-;;;;:::o;21165:91::-;21236:12;;21165:91;:::o;84734:234::-;32395:11;:9;:11::i;:::-;-1:-1:-1;;;;;32381:25:0;:10;-1:-1:-1;;;;;32381:25:0;;:56;;;;32424:13;:11;:13::i;:::-;-1:-1:-1;;;;;32410:27:0;:10;-1:-1:-1;;;;;32410:27:0;;32381:56;32359:133;;;;-1:-1:-1;;;32359:133:0;;;;;;;;;;;;;;;;;84856:4;84842:10;:18;;84834:45;;;;-1:-1:-1;;;84834:45:0;;;;;;;;;84892:9;:22;;;84932:28;;;;;;84904:10;;84932:28;;;;;;;;;;84734:234;:::o;69904:243::-;36671:11;;70045:22;;-1:-1:-1;;;36671:11:0;;;;36663:55;;;;-1:-1:-1;;;36663:55:0;;;;;;;;;36796:11;:19;;-1:-1:-1;;;;36796:19:0;;;70092:47;70102:7;70111:15;70128:10;70092:9;:47::i;:::-;70085:54;;36976:11;:18;;-1:-1:-1;;;;36976:18:0;-1:-1:-1;;;36976:18:0;;;69904:243;;-1:-1:-1;;69904:243:0:o;22768:304::-;22857:4;22874:36;22884:6;22892:9;22903:6;22874:9;:36::i;:::-;22921:121;22930:6;22938:12;:10;:12::i;:::-;22952:89;22990:6;22952:89;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;22952:19:0;;;;;;:11;:19;;;;;;22972:12;:10;:12::i;:::-;-1:-1:-1;;;;;22952:33:0;;;;;;;;;;;;-1:-1:-1;22952:33:0;;;:89;;:37;:89;:::i;:::-;22921:8;:121::i;:::-;-1:-1:-1;23060:4:0;22768:304;;;;;;:::o;85203:383::-;32089:11;:9;:11::i;:::-;-1:-1:-1;;;;;32075:25:0;:10;-1:-1:-1;;;;;32075:25:0;;32067:63;;;;-1:-1:-1;;;32067:63:0;;;;;;;;;85327:20;;-1:-1:-1;;;85327:20:0;;;;85326:21;85318:60;;;;-1:-1:-1;;;85318:60:0;;;;;;;;;-1:-1:-1;;;;;85397:32:0;;85389:69;;;;-1:-1:-1;;;85389:69:0;;;;;;;;;85469:14;:52;;-1:-1:-1;;;;;;85469:52:0;-1:-1:-1;;;;;85469:52:0;;;;;85537:41;;;;;;85469:52;;85537:41;;87258:756;87371:22;;54861:10;54840:17;:15;:17::i;:::-;-1:-1:-1;;;;;54840:31:0;;54832:67;;;;-1:-1:-1;;;54832:67:0;;;;;;;;;36671:11;;-1:-1:-1;;;36671:11:0;;;;36663:55;;;;-1:-1:-1;;;36663:55:0;;;;;;;;;36796:11;:19;;-1:-1:-1;;;;36796:19:0;;;87678:7;;36810:5;;36796:19;-1:-1:-1;87675:289:0;;;87714:7;;:14;;87726:1;87714:14;:11;:14;:::i;:::-;87753:1;87743:7;:11;87705:23;-1:-1:-1;87822:25:0;87828:10;87705:23;87822:5;:25::i;:::-;87917:16;;;87931:1;87917:16;;;;;;87935;;;;;;;;;;87887:4;;87867:85;;;;87887:4;;87909:6;;87917:16;;87867:85;;;;;;;;;;87675:289;87984:6;87992:13;:11;:13::i;:::-;87976:30;;;;;36976:11;:18;;-1:-1:-1;;;;36976:18:0;-1:-1:-1;;;36976:18:0;;;87258:756;;:::o;29416:83::-;29482:9;;;;29416:83;:::o;85958:231::-;32089:11;:9;:11::i;:::-;-1:-1:-1;;;;;32075:25:0;:10;-1:-1:-1;;;;;32075:25:0;;32067:63;;;;-1:-1:-1;;;32067:63:0;;;;;;;;;86072:7;;86060:8;:19;;86052:58;;;;-1:-1:-1;;;86052:58:0;;;;;;;;;86121:7;:18;;;86157:24;;;;;;86131:8;;86157:24;;23481:210;23561:4;23578:83;23587:12;:10;:12::i;:::-;23601:7;23610:50;23649:10;23610:11;:25;23622:12;:10;:12::i;:::-;-1:-1:-1;;;;;23610:25:0;;;;;;;;;;;;;;;;;-1:-1:-1;23610:25:0;;;:34;;;;;;;;;;;:50;:38;:50;:::i;55396:237::-;36671:11;;55535:20;;-1:-1:-1;;;36671:11:0;;;;36663:55;;;;-1:-1:-1;;;36663:55:0;;;;;;;;;36796:11;:19;;-1:-1:-1;;;;36796:19:0;;;55580:45;55588:7;55597:15;55614:10;55580:7;:45::i;56050:268::-;36671:11;;56220:20;;-1:-1:-1;;;36671:11:0;;;;36663:55;;;;-1:-1:-1;;;36663:55:0;;;;;;;;;36796:11;:19;;-1:-1:-1;;;;36796:19:0;;;56265:45;56273:7;56282:15;56299:10;56265:7;:45::i;:::-;56258:52;;36976:11;:18;;-1:-1:-1;;;;36976:18:0;-1:-1:-1;;;36976:18:0;;;56050:268;;-1:-1:-1;;;56050:268:0:o;53805:28::-;;;;:::o;53719:22::-;;;;:::o;85693:121::-;32089:11;:9;:11::i;:::-;-1:-1:-1;;;;;32075:25:0;:10;-1:-1:-1;;;;;32075:25:0;;32067:63;;;;-1:-1:-1;;;32067:63:0;;;;;;;;;85779:20;:27;;-1:-1:-1;;;;85779:27:0;-1:-1:-1;;;85779:27:0;;;85693:121::o;53867:24::-;;;;:::o;63804:2950::-;36671:11;;63991:14;;-1:-1:-1;;;36671:11:0;;;;36663:55;;;;-1:-1:-1;;;36663:55:0;;;;;;;;;36796:11;:19;;-1:-1:-1;;;;36796:19:0;;;64107:20;;:::i;:::-;-1:-1:-1;64130:37:0;;;;;;;;-1:-1:-1;;;;;64130:37:0;;;;;;;;;;;;;;;;;;;;;;;;64186:24;;;;:53;;-1:-1:-1;64214:11:0;;;;-1:-1:-1;;;;;64214:25:0;;;64186:53;64178:94;;;;-1:-1:-1;;;64178:94:0;;;;;;;;;64305:4;:11;;;-1:-1:-1;;;;;64291:25:0;:4;:10;;;-1:-1:-1;;;;;64291:25:0;;;64283:64;;;;-1:-1:-1;;;64283:64:0;;;;;;;;;64366:14;;;;-1:-1:-1;;;;;64366:28:0;64358:66;;;;-1:-1:-1;;;64358:66:0;;;;;;;;;64455:1;64443:9;:13;64435:42;;;;-1:-1:-1;;;64435:42:0;;;;;;;;;64548:11;;;;-1:-1:-1;;;;;64548:28:0;64571:4;64548:28;64545:112;;;64599:46;64607:4;:10;;;64619:9;64630:4;:14;;;64599:7;:46::i;:::-;64592:53;;;;;64545:112;64725:12;64739:20;64761:33;;:::i;:::-;64796:34;;:::i;:::-;64847:13;;64880:10;;64892:11;;;;64847:64;;-1:-1:-1;;;64847:64:0;;-1:-1:-1;;;;;64847:13:0;;;;:32;;:64;;64880:10;;64847:13;;:64;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64847:64:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64847:64:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;64847:64:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;64847:64:0;;;;;;;;;64724:187;;;;;;;;64930:7;64939:6;64922:24;;;;;-1:-1:-1;;;64922:24:0;;;;;;;;;;;64959:18;;:::i;:::-;64980;:16;:18::i;:::-;64959:39;;65052:17;65088:147;65103:4;:10;;;65115:12;:19;;;:25;;;65142:12;:23;;;65167:12;:19;;;:40;;;65209:9;65220:5;:14;;;65088;:147::i;:::-;-1:-1:-1;65288:13:0;;65323:18;;;;;65343:23;;;;65288:90;;-1:-1:-1;;;65288:90:0;;65051:184;;-1:-1:-1;;;;;;65288:13:0;;;;:34;;:90;;65323:18;;65051:184;;65288:90;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;65288:90:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;65529:14:0;;65557:21;;65580:19;;65601:20;;65529:104;;-1:-1:-1;;;65529:104:0;;65425:14;;-1:-1:-1;65441:32:0;;-1:-1:-1;65425:14:0;;;;-1:-1:-1;;;;;65529:14:0;;;;:27;;:104;;65623:9;;65529:104;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;65529:104:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65529:104:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;65529:104:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;65529:104:0;;;;;;;;;65424:209;;;;;;;;65652:9;65663:18;65644:38;;;;;-1:-1:-1;;;65644:38:0;;;;;;;;;;;65714:1;65701:10;:14;65693:50;;;;-1:-1:-1;;;65693:50:0;;;;;;;;;65871:14;;;;65933:17;;:::i;:::-;65953:526;65983:485;;;;;;;;66025:10;65983:485;;;;66062:4;:11;;;-1:-1:-1;;;;;65983:485:0;;;;;66104:13;:24;;;-1:-1:-1;;;;;65983:485:0;;;;;66156:12;:26;;66181:1;66156:26;;;66171:7;;66156:26;65983:485;;;;66211:13;:20;;;:41;;;65983:485;;;;;;66282:9;-1:-1:-1;;;;;65983:485:0;;;;;66317:13;:20;;;:26;;;65983:485;;;;66372:5;:14;;;65983:485;;;;66419:13;:20;;;:33;;;65983:485;;;65953:15;:526::i;:::-;66492:13;;66527:19;;;;;66548:24;;;;;66574:7;;;;66492:90;;-1:-1:-1;;;66492:90:0;;65933:546;;-1:-1:-1;;;;;;66492:13:0;;;;:34;;:90;;66548:24;;66492:90;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;66492:90:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;66492:90:0;;;;66605:32;66623:3;:13;;;66605:5;:13;;;:17;;:32;;;;:::i;:::-;66595:7;:42;66675:10;;66687:11;;;;;66700:7;;;;66655:64;;66663:10;;66655:64;;;;66675:10;;66687:11;;66700:7;66709:9;;66655:64;;;;;;;;;;66739:7;;;;-1:-1:-1;;;;;;;;;;;;;36828:1:0;36976:11;:18;;-1:-1:-1;;;;36976:18:0;-1:-1:-1;;;36976:18:0;;;63804:2950;;-1:-1:-1;;;;63804:2950:0:o;21319:110::-;-1:-1:-1;;;;;21403:18:0;;21376:7;21403:18;;;:9;:18;;;;;;21319:110;;;;:::o;67347:1970::-;67506:4;67512:13;67506:4;-1:-1:-1;;;;;67567:20:0;;;;;;:45;;-1:-1:-1;;;;;;67591:21:0;;;;67567:45;67559:86;;;;-1:-1:-1;;;67559:86:0;;;;;;;;;67674:7;-1:-1:-1;;;;;67664:17:0;:6;-1:-1:-1;;;;;67664:17:0;;;67656:56;;;;-1:-1:-1;;;67656:56:0;;;;;;;;;-1:-1:-1;;;;;67739:24:0;;67758:4;67739:24;67793:9;67725:11;67869:20;67891:33;;:::i;:::-;67926:34;;:::i;:::-;67977:13;;:57;;-1:-1:-1;;;67977:57:0;;-1:-1:-1;;;;;67977:13:0;;;;:32;;:57;;68010:6;;68018:7;;68027:6;;67977:57;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67977:57:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;67977:57:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;67977:57:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;67977:57:0;;;;;;;;;67854:180;;;;;;;;68049:7;68045:64;;-1:-1:-1;68080:5:0;;-1:-1:-1;68087:6:0;;-1:-1:-1;68080:5:0;;-1:-1:-1;68072:25:0;;-1:-1:-1;;;;68072:25:0;68045:64;68121:18;;:::i;:::-;68142;:16;:18::i;:::-;68121:39;;68288:6;68285:1025;;;68360:14;;68388:21;;68411:19;;68360:81;;-1:-1:-1;;;68360:81:0;;-1:-1:-1;;;;;68360:14:0;;;;:27;;:81;;68388:21;;68432:8;;68360:81;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68360:81:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;68360:81:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;68360:81:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;68360:81:0;;;;;;;;;68340:101;;-1:-1:-1;68340:101:0;-1:-1:-1;68340:101:0;68456:38;;-1:-1:-1;68477:5:0;;-1:-1:-1;68484:6:0;;-1:-1:-1;68477:5:0;;-1:-1:-1;68469:25:0;;-1:-1:-1;;;;;68469:25:0;68456:38;68595:19;;:25;;;68569:52;;:8;;:52;:25;:52;:::i;:::-;68636:24;;;;;;;;;-1:-1:-1;68636:24:0;;68643:4;;-1:-1:-1;68636:24:0;-1:-1:-1;68560:61:0;-1:-1:-1;68636:24:0;;-1:-1:-1;;;;;;;68636:24:0;68285:1025;68777:14;68793:32;68827:18;68847:17;68885:14;;;;;;;;;-1:-1:-1;;;;;68885:14:0;-1:-1:-1;;;;;68885:27:0;;68913:5;:21;;;68936:12;:19;;;68957:13;:20;;;68979:8;68885:103;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68885:103:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;68885:103:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;68885:103:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;68885:103:0;;;;;;;;;68776:212;;;;;;;;69007:9;69003:86;;-1:-1:-1;69044:5:0;;-1:-1:-1;69051:18:0;;-1:-1:-1;69044:5:0;;-1:-1:-1;69036:37:0;;-1:-1:-1;;;;;;;;;69036:37:0;69003:86;69157:12;69154:101;;;69206:33;69219:10;69231:7;;69206:12;:33::i;:::-;69189:50;-1:-1:-1;;69154:101:0;-1:-1:-1;69269:29:0;;;;;;;;;-1:-1:-1;69269:29:0;;69277:4;;-1:-1:-1;69269:29:0;-1:-1:-1;69287:10:0;-1:-1:-1;69269:29:0;;-1:-1:-1;;;;;;;;;69269:29:0;67347:1970;;;;;;;;:::o;86339:273::-;32089:11;:9;:11::i;:::-;-1:-1:-1;;;;;32075:25:0;:10;-1:-1:-1;;;;;32075:25:0;;32067:63;;;;-1:-1:-1;;;32067:63:0;;;;;;;;;86471:7;;86453:14;:25;;86445:64;;;;-1:-1:-1;;;86445:64:0;;;;;;;;;86520:13;:30;;;86568:36;;;;;;86536:14;;86568:36;;88323:547;88444:22;;54861:10;54840:17;:15;:17::i;:::-;-1:-1:-1;;;;;54840:31:0;;54832:67;;;;-1:-1:-1;;;54832:67:0;;;;;;;;;36671:11;;-1:-1:-1;;;36671:11:0;;;;36663:55;;;;-1:-1:-1;;;36663:55:0;;;;;;;;;36796:11;:19;;-1:-1:-1;;;;36796:19:0;;;88601:13;;:31;;;-1:-1:-1;;;88601:31:0;;;;36810:5;;88575:22;;-1:-1:-1;;;;;88601:13:0;;;;:29;;:31;;;;;36810:5;;88601:31;;;;;;;;36810:5;88601:13;:31;;;5:2:-1;;;;30:1;27;20:12;5:2;88601:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;88601:31:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;88601:31:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;88601:31:0;;;;;;;;;88547:85;;;;88671:36;88677:10;88689:17;88671:5;:36::i;:::-;88784:16;;;88798:1;88784:16;;;;;;;;;88743:4;;88723:85;;;;88743:4;;88765:17;;88802:5;;88723:85;;;;;;;;;;88829:17;88848:13;:11;:13::i;:::-;88821:41;;;;;;36976:11;:18;;-1:-1:-1;;;;36976:18:0;-1:-1:-1;;;36976:18:0;;;88323:547;;:::o;56862:294::-;36671:11;;57057:20;;-1:-1:-1;;;36671:11:0;;;;36663:55;;;;-1:-1:-1;;;36663:55:0;;;;;;;;;36796:11;:19;;-1:-1:-1;;;;36796:19:0;;;57102:46;;;;;;;;;;;;;;;;;;;;57110:8;;;;;;57102:46;;;57110:8;;57102:46;57110:8;57102:46;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;;57102:46:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57120:15:0;;-1:-1:-1;57120:15:0;;;;57102:46;;;57120:15;;57102:46;57120:15;57102:46;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;57137:10:0;;-1:-1:-1;57102:7:0;;-1:-1:-1;;57102:46:0:i;:::-;57095:53;;36976:11;:18;;-1:-1:-1;;;;36976:18:0;-1:-1:-1;;;36976:18:0;;;56862:294;;-1:-1:-1;;;;;56862:294:0:o;28766:87::-;28838:7;28831:14;;;;;;;;-1:-1:-1;;28831:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28805:13;;28831:14;;28838:7;;28831:14;;28838:7;28831:14;;;;;;;;;;;;;;;;;;;;;;;;31916:19;;;-1:-1:-1;;;;;31916:19:0;;:::o;24194:261::-;24279:4;24296:129;24305:12;:10;:12::i;:::-;24319:7;24328:96;24367:15;24328:96;;;;;;;;;;;;;;;;;:11;:25;24340:12;:10;:12::i;:::-;-1:-1:-1;;;;;24328:25:0;;;;;;;;;;;;;;;;;-1:-1:-1;24328:25:0;;;:34;;;;;;;;;;;:96;;:38;:96;:::i;21642:158::-;21711:4;21728:42;21738:12;:10;:12::i;:::-;21752:9;21763:6;21728:9;:42::i;71484:305::-;36671:11;;71684:22;;-1:-1:-1;;;36671:11:0;;;;36663:55;;;;-1:-1:-1;;;36663:55:0;;;;;;;;;36796:11;:19;;-1:-1:-1;;;;36796:19:0;;;71731:50;;;;;;;;;;;;;;;;;;;;71741:8;;;;;;71731:50;;;71741:8;;71731:50;71741:8;71731:50;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;;71731:50:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;71751:17:0;;-1:-1:-1;71751:17:0;;;;71731:50;;;71751:17;;71731:50;71751:17;71731:50;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;71770:10:0;;-1:-1:-1;71731:9:0;;-1:-1:-1;;71731:50:0:i;72130:198::-;36671:11;;-1:-1:-1;;;36671:11:0;;;;36663:55;;;;-1:-1:-1;;;36663:55:0;;;;;;;;;36796:11;:19;;-1:-1:-1;;;;36796:19:0;;;72278:42;72292:15;72309:10;72278:13;:42::i;:::-;-1:-1:-1;;36976:11:0;:18;;-1:-1:-1;;;;36976:18:0;-1:-1:-1;;;36976:18:0;;;72130:198::o;53549:37::-;;;-1:-1:-1;;;;;53549:37:0;;:::o;54053:640::-;10498:12;;;;;;;;:31;;;10514:15;:13;:15::i;:::-;10498:47;;;-1:-1:-1;10534:11:0;;;;10533:12;10498:47;10490:106;;;;-1:-1:-1;;;10490:106:0;;;;;;;;;10605:19;10628:12;;;;;;10627:13;10647:83;;;;10676:12;:19;;-1:-1:-1;;;;10676:19:0;;;;;10704:18;10691:4;10704:18;;;10647:83;54299:52;54330:8;;54299:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;;54299:52:0;;;;137:4:-1;54299:52:0;;;;;;;;;;;;;;;;;;-1:-1:-1;54340:10:0;;-1:-1:-1;54340:10:0;;;;54299:52;;54340:10;;;;54299:52;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;54299:30:0;;-1:-1:-1;;;54299:52:0:i;:::-;54362:39;54394:6;54362:31;:39::i;:::-;54412:42;:40;:42::i;:::-;54467:14;:49;;-1:-1:-1;;;;;54467:49:0;;;-1:-1:-1;;;;;;54467:49:0;;;;;;;54529:13;:46;;;;;;;;;;;;;;;54598:4;54588:7;:14;54623:4;54613:7;:14;54654:4;54638:13;:20;54681:4;54669:9;:16;10748:57;;;;10792:5;10777:20;;-1:-1:-1;;10777:20:0;;;10748:57;54053:640;;;;;;;;:::o;21863:134::-;-1:-1:-1;;;;;21962:18:0;;;21935:7;21962:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;21863:134::o;86746:140::-;86864:13;;-1:-1:-1;;;;;86864:13:0;86746:140;:::o;70670:274::-;36671:11;;70842:22;;-1:-1:-1;;;36671:11:0;;;;36663:55;;;;-1:-1:-1;;;36663:55:0;;;;;;;;;36796:11;:19;;-1:-1:-1;;;;36796:19:0;;;70889:47;70899:7;70908:15;70925:10;70889:9;:47::i;12301:98::-;12381:10;12301:98;:::o;27125:338::-;-1:-1:-1;;;;;27219:19:0;;27211:68;;;;-1:-1:-1;;;27211:68:0;;;;;;;;;-1:-1:-1;;;;;27298:21:0;;27290:68;;;;-1:-1:-1;;;27290:68:0;;;;;;;;;-1:-1:-1;;;;;27371:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;;:36;;;27423:32;;;;;27401:6;;27423:32;;;;;;;;;;27125:338;;;:::o;33431:95::-;33502:5;;:16;;;-1:-1:-1;;;33502:16:0;;;;33475:7;;-1:-1:-1;;;;;33502:5:0;;:14;;:16;;;;;;;;;;;;;;:5;:16;;;5:2:-1;;;;30:1;27;20:12;5:2;33502:16:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;33502:16:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;33502:16:0;;;;;;;;;33495:23;;33431:95;:::o;33666:112::-;33739:5;;33755:14;;33739:31;;-1:-1:-1;;;33739:31:0;;33712:7;;-1:-1:-1;;;;;33739:5:0;;:15;;:31;;33755:14;33739:31;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;72531:432:0;72749:16;;;72763:1;72749:16;;;;;;;;;72682:22;;72722:24;;72749:16;;;;;;;105:10:-1;72749:16:0;88:34:-1;-1:-1;;72806:16:0;;;72820:1;72806:16;;;;;;;;;72722:43;;-1:-1:-1;72776:27:0;;72806:16;-1:-1:-1;72806:16:0;;;;;;105:10:-1;72806:16:0;88:34:-1;136:17;;-1:-1;72806:16:0;72776:46;;72846:7;72833;72841:1;72833:10;;;;;;;;;;;;;:20;-1:-1:-1;;;;;72833:20:0;;;-1:-1:-1;;;;;72833:20:0;;;;;72880:15;72864:10;72875:1;72864:13;;;;;;;;;;;;;:31;;;;;72913:42;72923:7;72932:10;72944;72913:9;:42::i;:::-;72906:49;72531:432;-1:-1:-1;;;;;;72531:432:0:o;24945:471::-;-1:-1:-1;;;;;25043:20:0;;25035:70;;;;-1:-1:-1;;;25035:70:0;;;;;;;;;-1:-1:-1;;;;;25124:23:0;;25116:71;;;;-1:-1:-1;;;25116:71:0;;;;;;;;;25220;25242:6;25220:71;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;25220:17:0;;;;;;:9;:17;;;;;;;:71;;:21;:71;:::i;:::-;-1:-1:-1;;;;;25200:17:0;;;;;;;:9;:17;;;;;;:91;;;;25325:20;;;;;;;:32;;25350:6;25325:32;:24;:32;:::i;:::-;-1:-1:-1;;;;;25302:20:0;;;;;;;:9;:20;;;;;;;:55;;;;25373:35;;;;;;;;;;25401:6;;25373:35;;17194:192;17280:7;17316:12;17308:6;;;;17300:29;;;;-1:-1:-1;;;17300:29:0;;;;;;;;;;-1:-1:-1;;;17352:5:0;;;17194:192::o;35187:121::-;35264:5;;35280:19;;;35264:36;;-1:-1:-1;;;35264:36:0;;35237:7;;-1:-1:-1;;;;;35264:5:0;;:15;;:36;;35280:19;35264:36;;;;16721:136;16779:7;16806:43;16810:1;16813;16806:43;;;;;;;;;;;;;;;;;:3;:43::i;25697:308::-;-1:-1:-1;;;;;25773:21:0;;25765:65;;;;-1:-1:-1;;;25765:65:0;;;;;;;;;25858:12;;:24;;25875:6;25858:24;:16;:24;:::i;:::-;25843:12;:39;-1:-1:-1;;;;;25914:18:0;;;;;;:9;:18;;;;;;:30;;25937:6;25914:30;:22;:30;:::i;:::-;-1:-1:-1;;;;;25893:18:0;;;;;;:9;:18;;;;;;:51;;;;25960:37;;25893:18;;;25960:37;;;;25990:6;;25960:37;;;;;;;;;;25697:308;;:::o;16265:181::-;16323:7;16355:5;;;16379:6;;;;16371:46;;;;-1:-1:-1;;;16371:46:0;;;;;;;;57322:1490;57471:20;-1:-1:-1;;;;;57517:24:0;;57509:62;;;;-1:-1:-1;;;57509:62:0;;;;;;;;;57608:1;57590:15;:19;57582:54;;;;-1:-1:-1;;;57582:54:0;;;;;;;;;57650:12;57664:26;;:::i;:::-;57694:13;;:64;;-1:-1:-1;;;57694:64:0;;-1:-1:-1;;;;;57694:13:0;;;;:32;;:64;;57727:7;;57736:15;;57694:13;;:64;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57694:64:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;57694:64:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;57694:64:0;;;;;;;;;57649:109;;;;57773:7;57769:21;;57789:1;57782:8;;;;;;57769:21;57803:18;;:::i;:::-;57824;:16;:18::i;:::-;57803:39;;57940:18;57961:5;:16;;;57940:37;;57989:25;58016:22;58055:123;58070:7;58079:5;:12;;;:18;;;58099:10;58111:5;:12;;;:33;;;58146:15;58163:5;:14;;;58055;:123::i;:::-;58318:14;;58346:21;;58369:12;;58318:83;;-1:-1:-1;;;58318:83:0;;57988:190;;-1:-1:-1;57988:190:0;;-1:-1:-1;58278:14:0;;58294:20;;-1:-1:-1;;;;;58318:14:0;;;;:27;;:83;;58346:21;;58369:12;57988:190;;58318:83;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58318:83:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58318:83:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;58318:83:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;58318:83:0;;;;;;;;;58277:124;;;;58420:9;58431:6;58412:26;;;;;-1:-1:-1;;;58412:26:0;;;;;;;;;;-1:-1:-1;58528:13:0;;58563:11;;;;;58528:78;;-1:-1:-1;;;58528:78:0;;-1:-1:-1;;;;;58528:13:0;;;;:34;;:78;;58576:10;;58588:17;;58528:78;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58528:78:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58528:78:0;;;;58647:33;58653:10;58665:14;58647:5;:33::i;:::-;58703:10;-1:-1:-1;;;;;58696:74:0;;58715:10;58727:14;58743:7;58752:17;58696:74;;;;;;;;;;;;;;;;;;-1:-1:-1;58790:14:0;;57322:1490;-1:-1:-1;;;;;;;;;;57322:1490:0:o;84102:228::-;84153:12;;:::i;:::-;84197:7;;84178:16;84229:27;84197:7;84229:13;:11;:13::i;:::-;:17;:27;:17;:27;:::i;:::-;84215:41;;84274:48;;;;;;;;84280:3;84274:48;;;;84285:26;84301:9;;84285:3;:15;;:26;;;;:::i;:::-;84274:48;;;;;;;;-1:-1:-1;84267:55:0;-1:-1:-1;84102:228:0;:::o;61200:1790::-;61435:25;61462:22;61609:19;61630:16;61650:80;61686:10;61698:11;61711:7;61720:9;61650:35;:80::i;:::-;61608:122;;;;62015:9;62012:893;;;62060:69;;-1:-1:-1;;;62060:69:0;;62040:17;;-1:-1:-1;;;;;62060:41:0;;;;;:69;;62102:7;;62111:11;;62124:4;;62060:69;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62060:69:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62060:69:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;62060:69:0;;;;;;;;;62040:89;;62164:36;62179:9;62190;62164:14;:36::i;:::-;62144:56;;62012:893;;;;62501:9;62486:11;:24;62478:64;;;;-1:-1:-1;;;62478:64:0;;;;;;;;;62579:11;;-1:-1:-1;62579:11:0;;62607:24;62634:41;:9;62662:12;62634:41;:27;:41;:::i;:::-;62607:68;;62706:16;62695:8;:27;62692:202;;;62742:13;62758:37;62771:23;:16;62792:1;62771:23;:20;:23;:::i;:::-;62758:8;;:37;:12;:37;:::i;:::-;62814:64;;-1:-1:-1;;;62814:64:0;;62742:53;;-1:-1:-1;;;;;;62814:41:0;;;;;:64;;62856:7;;62742:53;;62872:5;;62814:64;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62814:64:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62814:64:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;62814:64:0;;;;;;;;;;62692:202;;62012:893;;62934:48;:17;62969:12;62934:48;:34;:48;:::i;:::-;62917:65;;61200:1790;;;;;;;;;;;:::o;79926:1721::-;79995:20;;:::i;:::-;80031:13;;:17;80028:1612;;80148:68;80163:4;:11;;;80176:4;:13;;;80191:4;:12;;;80205:4;:10;;;80148:14;:68::i;:::-;80139:77;;80303:4;:13;;;80300:1329;;;80357:15;;;;;80383:14;;;;80399:11;;;;;80412:10;;;;80336:105;;-1:-1:-1;;;80336:105:0;;-1:-1:-1;;;;;80336:46:0;;;;;;:105;;80383:14;80399:11;80412:10;;;80436:4;;80336:105;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;80336:105:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;80336:105:0;;;;80300:1329;;;80561:16;80587:4;:11;;;-1:-1:-1;;;;;80580:29:0;;80610:4;:15;;;80580:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;80580:46:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;80580:46:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;80580:46:0;;;;;;;;;80561:65;;80725:6;:10;;;80713:8;:22;80710:904;;80781:4;:15;;;-1:-1:-1;;;;;80760:49:0;;80810:4;:14;;;80826:4;:11;;;80839:6;:10;;;80760:90;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;80760:90:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;80760:90:0;;;;80710:904;;;81089:24;81116:50;81164:1;81116:43;81148:4;:10;;;81116:4;:13;;;:31;;:43;;;;:::i;:::-;:47;:50;:47;:50;:::i;:::-;81089:77;;81189:23;81215:95;81230:46;81267:8;81230:32;81251:6;:10;;;81230:16;:20;;:32;;;;:::i;:::-;:36;:46;:36;:46;:::i;:::-;81278:17;;;;:31;;81300:8;81278:31;:21;:31;:::i;:::-;81215:14;:95::i;:::-;81189:121;;81356:4;:15;;;-1:-1:-1;;;;;81335:46:0;;81408:4;:14;;;81449:4;:11;;;81487:6;:10;;;81524:15;81566:5;81335:259;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;81335:259:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;81335:259:0;;;;80710:904;;;80300:1329;79926:1721;;;:::o;41905:183::-;42007:9;42041:39;42058:1;42061:5;37660:3;42041:16;:39::i;83178:416::-;83292:17;;83491:37;:15;83519:8;83491:37;:27;:37;:::i;:::-;83479:49;-1:-1:-1;83556:30:0;:15;83479:49;83556:30;:19;:30;:::i;:::-;83539:47;;83178:416;;;;;:::o;58848:2092::-;59018:20;-1:-1:-1;;;;;59064:24:0;;59056:62;;;;-1:-1:-1;;;59056:62:0;;;;;;;;;59143:24;;59186:7;;;;;:33;;;59204:8;:15;59197:3;:22;59186:33;59178:66;;;;-1:-1:-1;;;59178:66:0;;;;;;;;;59303:28;;:::i;:::-;59347:13;;:68;;-1:-1:-1;;;59347:68:0;;-1:-1:-1;;;;;59347:13:0;;;;:33;;:68;;59381:8;;59391:17;;59347:13;;:68;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59347:68:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59347:68:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;59347:68:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;59347:68:0;;;;;;;;;59430:13;;59303:112;;-1:-1:-1;59426:27:0;;59452:1;59445:8;;;;;;59426:27;59466:18;;:::i;:::-;59487;:16;:18::i;:::-;59466:39;;59518:22;59543:1;59518:26;;59555:28;59600:3;59586:18;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;59586:18:0;-1:-1:-1;59555:49:0;-1:-1:-1;59705:9:0;59701:630;59724:3;59720:1;:7;59701:630;;;59748:22;59773:17;59791:1;59773:20;;;;;;;;;;;;;;59748:45;;59828:1;59811:14;:18;59808:512;;;59920:20;;:::i;:::-;59943:5;:13;;;59957:1;59943:16;;;;;;;;;;;;;;59920:39;;59981:25;60008:22;60055:124;60070:6;:11;;;60083:6;:12;;;60097:5;:17;;;60115:1;60097:20;;;;;;;;;;;;;;60119:6;:27;;;60148:14;60164:5;:14;;;60055;:124::i;:::-;59980:199;;;;60217:17;60200:11;60212:1;60200:14;;;;;;;;;;;;;;;;;:34;60270;:14;60289;60270:34;:18;:34;:::i;:::-;60253:51;;59808:512;;;;-1:-1:-1;59729:3:0;;59701:630;;;;60366:1;60349:14;:18;60341:57;;;;-1:-1:-1;;;60341:57:0;;;;;;;;;60411:13;;60447;;;;60462:17;;;;;60411:82;;-1:-1:-1;;;60411:82:0;;-1:-1:-1;;;;;60411:13:0;;;;:35;;:82;;60447:13;;60481:11;;60411:82;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60411:82:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;60608:14:0;;60641:21;;60664:13;;;;60608:83;;-1:-1:-1;;;60608:83:0;;60568:14;;-1:-1:-1;60584:20:0;;-1:-1:-1;;;;;;60608:14:0;;;;:32;;:83;;60641:21;;60679:11;;60608:83;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60608:83:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60608:83:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;60608:83:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;60608:83:0;;;;;;;;;60567:124;;;;60710:9;60721:6;60702:26;;;;;-1:-1:-1;;;60702:26:0;;;;;;;;;;;60769:33;60775:10;60787:14;60769:5;:33::i;:::-;60830:10;-1:-1:-1;;;;;60818:80:0;;60842:10;60854:14;60870:8;60880:17;60818:80;;;;;;;;;;;;;;;;;;-1:-1:-1;60918:14:0;;58848:2092;-1:-1:-1;;;;;;;;;58848:2092:0:o;73026:2187::-;73198:22;-1:-1:-1;;;;;73246:24:0;;73238:62;;;;-1:-1:-1;;;73238:62:0;;;;;;;;;73333:24;;73376:15;;;;;:49;;;73410:8;:15;73395:11;:30;73376:49;73368:82;;;;-1:-1:-1;;;73368:82:0;;;;;;;;;73497:24;;:::i;:::-;73524:13;;:44;;-1:-1:-1;;;73524:44:0;;-1:-1:-1;;;;;73524:13:0;;;;:34;;:44;;73559:8;;73524:44;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73524:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73524:44:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;73524:44:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;73524:44:0;;;;;;;;;73583:13;;73497:71;;-1:-1:-1;73579:27:0;;73605:1;73598:8;;;;;;73579:27;73619:18;;:::i;:::-;73640;:16;:18::i;:::-;73619:39;;73704:20;73726;73748:13;73778:14;;;;;;;;;-1:-1:-1;;;;;73778:14:0;-1:-1:-1;;;;;73778:33:0;;73812:5;73819;:21;;;73842:5;:16;;;73860:5;:13;;;73875:17;73778:115;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73778:115:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73778:115:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;73778:115:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;73778:115:0;;;;;;;;;73703:190;;;;;;73912:15;73929:6;73904:32;;;;;-1:-1:-1;;;73904:32:0;;;;;;;;;;-1:-1:-1;73949:22:0;;74036:385;74059:11;74055:1;:15;74036:385;;;74091:22;74116:17;74134:1;74116:20;;;;;;;;;;;;;;74091:45;;74171:1;74154:14;:18;74151:259;;;74242:21;74266:59;74302:5;:13;;;74316:1;74302:16;;;;;;;;;;;;;;:22;;;74266:14;:35;;:59;;;;:::i;:::-;74242:83;-1:-1:-1;74361:33:0;:14;74242:83;74361:33;:18;:33;:::i;:::-;74344:50;;74151:259;;-1:-1:-1;74072:3:0;;74036:385;;;;74456:1;74439:14;:18;74431:55;;;;-1:-1:-1;;;74431:55:0;;;;;;;;;74546:11;74560:8;:22;;74581:1;74560:22;;;74571:7;;74560:22;74546:36;;74662:416;74694:373;;;;;;;;74745:10;-1:-1:-1;;;;;74694:373:0;;;;;74790:14;74694:373;;;;74841:17;74694:373;;;;74886:5;:13;;;74694:373;;;;74931:5;:17;;;74694:373;;;;74976:3;74694:373;;;;75007:5;:13;;;74694:373;;;;75046:5;74694:373;;;74662:17;:416::i;:::-;75105:10;-1:-1:-1;;;;;75096:77:0;;75117:10;75129:14;75145:8;75155:17;75096:77;;;;;;;;;;;;;;;;;;-1:-1:-1;75191:14:0;73026:2187;-1:-1:-1;;;;;;;;;;73026:2187:0:o;75277:1505::-;-1:-1:-1;;;;;75412:24:0;;75404:62;;;;-1:-1:-1;;;75404:62:0;;;;;;;;;75503:1;75485:15;:19;75477:59;;;;-1:-1:-1;;;75477:59:0;;;;;;;;;75586:29;;:::i;:::-;75618:13;;;;;;;;;-1:-1:-1;;;;;75618:13:0;-1:-1:-1;;;;;75618:32:0;;:34;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;75618:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;75618:34:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;75618:34:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;75618:34:0;;;;;;;;;75586:66;;75663:16;75682:57;75697:5;:14;;;75713:25;:23;:25::i;75682:57::-;75663:76;-1:-1:-1;75827:36:0;75866:37;:15;75663:76;75866:37;:27;:37;:::i;:::-;76055:14;;76125:13;;;;76055:84;;-1:-1:-1;;;76055:84:0;;75827:76;;-1:-1:-1;75961:20:0;;75983;;;;-1:-1:-1;;;;;76055:14:0;;;;:39;;:84;;75827:76;;76125:13;76055:84;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;76055:84:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;76055:84:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;76055:84:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;76055:84:0;;;;;;;;;75960:179;;;;;;76158:15;76175:6;76150:32;;;;;-1:-1:-1;;;76150:32:0;;;;;;;;;;;76262:439;76294:396;;;;;;;;76345:10;-1:-1:-1;;;;;76294:396:0;;;;;76390:15;76294:396;;;;76442:16;76294:396;;;;76486:5;:13;;;76294:396;;;;76531:5;:17;;;76294:396;;;;76576:13;;76294:396;;;;76617:5;:13;;;76294:396;;;;76656:18;:16;:18::i;:::-;76294:396;;76262:17;:439::i;:::-;76734:10;-1:-1:-1;;;;;76719:55:0;;76746:10;76758:15;76719:55;;;;;;;;;;;;;;;;75277:1505;;;;;;;;:::o;10899:508::-;11316:4;11362:17;11394:7;10899:508;:::o;29742:163::-;29833:64;29872:8;29882:10;29894:2;29833:38;:64::i;:::-;29742:163;;:::o;33107:200::-;-1:-1:-1;;;;;33172:20:0;;33164:54;;;;-1:-1:-1;;;33164:54:0;;;;;;;;;33229:5;:22;;-1:-1:-1;;;;;;33229:22:0;-1:-1:-1;;;;;33229:22:0;;;;;33262:37;:35;:37::i;:::-;33107:200;:::o;35685:487::-;36146:11;:18;;-1:-1:-1;;;;36146:18:0;-1:-1:-1;;;36146:18:0;;;35685:487::o;38913:167::-;39006:7;39038:34;39055:1;39058;37244:4;39038:16;:34::i;51249:521::-;51427:19;51448:24;51490:17;51517:7;-1:-1:-1;;;;;51510:25:0;;51536:10;51510:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51510:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51510:37:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;51510:37:0;;;;;;;;;51490:57;-1:-1:-1;51558:59:0;-1:-1:-1;;;;;51558:32:0;;51591:7;51600:10;51612:4;51558:59;:32;:59;:::i;:::-;51647:37;;-1:-1:-1;;;51647:37:0;;-1:-1:-1;;;;;51647:25:0;;;;;:37;;51673:10;;51647:37;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51647:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51647:37:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;51647:37:0;;;;;;;;;51628:56;-1:-1:-1;51709:53:0;51724:4;51730:31;51628:56;51751:9;51730:31;:20;:31;:::i;51709:53::-;51695:67;;51249:521;;;;;;;;:::o;43967:138::-;44052:7;44088:1;44084;:5;:13;;44096:1;44084:13;;43377:271;43480:9;;43554:18;:1;37660:3;43554:18;:5;:18;:::i;:::-;43542:30;-1:-1:-1;43628:12:0;43542:30;43634:5;43628:12;:5;:12;:::i;:::-;43621:19;43377:271;-1:-1:-1;;;;43377:271:0:o;18576:132::-;18634:7;18661:39;18665:1;18668;18661:39;;;;;;;;;;;;;;;;;:3;:39::i;82349:486::-;82483:13;;:::i;:::-;82517:12;;82514:253;;82546:11;82559:14;82577:39;82590:15;82607:8;82577:12;:39::i;:::-;82545:71;;;;82646:10;-1:-1:-1;;;;;82638:32:0;;82658:6;82666:3;82638:32;;;;;;;;;;;;;;;;82694:61;;;;;;;;;;;;;;;;;;;;82726:28;:3;82747:6;82726:28;:20;:28;:::i;:::-;82694:61;;;82687:68;;;;;;82514:253;-1:-1:-1;;82784:43:0;;;;;;;;;;;;;;;;;;-1:-1:-1;82784:43:0;;;;-1:-1:-1;82784:43:0;82349:486;-1:-1:-1;82349:486:0:o;39553:312::-;39666:7;;39781:8;:1;39787;39781:8;:5;:8;:::i;:::-;39769:20;-1:-1:-1;39845:12:0;39769:20;39851:5;39845:12;:5;:12;:::i;:::-;39838:19;39553:312;-1:-1:-1;;;;;39553:312:0:o;42520:449::-;42626:7;;42766:12;:1;42772:5;42766:12;:5;:12;:::i;:::-;42749:29;-1:-1:-1;42831:12:0;42846:30;42857:18;37660:3;42873:1;42857:18;:15;:18;:::i;:::-;42846:6;;:30;:10;:30;:::i;:::-;42831:45;-1:-1:-1;42940:21:0;42831:45;37660:3;42940:21;:8;:21;:::i;77709:1522::-;77854:38;77860:10;77872:4;:19;;;77854:5;:38::i;:::-;77997:12;;;;:19;78057:26;;;;;;;;;;;;;;;;78027:27;;77997:19;78057:26;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;78057:26:0;-1:-1:-1;78027:56:0;-1:-1:-1;78094:12:0;;78121:843;78144:11;78140:1;:15;78121:843;;;78176:17;;:::i;:::-;78196:573;78230:524;;;;;;;;78276:4;:21;;;78298:1;78276:24;;;;;;;;;;;;;;78230:524;;;;78331:4;:12;;;78344:1;78331:15;;;;;;;;;;;;;;:20;;;-1:-1:-1;;;;;78230:524:0;;;;;78386:4;:16;;;78403:1;78386:19;;;;;;;;;;;;;;-1:-1:-1;;;;;78230:524:0;;;;;78437:4;:12;;;78230:524;;;;78482:4;:12;;;78495:1;78482:15;;;;;;;;;;;;;;:36;;;78230:524;;;;;;78552:4;:14;;;-1:-1:-1;;;;;78230:524:0;;;;;78596:4;:12;;;78609:1;78596:15;;;;;;;;;;;;;;:21;;;78230:524;;;;78650:4;:10;;;:19;;;78230:524;;;;78706:4;:12;;;78719:1;78706:15;;;;;;;;;;;;;;:28;;;78230:524;;;78196:15;:573::i;:::-;78176:593;;78856:3;:7;;;78840:10;78851:1;78840:13;;;;;;;;;;;;;;;;;:23;78938:13;;;;78929:23;;:4;;:23;:8;:23;:::i;:::-;78922:30;-1:-1:-1;;78157:3:0;;78121:843;;;-1:-1:-1;79039:10:0;;;;:18;;;:28;;79062:4;79039:28;:22;:28;:::i;:::-;79029:7;:38;79144:13;;79180:12;;;;79194:16;;;;79144:79;;-1:-1:-1;;;79144:79:0;;-1:-1:-1;;;;;79144:13:0;;;;:35;;:79;;79180:12;;79212:10;;79144:79;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;79144:79:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;37795:92:0;37244:4;37795:92;:::o;28299:195::-;28407:15;;;;:5;;:15;;;;;:::i;:::-;-1:-1:-1;28433:19:0;;;;:7;;:19;;;;;:::i;:::-;-1:-1:-1;28463:9:0;:23;;-1:-1:-1;;28463:23:0;;;;;;;;;;;;-1:-1:-1;;28299:195:0:o;30647:623::-;30872:23;;;;;;;;;;;;;;;30855:14;:40;30920:20;;;;;;;;;;;;;30906:11;:34;30969:23;;;;;;;;;;;;;30951:15;:41;31022:22;;;;;;;;;;;;;31005:14;:39;31069:20;;;;;;;;;;;;;31055:11;:34;31123:29;;;;;;;;;;;;;31100:20;:52;31180:22;;;;;;;;;;;;;31163:14;:39;31235:27;;;;;;;;;;;;31213:19;:49;;;;30647:623::o;48137:204::-;48264:68;;48238:95;;48257:5;;-1:-1:-1;;;48287:27:0;48264:68;;48316:4;;48322:2;;48326:5;;48264:68;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;48264:68:0;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;48264:68:0;;;179:29:-1;;;;160:49;;;48238:18:0;:95::i;:::-;48137:204;;;;:::o;17637:471::-;17695:7;17940:6;17936:47;;-1:-1:-1;17970:1:0;17963:8;;17936:47;18007:5;;;18011:1;18007;:5;:1;18031:5;;;;;:10;18023:56;;;;-1:-1:-1;;;18023:56:0;;;;;;;;19238:345;19324:7;19426:12;19419:5;19411:28;;;;-1:-1:-1;;;19411:28:0;;;;;;;;;;;19450:9;19466:1;19462;:5;;;;;;;19238:345;-1:-1:-1;;;;;19238:345:0:o;26337:348::-;-1:-1:-1;;;;;26413:21:0;;26405:67;;;;-1:-1:-1;;;26405:67:0;;;;;;;;;26506:68;26529:6;26506:68;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;26506:18:0;;;;;;:9;:18;;;;;;;:68;;:22;:68;:::i;:::-;-1:-1:-1;;;;;26485:18:0;;;;;;:9;:18;;;;;:89;26600:12;;:24;;26617:6;26600:24;:16;:24;:::i;:::-;26585:12;:39;26640:37;;26666:1;;-1:-1:-1;;;;;26640:37:0;;;;;;;26670:6;;26640:37;;49992:1114;50596:27;50604:5;-1:-1:-1;;;;;50596:25:0;;:27::i;:::-;50588:71;;;;-1:-1:-1;;;50588:71:0;;;;;;;;;50733:12;50747:23;50782:5;-1:-1:-1;;;;;50774:19:0;50794:4;50774:25;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;50732:67:0;;;;50818:7;50810:52;;;;-1:-1:-1;;;50810:52:0;;;;;;;;;50879:17;;:21;50875:224;;51021:10;51010:30;;;;;;;;;;;;;;51002:85;;;;-1:-1:-1;;;51002:85:0;;;;;;;;45543:619;45603:4;46071:20;;45914:66;46111:23;;;;;;:42;;-1:-1:-1;;46138:15:0;;;46103:51;-1:-1:-1;;45543:619:0:o;52402:36471::-;;;;;;;;;-1:-1:-1;52402:36471:0;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;-1:-1:-1;52402:36471:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;52402:36471:0;;;-1:-1:-1;52402:36471:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;5:130:-1;72:20;;97:33;72:20;97:33;;142:134;220:13;;238:33;220:13;238:33;;301:352;;;431:3;424:4;416:6;412:17;408:27;398:2;;449:1;446;439:12;398:2;-1:-1;469:20;;-1:-1;;;;;498:30;;495:2;;;541:1;538;531:12;495:2;575:4;567:6;563:17;551:29;;626:3;618:4;610:6;606:17;596:8;592:32;589:41;586:2;;;643:1;640;633:12;586:2;391:262;;;;;;679:714;;803:3;796:4;788:6;784:17;780:27;770:2;;821:1;818;811:12;770:2;851:6;845:13;873:76;888:60;941:6;888:60;;;873:76;;;864:85;;966:5;991:6;984:5;977:21;1021:4;1013:6;1009:17;999:27;;1043:4;1038:3;1034:14;1027:21;;1096:6;1143:3;1135:4;1127:6;1123:17;1118:3;1114:27;1111:36;1108:2;;;1160:1;1157;1150:12;1108:2;1185:1;1170:217;1195:6;1192:1;1189:13;1170:217;;;1253:3;1275:48;1319:3;1307:10;1275:48;;;1263:61;;-1:-1;1347:4;1338:14;;;;1366;;;;;1217:1;1210:9;1170:217;;;1174:14;763:630;;;;;;;;1439:768;;1581:3;1574:4;1566:6;1562:17;1558:27;1548:2;;1599:1;1596;1589:12;1548:2;1629:6;1623:13;1651:94;1666:78;1737:6;1666:78;;1651:94;1642:103;;1762:5;1787:6;1780:5;1773:21;1817:4;1809:6;1805:17;1795:27;;1839:4;1834:3;1830:14;1823:21;;1892:6;1939:3;1931:4;1923:6;1919:17;1914:3;1910:27;1907:36;1904:2;;;1956:1;1953;1946:12;1904:2;1981:1;1966:235;1991:6;1988:1;1985:13;1966:235;;;2049:3;2071:66;2133:3;2121:10;2071:66;;;2059:79;;-1:-1;2161:4;2152:14;;;;2189:4;2180:14;;;;;2013:1;2006:9;1966:235;;2611:722;;2739:3;2732:4;2724:6;2720:17;2716:27;2706:2;;2757:1;2754;2747:12;2706:2;2787:6;2781:13;2809:80;2824:64;2881:6;2824:64;;2809:80;2800:89;;2906:5;2931:6;2924:5;2917:21;2961:4;2953:6;2949:17;2939:27;;2983:4;2978:3;2974:14;2967:21;;3036:6;3083:3;3075:4;3067:6;3063:17;3058:3;3054:27;3051:36;3048:2;;;3100:1;3097;3090:12;3048:2;3125:1;3110:217;3135:6;3132:1;3129:13;3110:217;;;3193:3;3215:48;3259:3;3247:10;3215:48;;;3203:61;;-1:-1;3287:4;3278:14;;;;3306;;;;;3157:1;3150:9;3110:217;;3357:708;;3479:3;3472:4;3464:6;3460:17;3456:27;3446:2;;3497:1;3494;3487:12;3446:2;3527:6;3521:13;3549:74;3564:58;3615:6;3564:58;;3549:74;3540:83;;3640:5;3665:6;3658:5;3651:21;3695:4;3687:6;3683:17;3673:27;;3717:4;3712:3;3708:14;3701:21;;3770:6;3817:3;3809:4;3801:6;3797:17;3792:3;3788:27;3785:36;3782:2;;;3834:1;3831;3824:12;3782:2;3859:1;3844:215;3869:6;3866:1;3863:13;3844:215;;;3927:3;3949:46;3991:3;3979:10;3949:46;;;3937:59;;-1:-1;4019:4;4010:14;;;;4038;;;;;3891:1;3884:9;3844:215;;4073:128;4148:13;;4166:30;4148:13;4166:30;;4208:164;4301:13;;4319:48;4301:13;4319:48;;4394:337;;;4509:3;4502:4;4494:6;4490:17;4486:27;4476:2;;4527:1;4524;4517:12;4476:2;-1:-1;4547:20;;-1:-1;;;;;4576:30;;4573:2;;;4619:1;4616;4609:12;4573:2;4653:4;4645:6;4641:17;4629:29;;4704:3;4696:4;4688:6;4684:17;4674:8;4670:32;4667:41;4664:2;;;4721:1;4718;4711:12;4740:444;;4853:3;4846:4;4838:6;4834:17;4830:27;4820:2;;4871:1;4868;4861:12;4820:2;4901:6;4895:13;4923:65;4938:49;4980:6;4938:49;;4923:65;4914:74;;5008:6;5001:5;4994:21;5044:4;5036:6;5032:17;5077:4;5070:5;5066:16;5112:3;5103:6;5098:3;5094:16;5091:25;5088:2;;;5129:1;5126;5119:12;5088:2;5139:39;5171:6;5166:3;5161;5139:39;;;4813:371;;;;;;;;5233:688;;5362:6;5350:9;5345:3;5341:19;5337:32;5334:2;;;5382:1;5379;5372:12;5334:2;5400:20;5415:4;5400:20;;;5391:29;-1:-1;5472:1;5504:78;5578:3;5558:9;5504:78;;;5479:104;;-1:-1;5650:3;5684:60;5740:3;5716:22;;;5684:60;;;5677:4;5670:5;5666:16;5659:86;5604:152;5807:3;5841:58;5895:3;5886:6;5875:9;5871:22;5841:58;;;5834:4;5827:5;5823:16;5816:84;5766:145;5328:593;;;;;5962:1159;;6080:4;6068:9;6063:3;6059:19;6055:30;6052:2;;;6098:1;6095;6088:12;6052:2;6116:20;6131:4;6116:20;;;6107:29;-1:-1;6186:1;6218:60;6274:3;6254:9;6218:60;;;6193:86;;-1:-1;6342:2;6375:75;6446:3;6422:22;;;6375:75;;;6368:4;6361:5;6357:16;6350:101;6300:162;6528:2;6561:57;6614:3;6605:6;6594:9;6590:22;6561:57;;;6554:4;6547:5;6543:16;6536:83;6472:158;6681:2;6714:60;6770:3;6761:6;6750:9;6746:22;6714:60;;;6707:4;6700:5;6696:16;6689:86;6640:146;6841:3;6875:60;6931:3;6922:6;6911:9;6907:22;6875:60;;;6868:4;6861:5;6857:16;6850:86;6796:151;7005:3;7039:60;7095:3;7086:6;7075:9;7071:22;7039:60;;;7032:4;7025:5;7021:16;7014:86;6957:154;6046:1075;;;;;7171:1145;;7302:4;7290:9;7285:3;7281:19;7277:30;7274:2;;;7320:1;7317;7310:12;7274:2;7338:20;7353:4;7338:20;;;7329:29;-1:-1;7411:1;7443:57;7496:3;7476:9;7443:57;;;7418:83;;-1:-1;7586:2;7571:18;;7565:25;-1:-1;;;;;7599:30;;7596:2;;;7642:1;7639;7632:12;7596:2;7677:99;7772:3;7763:6;7752:9;7748:22;7677:99;;;7670:4;7663:5;7659:16;7652:125;7522:266;7866:2;7855:9;7851:18;7845:25;-1:-1;;;;;7882:6;7879:30;7876:2;;;7922:1;7919;7912:12;7876:2;7957:81;8034:3;8025:6;8014:9;8010:22;7957:81;;;7950:4;7943:5;7939:16;7932:107;7798:252;8124:2;8113:9;8109:18;8103:25;-1:-1;;;;;8140:6;8137:30;8134:2;;;8180:1;8177;8170:12;8134:2;8215:79;8290:3;8281:6;8270:9;8266:22;8215:79;;;8208:4;8201:5;8197:16;8190:105;8060:246;7268:1048;;;;;8367:1150;;8499:4;8487:9;8482:3;8478:19;8474:30;8471:2;;;8517:1;8514;8507:12;8471:2;8535:20;8550:4;8535:20;;;8526:29;-1:-1;8609:1;8641:60;8697:3;8677:9;8641:60;;9563:1421;;9690:4;9678:9;9673:3;9669:19;9665:30;9662:2;;;9708:1;9705;9698:12;9662:2;9726:20;9741:4;9726:20;;;9717:29;-1:-1;9799:1;9831:57;9884:3;9864:9;9831:57;;;9806:83;;-1:-1;9977:2;9962:18;;9956:25;-1:-1;;;;;9990:30;;9987:2;;;10033:1;10030;10023:12;9987:2;10068:99;10163:3;10154:6;10143:9;10139:22;10068:99;;;10061:4;10054:5;10050:16;10043:125;9910:269;10253:2;10242:9;10238:18;10232:25;-1:-1;;;;;10269:6;10266:30;10263:2;;;10309:1;10306;10299:12;10263:2;10344:99;10439:3;10430:6;10419:9;10415:22;10344:99;;;10337:4;10330:5;10326:16;10319:125;10189:266;10533:2;10522:9;10518:18;10512:25;-1:-1;;;;;10549:6;10546:30;10543:2;;;10589:1;10586;10579:12;10543:2;10624:81;10701:3;10692:6;10681:9;10677:22;10624:81;;;10617:4;10610:5;10606:16;10599:107;10465:252;10791:3;10780:9;10776:19;10770:26;-1:-1;;;;;10808:6;10805:30;10802:2;;;10848:1;10845;10838:12;10802:2;10883:79;10958:3;10949:6;10938:9;10934:22;10883:79;;;10876:4;10869:5;10865:16;10858:105;10727:247;9656:1328;;;;;10991:130;11058:20;;11083:33;11058:20;11083:33;;11128:134;11206:13;;11224:33;11206:13;11224:33;;11269:130;11345:13;;11363:31;11345:13;11363:31;;11406:241;;11510:2;11498:9;11489:7;11485:23;11481:32;11478:2;;;11526:1;11523;11516:12;11478:2;11561:1;11578:53;11623:7;11603:9;11578:53;;11654:263;;11769:2;11757:9;11748:7;11744:23;11740:32;11737:2;;;11785:1;11782;11775:12;11737:2;11820:1;11837:64;11893:7;11873:9;11837:64;;11924:366;;;12045:2;12033:9;12024:7;12020:23;12016:32;12013:2;;;12061:1;12058;12051:12;12013:2;12096:1;12113:53;12158:7;12138:9;12113:53;;;12103:63;;12075:97;12203:2;12221:53;12266:7;12257:6;12246:9;12242:22;12221:53;;;12211:63;;12182:98;12007:283;;;;;;12297:491;;;;12435:2;12423:9;12414:7;12410:23;12406:32;12403:2;;;12451:1;12448;12441:12;12403:2;12486:1;12503:53;12548:7;12528:9;12503:53;;;12493:63;;12465:97;12593:2;12611:53;12656:7;12647:6;12636:9;12632:22;12611:53;;;12601:63;;12572:98;12701:2;12719:53;12764:7;12755:6;12744:9;12740:22;12719:53;;;12709:63;;12680:98;12397:391;;;;;;12795:617;;;;;12950:3;12938:9;12929:7;12925:23;12921:33;12918:2;;;12967:1;12964;12957:12;12918:2;13002:1;13019:53;13064:7;13044:9;13019:53;;;13009:63;;12981:97;13109:2;13127:53;13172:7;13163:6;13152:9;13148:22;13127:53;;;13117:63;;13088:98;13217:2;13235:53;13280:7;13271:6;13260:9;13256:22;13235:53;;;13225:63;;13196:98;13325:2;13343:53;13388:7;13379:6;13368:9;13364:22;13343:53;;;13333:63;;13304:98;12912:500;;;;;;;;13419:366;;;13540:2;13528:9;13519:7;13515:23;13511:32;13508:2;;;13556:1;13553;13546:12;13508:2;13591:1;13608:53;13653:7;13633:9;13608:53;;;13598:63;;13570:97;13698:2;13716:53;13761:7;13752:6;13741:9;13737:22;13716:53;;13792:491;;;;13930:2;13918:9;13909:7;13905:23;13901:32;13898:2;;;13946:1;13943;13936:12;13898:2;13981:1;13998:53;14043:7;14023:9;13998:53;;;13988:63;;13960:97;14088:2;14106:53;14151:7;14142:6;14131:9;14127:22;14106:53;;;14096:63;;14067:98;14196:2;14214:53;14259:7;14250:6;14239:9;14235:22;14214:53;;14290:803;;;;;;14498:2;14486:9;14477:7;14473:23;14469:32;14466:2;;;14514:1;14511;14504:12;14466:2;14549:31;;-1:-1;;;;;14589:30;;14586:2;;;14632:1;14629;14622:12;14586:2;14660:80;14732:7;14723:6;14712:9;14708:22;14660:80;;;14650:90;;;;14528:218;14805:2;14794:9;14790:18;14777:32;-1:-1;;;;;14821:6;14818:30;14815:2;;;14861:1;14858;14851:12;14815:2;14889:80;14961:7;14952:6;14941:9;14937:22;14889:80;;;14879:90;;;;14756:219;15006:2;15024:53;15069:7;15060:6;15049:9;15045:22;15024:53;;;15014:63;;14985:98;14460:633;;;;;;;;;15100:257;;15212:2;15200:9;15191:7;15187:23;15183:32;15180:2;;;15228:1;15225;15218:12;15180:2;15263:1;15280:61;15333:7;15313:9;15280:61;;15364:492;;;15503:2;15491:9;15482:7;15478:23;15474:32;15471:2;;;15519:1;15516;15509:12;15471:2;15554:1;15571:61;15624:7;15604:9;15571:61;;;15561:71;;15533:105;15690:2;15679:9;15675:18;15669:25;-1:-1;;;;;15706:6;15703:30;15700:2;;;15746:1;15743;15736:12;15700:2;15766:74;15832:7;15823:6;15812:9;15808:22;15766:74;;15863:757;;;;16044:2;16032:9;16023:7;16019:23;16015:32;16012:2;;;16060:1;16057;16050:12;16012:2;16095:1;16112:61;16165:7;16145:9;16112:61;;;16102:71;;16074:105;16231:2;16220:9;16216:18;16210:25;-1:-1;;;;;16247:6;16244:30;16241:2;;;16287:1;16284;16277:12;16241:2;16307:74;16373:7;16364:6;16353:9;16349:22;16307:74;;;16297:84;;16189:198;16439:2;16428:9;16424:18;16418:25;-1:-1;;;;;16455:6;16452:30;16449:2;;;16495:1;16492;16485:12;16449:2;16515:89;16596:7;16587:6;16576:9;16572:22;16515:89;;16627:622;;;;16780:2;16768:9;16759:7;16755:23;16751:32;16748:2;;;16796:1;16793;16786:12;16748:2;16831:1;16848:61;16901:7;16881:9;16848:61;;;16838:71;;16810:105;16967:2;16956:9;16952:18;16946:25;-1:-1;;;;;16983:6;16980:30;16977:2;;;17023:1;17020;17013:12;16977:2;17043:74;17109:7;17100:6;17089:9;17085:22;17043:74;;;17033:84;;16925:198;17154:2;17172:61;17225:7;17216:6;17205:9;17201:22;17172:61;;17256:882;;;;;17487:3;17475:9;17466:7;17462:23;17458:33;17455:2;;;17504:1;17501;17494:12;17455:2;17539:1;17556:61;17609:7;17589:9;17556:61;;;17546:71;;17518:105;17675:2;17664:9;17660:18;17654:25;-1:-1;;;;;17691:6;17688:30;17685:2;;;17731:1;17728;17721:12;17685:2;17751:74;17817:7;17808:6;17797:9;17793:22;17751:74;;;17741:84;;17633:198;17862:2;17880:93;17965:7;17956:6;17945:9;17941:22;17880:93;;;17870:103;;17841:138;18010:3;18029:93;18114:7;18105:6;18094:9;18090:22;18029:93;;18145:759;;;;;18315:3;18303:9;18294:7;18290:23;18286:33;18283:2;;;18332:1;18329;18322:12;18283:2;18367:1;18384:61;18437:7;18417:9;18384:61;;;18374:71;;18346:105;18503:2;18492:9;18488:18;18482:25;-1:-1;;;;;18519:6;18516:30;18513:2;;;18559:1;18556;18549:12;18513:2;18579:74;18645:7;18636:6;18625:9;18621:22;18579:74;;;18569:84;;18461:198;18690:2;18708:64;18764:7;18755:6;18744:9;18740:22;18708:64;;;18698:74;;18669:109;18809:2;18827:61;18880:7;18871:6;18860:9;18856:22;18827:61;;18911:452;;;19069:3;19057:9;19048:7;19044:23;19040:33;19037:2;;;19086:1;19083;19076:12;19037:2;19121:1;19138:61;19191:7;19171:9;19138:61;;;19128:71;;19100:105;19236:2;19254:93;19339:7;19330:6;19319:9;19315:22;19254:93;;19370:995;;;;;;;;19582:3;19570:9;19561:7;19557:23;19553:33;19550:2;;;19599:1;19596;19589:12;19550:2;19634:31;;-1:-1;;;;;19674:30;;19671:2;;;19717:1;19714;19707:12;19671:2;19745:65;19802:7;19793:6;19782:9;19778:22;19745:65;;;19735:75;;;;19613:203;19875:2;19864:9;19860:18;19847:32;-1:-1;;;;;19891:6;19888:30;19885:2;;;19931:1;19928;19921:12;19885:2;19959:65;20016:7;20007:6;19996:9;19992:22;19959:65;;;19949:75;;;;19826:204;20061:2;20079:53;20124:7;20115:6;20104:9;20100:22;20079:53;;;20069:63;;20040:98;20169:2;20187:53;20232:7;20223:6;20212:9;20208:22;20187:53;;;20177:63;;20148:98;20277:3;20296:53;20341:7;20332:6;20321:9;20317:22;20296:53;;;20286:63;;20256:99;19544:821;;;;;;;;;;;20372:404;;20518:2;20506:9;20497:7;20493:23;20489:32;20486:2;;;20534:1;20531;20524:12;20486:2;20569:24;;-1:-1;;;;;20602:30;;20599:2;;;20645:1;20642;20635:12;20599:2;20665:95;20752:7;20743:6;20732:9;20728:22;20665:95;;20783:406;;20930:2;20918:9;20909:7;20905:23;20901:32;20898:2;;;20946:1;20943;20936:12;20898:2;20981:24;;-1:-1;;;;;21014:30;;21011:2;;;21057:1;21054;21047:12;21011:2;21077:96;21165:7;21156:6;21145:9;21141:22;21077:96;;21196:396;;21338:2;21326:9;21317:7;21313:23;21309:32;21306:2;;;21354:1;21351;21344:12;21306:2;21389:24;;-1:-1;;;;;21422:30;;21419:2;;;21465:1;21462;21455:12;21419:2;21485:91;21568:7;21559:6;21548:9;21544:22;21485:91;;21599:241;;21703:2;21691:9;21682:7;21678:23;21674:32;21671:2;;;21719:1;21716;21709:12;21671:2;21754:1;21771:53;21816:7;21796:9;21771:53;;21847:263;;21962:2;21950:9;21941:7;21937:23;21933:32;21930:2;;;21978:1;21975;21968:12;21930:2;22013:1;22030:64;22086:7;22066:9;22030:64;;22117:366;;;22238:2;22226:9;22217:7;22213:23;22209:32;22206:2;;;22254:1;22251;22244:12;22206:2;22289:1;22306:53;22351:7;22331:9;22306:53;;22490:528;;;22647:2;22635:9;22626:7;22622:23;22618:32;22615:2;;;22663:1;22660;22653:12;22615:2;22698:1;22715:64;22771:7;22751:9;22715:64;;;22705:74;;22677:108;22837:2;22826:9;22822:18;22816:25;-1:-1;;;;;22853:6;22850:30;22847:2;;;22893:1;22890;22883:12;22847:2;22913:89;22994:7;22985:6;22974:9;22970:22;22913:89;;23026:173;;23113:46;23155:3;23147:6;23113:46;;;-1:-1;;23188:4;23179:14;;23106:93;23208:249;;23331:86;23413:3;23405:6;23331:86;;;-1:-1;;23446:4;23437:14;;23324:133;23466:173;;23553:46;23595:3;23587:6;23553:46;;23648:165;;23731:42;23769:3;23761:6;23731:42;;23821:103;23894:24;23912:5;23894:24;;;23889:3;23882:37;23876:48;;;24082:690;;24227:54;24275:5;24227:54;;;24294:86;24373:6;24368:3;24294:86;;;24287:93;;24401:56;24451:5;24401:56;;;24477:7;24505:1;24490:260;24515:6;24512:1;24509:13;24490:260;;;24582:6;24576:13;24603:63;24662:3;24647:13;24603:63;;;24596:70;;24683:60;24736:6;24683:60;;;24673:70;-1:-1;;24537:1;24530:9;24490:260;;;-1:-1;24763:3;;24206:566;-1:-1;;;;;24206:566;24811:674;;24952:50;24996:5;24952:50;;;25015:86;25094:6;25089:3;25015:86;;;25008:93;;25122:52;25168:5;25122:52;;;25194:7;25222:1;25207:256;25232:6;25229:1;25226:13;25207:256;;;25299:6;25293:13;25320:63;25379:3;25364:13;25320:63;;;25313:70;;25400:56;25449:6;25400:56;;;25390:66;-1:-1;;25254:1;25247:9;25207:256;;25564:818;;25741:68;25803:5;25741:68;;;25822:104;25919:6;25914:3;25822:104;;;25815:111;;25947:70;26011:5;25947:70;;;26037:7;26065:1;26050:310;26075:6;26072:1;26069:13;26050:310;;;26142:6;26136:13;26163:99;26258:3;26243:13;26163:99;;;26156:106;;26279:74;26346:6;26279:74;;;26269:84;-1:-1;;26097:1;26090:9;26050:310;;26421:690;;26566:54;26614:5;26566:54;;;26633:86;26712:6;26707:3;26633:86;;;26626:93;;26740:56;26790:5;26740:56;;;26816:7;26844:1;26829:260;26854:6;26851:1;26848:13;26829:260;;;26921:6;26915:13;26942:63;27001:3;26986:13;26942:63;;;26935:70;;27022:60;27075:6;27022:60;;;27012:70;-1:-1;;26876:1;26869:9;26829:260;;27150:674;;27291:50;27335:5;27291:50;;;27354:86;27433:6;27428:3;27354:86;;;27347:93;;27461:52;27507:5;27461:52;;;27533:7;27561:1;27546:256;27571:6;27568:1;27565:13;27546:256;;;27638:6;27632:13;27659:63;27718:3;27703:13;27659:63;;;27652:70;;27739:56;27788:6;27739:56;;;27729:66;-1:-1;;27593:1;27586:9;27546:256;;27859:658;;27996:48;28038:5;27996:48;;;28057:84;28134:6;28129:3;28057:84;;;28050:91;;28162:50;28206:5;28162:50;;;28232:7;28260:1;28245:250;28270:6;28267:1;28264:13;28245:250;;;28337:6;28331:13;28358:59;28413:3;28398:13;28358:59;;;28351:66;;28434:54;28481:6;28434:54;;;28424:64;-1:-1;;28292:1;28285:9;28245:250;;28525:94;28592:21;28607:5;28592:21;;28737:113;28820:24;28838:5;28820:24;;28857:356;;28985:38;29017:5;28985:38;;;29035:88;29116:6;29111:3;29035:88;;;29028:95;;29128:52;29173:6;29168:3;29161:4;29154:5;29150:16;29128:52;;;29192:16;;;;;28965:248;-1:-1;;28965:248;29220:172;29326:60;29380:5;29326:60;;29562:142;29648:50;29692:5;29648:50;;29711:347;;29823:39;29856:5;29823:39;;;29874:71;29938:6;29933:3;29874:71;;;29867:78;;29950:52;29995:6;29990:3;29983:4;29976:5;29972:16;29950:52;;;30023:29;30045:6;30023:29;;;30014:39;;;;29803:255;-1:-1;;;29803:255;30066:372;;30226:67;30290:2;30285:3;30226:67;;;30326:34;30306:55;;-1:-1;;;30390:2;30381:12;;30374:27;30429:2;30420:12;;30212:226;-1:-1;;30212:226;30447:321;;30607:67;30671:2;30666:3;30607:67;;;-1:-1;;;30687:44;;30759:2;30750:12;;30593:175;-1:-1;;30593:175;30777:350;;30955:85;31037:2;31032:3;30955:85;;;-1:-1;;;31053:37;;31118:2;31109:12;;30941:186;-1:-1;;30941:186;31136:327;;31296:67;31360:2;31355:3;31296:67;;;31396:29;31376:50;;31454:2;31445:12;;31282:181;-1:-1;;31282:181;31472:341;;31650:84;31732:1;31727:3;31650:84;;;-1:-1;;;31747:30;;31805:1;31796:11;;31636:177;-1:-1;;31636:177;31822:371;;31982:67;32046:2;32041:3;31982:67;;;32082:34;32062:55;;-1:-1;;;32146:2;32137:12;;32130:26;32184:2;32175:12;;31968:225;-1:-1;;31968:225;32202:327;;32362:67;32426:2;32421:3;32362:67;;;32462:29;32442:50;;32520:2;32511:12;;32348:181;-1:-1;;32348:181;32538:352;;32716:85;32798:2;32793:3;32716:85;;;-1:-1;;;32814:39;;32881:2;32872:12;;32702:188;-1:-1;;32702:188;32899:325;;33059:67;33123:2;33118:3;33059:67;;;33159:27;33139:48;;33215:2;33206:12;;33045:179;-1:-1;;33045:179;33233:320;;33393:67;33457:2;33452:3;33393:67;;;-1:-1;;;33473:43;;33544:2;33535:12;;33379:174;-1:-1;;33379:174;33562:332;;33722:67;33786:2;33781:3;33722:67;;;33822:34;33802:55;;33885:2;33876:12;;33708:186;-1:-1;;33708:186;33903:323;;34063:67;34127:2;34122:3;34063:67;;;34163:25;34143:46;;34217:2;34208:12;;34049:177;-1:-1;;34049:177;34235:326;;34395:67;34459:2;34454:3;34395:67;;;34495:28;34475:49;;34552:2;34543:12;;34381:180;-1:-1;;34381:180;34570:326;;34730:67;34794:2;34789:3;34730:67;;;34830:28;34810:49;;34887:2;34878:12;;34716:180;-1:-1;;34716:180;34905:325;;35065:67;35129:2;35124:3;35065:67;;;35165:27;35145:48;;35221:2;35212:12;;35051:179;-1:-1;;35051:179;35239:341;;35417:84;35499:1;35494:3;35417:84;;;-1:-1;;;35514:30;;35572:1;35563:11;;35403:177;-1:-1;;35403:177;35589:316;;35749:67;35813:2;35808:3;35749:67;;;-1:-1;;;35829:39;;35896:2;35887:12;;35735:170;-1:-1;;35735:170;35914:324;;36074:67;36138:2;36133:3;36074:67;;;36174:26;36154:47;;36229:2;36220:12;;36060:178;-1:-1;;36060:178;36247:324;;36407:67;36471:2;36466:3;36407:67;;;36507:26;36487:47;;36562:2;36553:12;;36393:178;-1:-1;;36393:178;36580:327;;36740:67;36804:2;36799:3;36740:67;;;36840:29;36820:50;;36898:2;36889:12;;36726:181;-1:-1;;36726:181;36916:314;;37076:67;37140:2;37135:3;37076:67;;;-1:-1;;;37156:37;;37221:2;37212:12;;37062:168;-1:-1;;37062:168;37239:322;;37399:67;37463:2;37458:3;37399:67;;;-1:-1;;;37479:45;;37552:2;37543:12;;37385:176;-1:-1;;37385:176;37570:326;;37730:67;37794:2;37789:3;37730:67;;;37830:28;37810:49;;37887:2;37878:12;;37716:180;-1:-1;;37716:180;37905:343;;38083:84;38165:1;38160:3;38083:84;;;-1:-1;;;38180:32;;38240:1;38231:11;;38069:179;-1:-1;;38069:179;38257:328;;38417:67;38481:2;38476:3;38417:67;;;38517:30;38497:51;;38576:2;38567:12;;38403:182;-1:-1;;38403:182;38594:370;;38754:67;38818:2;38813:3;38754:67;;;38854:34;38834:55;;-1:-1;;;38918:2;38909:12;;38902:25;38955:2;38946:12;;38740:224;-1:-1;;38740:224;38973:346;;39151:85;39233:2;39228:3;39151:85;;;-1:-1;;;39249:33;;39310:2;39301:12;;39137:182;-1:-1;;39137:182;39328:346;;39506:85;39588:2;39583:3;39506:85;;;-1:-1;;;39604:33;;39665:2;39656:12;;39492:182;-1:-1;;39492:182;39683:326;;39843:67;39907:2;39902:3;39843:67;;;39943:28;39923:49;;40000:2;39991:12;;39829:180;-1:-1;;39829:180;40018:383;;40178:67;40242:2;40237:3;40178:67;;;40278:34;40258:55;;-1:-1;;;40342:2;40333:12;;40326:38;40392:2;40383:12;;40164:237;-1:-1;;40164:237;40410:370;;40570:67;40634:2;40629:3;40570:67;;;40670:34;40650:55;;-1:-1;;;40734:2;40725:12;;40718:25;40771:2;40762:12;;40556:224;-1:-1;;40556:224;40789:374;;40949:67;41013:2;41008:3;40949:67;;;41049:34;41029:55;;-1:-1;;;41113:2;41104:12;;41097:29;41154:2;41145:12;;40935:228;-1:-1;;40935:228;41172:373;;41332:67;41396:2;41391:3;41332:67;;;41432:34;41412:55;;-1:-1;;;41496:2;41487:12;;41480:28;41536:2;41527:12;;41318:227;-1:-1;;41318:227;41554:379;;41714:67;41778:2;41773:3;41714:67;;;41814:34;41794:55;;-1:-1;;;41878:2;41869:12;;41862:34;41924:2;41915:12;;41700:233;-1:-1;;41700:233;41942:327;;42102:67;42166:2;42161:3;42102:67;;;42202:29;42182:50;;42260:2;42251:12;;42088:181;-1:-1;;42088:181;42278:325;;42438:67;42502:2;42497:3;42438:67;;;42538:27;42518:48;;42594:2;42585:12;;42424:179;-1:-1;;42424:179;42612:343;;42790:84;42872:1;42867:3;42790:84;;;-1:-1;;;42887:32;;42947:1;42938:11;;42776:179;-1:-1;;42776:179;42964:331;;43124:67;43188:2;43183:3;43124:67;;;43224:33;43204:54;;43286:2;43277:12;;43110:185;-1:-1;;43110:185;43304:323;;43464:67;43528:2;43523:3;43464:67;;;43564:25;43544:46;;43618:2;43609:12;;43450:177;-1:-1;;43450:177;43636:331;;43796:67;43860:2;43855:3;43796:67;;;43896:33;43876:54;;43958:2;43949:12;;43782:185;-1:-1;;43782:185;43976:331;;44136:67;44200:2;44195:3;44136:67;;;44236:33;44216:54;;44298:2;44289:12;;44122:185;-1:-1;;44122:185;44380:1111;44569:23;;44503:4;44494:14;;;44598:63;44498:3;44569:23;44598:63;;;44523:144;44742:4;44735:5;44731:16;44725:23;44754:76;44824:4;44819:3;44815:14;44801:12;44754:76;;;44677:159;44925:4;44918:5;44914:16;44908:23;44937:57;44988:4;44983:3;44979:14;44965:12;44937:57;;;44846:154;45074:4;45067:5;45063:16;45057:23;45086:63;45143:4;45138:3;45134:14;45120:12;45086:63;;;45010:145;45233:4;45226:5;45222:16;45216:23;45245:63;45302:4;45297:3;45293:14;45279:12;45245:63;;;45165:149;45395:4;45388:5;45384:16;45378:23;45407:63;45464:4;45459:3;45455:14;45441:12;45407:63;;46921:97;46990:22;47006:5;46990:22;;47139:262;;47283:93;47372:3;47363:6;47283:93;;47408:372;;47607:148;47751:3;47607:148;;47787:372;;47986:148;48130:3;47986:148;;48166:372;;48365:148;48509:3;48365:148;;48545:372;;48744:148;48888:3;48744:148;;48924:372;;49123:148;49267:3;49123:148;;49303:372;;49502:148;49646:3;49502:148;;49682:372;;49881:148;50025:3;49881:148;;50061:372;;50260:148;50404:3;50260:148;;50440:213;50558:2;50543:18;;50572:71;50547:9;50616:6;50572:71;;50660:423;50828:2;50813:18;;50842:71;50817:9;50886:6;50842:71;;;50924:72;50992:2;50981:9;50977:18;50968:6;50924:72;;;51007:66;51069:2;51058:9;51054:18;51045:6;51007:66;;51090:435;51264:2;51249:18;;51278:71;51253:9;51322:6;51278:71;;;51360:72;51428:2;51417:9;51413:18;51404:6;51360:72;;;51443;51511:2;51500:9;51496:18;51487:6;51443:72;;51532:547;51734:3;51719:19;;51749:71;51723:9;51793:6;51749:71;;;51831:72;51899:2;51888:9;51884:18;51875:6;51831:72;;;51914;51982:2;51971:9;51967:18;51958:6;51914:72;;;51997;52065:2;52054:9;52050:18;52041:6;51997:72;;52086:647;52310:3;52295:19;;52325:71;52299:9;52369:6;52325:71;;;52407:72;52475:2;52464:9;52460:18;52451:6;52407:72;;;52490;52558:2;52547:9;52543:18;52534:6;52490:72;;;52573;52641:2;52630:9;52626:18;52617:6;52573:72;;;52656:67;52718:3;52707:9;52703:19;52694:6;52656:67;;52740:324;52886:2;52871:18;;52900:71;52875:9;52944:6;52900:71;;;52982:72;53050:2;53039:9;53035:18;53026:6;52982:72;;53071:547;53273:3;53258:19;;53288:71;53262:9;53332:6;53288:71;;;53370:72;53438:2;53427:9;53423:18;53414:6;53370:72;;;53453;53521:2;53510:9;53506:18;53497:6;53453:72;;;53536;53604:2;53593:9;53589:18;53580:6;53536:72;;53625:843;53927:3;53912:19;;53942:71;53916:9;53986:6;53942:71;;;54024:72;54092:2;54081:9;54077:18;54068:6;54024:72;;;54144:9;54138:4;54134:20;54129:2;54118:9;54114:18;54107:48;54169:108;54272:4;54263:6;54169:108;;;54161:116;;54325:9;54319:4;54315:20;54310:2;54299:9;54295:18;54288:48;54350:108;54453:4;54444:6;54350:108;;54475:827;54769:3;54754:19;;54784:71;54758:9;54828:6;54784:71;;;54866:72;54934:2;54923:9;54919:18;54910:6;54866:72;;;54986:9;54980:4;54976:20;54971:2;54960:9;54956:18;54949:48;55011:104;55110:4;55101:6;55011:104;;;55003:112;;55163:9;55157:4;55153:20;55148:2;55137:9;55133:18;55126:48;55188:104;55287:4;55278:6;55188:104;;55309:835;55607:3;55592:19;;55622:71;55596:9;55666:6;55622:71;;;55704:72;55772:2;55761:9;55757:18;55748:6;55704:72;;;55824:9;55818:4;55814:20;55809:2;55798:9;55794:18;55787:48;55849:104;55948:4;55939:6;55849:104;;56151:423;56319:2;56304:18;;56333:71;56308:9;56377:6;56333:71;;;56415:72;56483:2;56472:9;56468:18;56459:6;56415:72;;56581:361;56749:2;56763:47;;;56734:18;;56824:108;56734:18;56918:6;56824:108;;56949:719;57217:2;57231:47;;;57202:18;;57292:108;57202:18;57386:6;57292:108;;;57284:116;;57448:9;57442:4;57438:20;57433:2;57422:9;57418:18;57411:48;57473:108;57576:4;57567:6;57473:108;;;57465:116;;57592:66;57654:2;57643:9;57639:18;57630:6;57592:66;;57675:855;57987:2;58001:47;;;57972:18;;58062:100;57972:18;58148:6;58062:100;;;58054:108;;58210:9;58204:4;58200:20;58195:2;58184:9;58180:18;58173:48;58235:104;58334:4;58325:6;58235:104;;;58227:112;;58387:9;58381:4;58377:20;58372:2;58361:9;58357:18;58350:48;58412:108;58515:4;58506:6;58412:108;;58537:201;58649:2;58634:18;;58663:65;58638:9;58701:6;58663:65;;58745:511;58933:2;58918:18;;58947:65;58922:9;58985:6;58947:65;;;59060:9;59054:4;59050:20;59045:2;59034:9;59030:18;59023:48;59085:78;59158:4;59149:6;59085:78;;;59077:86;;59174:72;59242:2;59231:9;59227:18;59218:6;59174:72;;59263:1139;59661:3;59646:19;;59676:65;59650:9;59714:6;59676:65;;;59752:72;59820:2;59809:9;59805:18;59796:6;59752:72;;;59872:9;59866:4;59862:20;59857:2;59846:9;59842:18;59835:48;59897:140;60032:4;60023:6;59897:140;;;59889:148;;60085:9;60079:4;60075:20;60070:2;60059:9;60055:18;60048:48;60110:100;60205:4;60196:6;60110:100;;;60102:108;;60259:9;60253:4;60249:20;60243:3;60232:9;60228:19;60221:49;60284:108;60387:4;60378:6;60284:108;;;60276:116;59632:770;-1:-1;;;;;;;59632:770;60409:213;60527:2;60512:18;;60541:71;60516:9;60585:6;60541:71;;60629:259;60770:2;60755:18;;60784:94;60759:9;60851:6;60784:94;;61145:301;61283:2;61297:47;;;61268:18;;61358:78;61268:18;61422:6;61358:78;;61453:407;61644:2;61658:47;;;61629:18;;61719:131;61629:18;61719:131;;61867:407;62058:2;62072:47;;;62043:18;;62133:131;62043:18;62133:131;;62281:407;62472:2;62486:47;;;62457:18;;62547:131;62457:18;62547:131;;62695:407;62886:2;62900:47;;;62871:18;;62961:131;62871:18;62961:131;;63109:407;63300:2;63314:47;;;63285:18;;63375:131;63285:18;63375:131;;63523:407;63714:2;63728:47;;;63699:18;;63789:131;63699:18;63789:131;;63937:407;64128:2;64142:47;;;64113:18;;64203:131;64113:18;64203:131;;64351:407;64542:2;64556:47;;;64527:18;;64617:131;64527:18;64617:131;;64765:407;64956:2;64970:47;;;64941:18;;65031:131;64941:18;65031:131;;65179:407;65370:2;65384:47;;;65355:18;;65445:131;65355:18;65445:131;;65593:407;65784:2;65798:47;;;65769:18;;65859:131;65769:18;65859:131;;66007:407;66198:2;66212:47;;;66183:18;;66273:131;66183:18;66273:131;;66421:407;66612:2;66626:47;;;66597:18;;66687:131;66597:18;66687:131;;66835:407;67026:2;67040:47;;;67011:18;;67101:131;67011:18;67101:131;;67249:407;67440:2;67454:47;;;67425:18;;67515:131;67425:18;67515:131;;67663:407;67854:2;67868:47;;;67839:18;;67929:131;67839:18;67929:131;;68077:407;68268:2;68282:47;;;68253:18;;68343:131;68253:18;68343:131;;68491:407;68682:2;68696:47;;;68667:18;;68757:131;68667:18;68757:131;;68905:407;69096:2;69110:47;;;69081:18;;69171:131;69081:18;69171:131;;69319:407;69510:2;69524:47;;;69495:18;;69585:131;69495:18;69585:131;;69733:407;69924:2;69938:47;;;69909:18;;69999:131;69909:18;69999:131;;70147:407;70338:2;70352:47;;;70323:18;;70413:131;70323:18;70413:131;;70561:407;70752:2;70766:47;;;70737:18;;70827:131;70737:18;70827:131;;70975:407;71166:2;71180:47;;;71151:18;;71241:131;71151:18;71241:131;;71389:407;71580:2;71594:47;;;71565:18;;71655:131;71565:18;71655:131;;71803:407;71994:2;72008:47;;;71979:18;;72069:131;71979:18;72069:131;;72217:407;72408:2;72422:47;;;72393:18;;72483:131;72393:18;72483:131;;72631:407;72822:2;72836:47;;;72807:18;;72897:131;72807:18;72897:131;;73045:407;73236:2;73250:47;;;73221:18;;73311:131;73221:18;73311:131;;73459:407;73650:2;73664:47;;;73635:18;;73725:131;73635:18;73725:131;;73873:407;74064:2;74078:47;;;74049:18;;74139:131;74049:18;74139:131;;74287:407;74478:2;74492:47;;;74463:18;;74553:131;74463:18;74553:131;;74701:407;74892:2;74906:47;;;74877:18;;74967:131;74877:18;74967:131;;75335:536;75563:2;75548:18;;75577:71;75552:9;75621:6;75577:71;;;75696:9;75690:4;75686:20;75681:2;75670:9;75666:18;75659:48;75721:140;75856:4;75847:6;75721:140;;75878:795;76184:2;76169:18;;76198:71;76173:9;76242:6;76198:71;;;76317:9;76311:4;76307:20;76302:2;76291:9;76287:18;76280:48;76342:140;76477:4;76468:6;76342:140;;76680:709;76962:3;76947:19;;76977:71;76951:9;77021:6;76977:71;;;77059:112;77167:2;77156:9;77152:18;77143:6;77059:112;;;77182:113;77290:3;77279:9;77275:19;77266:6;77182:113;;;77306:73;77374:3;77363:9;77359:19;77350:6;77306:73;;77396:517;77610:3;77595:19;;77625:71;77599:9;77669:6;77625:71;;;77707:112;77815:2;77804:9;77800:18;77791:6;77707:112;;;77830:73;77898:3;77887:9;77883:19;77874:6;77830:73;;77920:324;78066:2;78051:18;;78080:71;78055:9;78124:6;78080:71;;78251:205;78365:2;78350:18;;78379:67;78354:9;78419:6;78379:67;;78463:427;78633:2;78618:18;;78647:67;78622:9;78687:6;78647:67;;78897:256;78959:2;78953:9;78985:17;;;-1:-1;;;;;79045:34;;79081:22;;;79042:62;79039:2;;;79117:1;79114;79107:12;79039:2;79133;79126:22;78937:216;;-1:-1;78937:216;79160:300;;-1:-1;;;;;79307:6;79304:30;79301:2;;;79347:1;79344;79337:12;79301:2;-1:-1;79382:4;79370:17;;;79435:15;;79238:222;80408:322;;-1:-1;;;;;80544:6;80541:30;80538:2;;;80584:1;80581;80574:12;80538:2;-1:-1;80715:4;80651;80628:17;;;;-1:-1;;80624:33;80705:15;;80475:255;80737:147;80857:4;80848:14;;80805:79;81685:133;81784:12;;81755:63;83497:178;83615:19;;;83664:4;83655:14;;83608:67;84739:91;;84801:24;84819:5;84801:24;;84837:85;84903:13;84896:21;;84879:43;85008:136;85085:5;85091:48;85085:5;85091:48;;85151:121;-1:-1;;;;;85213:54;;85196:76;85358:81;85429:4;85418:16;;85401:38;85446:167;;85548:60;85602:5;85548:60;;86046:136;;86138:39;86171:5;86138:39;;86190:268;86255:1;86262:101;86276:6;86273:1;86270:13;86262:101;;;86343:11;;;86337:18;86324:11;;;86317:39;86298:2;86291:10;86262:101;;;86378:6;86375:1;86372:13;86369:2;;;-1:-1;;86443:1;86425:16;;86418:27;86239:219;86466:97;86554:2;86534:14;-1:-1;;86530:28;;86514:49;86571:106;86655:1;86648:5;86645:12;86635:2;;86661:9;86684:117;86753:24;86771:5;86753:24;;;86746:5;86743:35;86733:2;;86792:1;86789;86782:12;86808:111;86874:21;86889:5;86874:21;;86926:109;87010:1;87003:5;87000:12;86990:2;;87026:1;87023;87016:12;87042:117;87111:24;87129:5;87111:24;;87166:113;87233:22;87249:5;87233:22;
Swarm Source
bzzr://f5ed41c5aeed2ab4675d2568bba346b7c92a0e8ad5807d86520159ec0cc290a7
Loading...
Loading
Loading...
Loading
OVERVIEW
Logic contract for mUSD proxyNet Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.