Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 12721108 | 1127 days ago | IN | 0 ETH | 0.10452448 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Controller
Compiler Version
v0.6.10+commit.00c0fcaf
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-06-28 */ /** * SPDX-License-Identifier: UNLICENSED */ pragma solidity =0.6.10; pragma experimental ABIEncoderV2; // File: contracts/packages/oz/upgradeability/Initializable.sol /** * @title Initializable * * @dev Helper contract to support initializer functions. To use it, replace * the constructor with a function that has the `initializer` modifier. * WARNING: Unlike constructors, initializer functions must be manually * invoked. This applies both to deploying an Initializable contract, as well * as extending an Initializable contract via inheritance. * WARNING: When used with inheritance, manual care must be taken to not invoke * a parent initializer twice, or ensure that all initializers are idempotent, * because this is not dealt with automatically as with constructors. */ 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; } // File: contracts/packages/oz/upgradeability/GSN/ContextUpgradeable.sol /* * @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. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer {} function _msgSender() internal virtual view returns (address payable) { return msg.sender; } function _msgData() internal virtual view returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } uint256[50] private __gap; } // File: contracts/packages/oz/upgradeability/OwnableUpgradeSafe.sol /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ contract OwnableUpgradeSafe is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init(address _sender) internal initializer { __Context_init_unchained(); __Ownable_init_unchained(_sender); } function __Ownable_init_unchained(address _sender) internal initializer { _owner = _sender; emit OwnershipTransferred(address(0), _sender); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(_owner == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } uint256[49] private __gap; } // File: contracts/packages/oz/upgradeability/ReentrancyGuardUpgradeSafe.sol /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ contract ReentrancyGuardUpgradeSafe is Initializable { bool private _notEntered; function __ReentrancyGuard_init() internal initializer { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal initializer { // 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; } uint256[49] private __gap; } // File: contracts/packages/oz/SafeMath.sol /** * @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. */ 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. */ 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. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File: contracts/libs/MarginVault.sol /** * MarginVault Error Codes * V1: invalid short otoken amount * V2: invalid short otoken index * V3: short otoken address mismatch * V4: invalid long otoken amount * V5: invalid long otoken index * V6: long otoken address mismatch * V7: invalid collateral amount * V8: invalid collateral token index * V9: collateral token address mismatch */ /** * @title MarginVault * @author Opyn Team * @notice A library that provides the Controller with a Vault struct and the functions that manipulate vaults. * Vaults describe discrete position combinations of long options, short options, and collateral assets that a user can have. */ library MarginVault { using SafeMath for uint256; // vault is a struct of 6 arrays that describe a position a user has, a user can have multiple vaults. struct Vault { // addresses of oTokens a user has shorted (i.e. written) against this vault address[] shortOtokens; // addresses of oTokens a user has bought and deposited in this vault // user can be long oTokens without opening a vault (e.g. by buying on a DEX) // generally, long oTokens will be 'deposited' in vaults to act as collateral in order to write oTokens against (i.e. in spreads) address[] longOtokens; // addresses of other ERC-20s a user has deposited as collateral in this vault address[] collateralAssets; // quantity of oTokens minted/written for each oToken address in shortOtokens uint256[] shortAmounts; // quantity of oTokens owned and held in the vault for each oToken address in longOtokens uint256[] longAmounts; // quantity of ERC-20 deposited as collateral in the vault for each ERC-20 address in collateralAssets uint256[] collateralAmounts; } /** * @dev increase the short oToken balance in a vault when a new oToken is minted * @param _vault vault to add or increase the short position in * @param _shortOtoken address of the _shortOtoken being minted from the user's vault * @param _amount number of _shortOtoken being minted from the user's vault * @param _index index of _shortOtoken in the user's vault.shortOtokens array */ function addShort( Vault storage _vault, address _shortOtoken, uint256 _amount, uint256 _index ) external { require(_amount > 0, "V1"); // valid indexes in any array are between 0 and array.length - 1. // if adding an amount to an preexisting short oToken, check that _index is in the range of 0->length-1 if ((_index == _vault.shortOtokens.length) && (_index == _vault.shortAmounts.length)) { _vault.shortOtokens.push(_shortOtoken); _vault.shortAmounts.push(_amount); } else { require((_index < _vault.shortOtokens.length) && (_index < _vault.shortAmounts.length), "V2"); address existingShort = _vault.shortOtokens[_index]; require((existingShort == _shortOtoken) || (existingShort == address(0)), "V3"); _vault.shortAmounts[_index] = _vault.shortAmounts[_index].add(_amount); _vault.shortOtokens[_index] = _shortOtoken; } } /** * @dev decrease the short oToken balance in a vault when an oToken is burned * @param _vault vault to decrease short position in * @param _shortOtoken address of the _shortOtoken being reduced in the user's vault * @param _amount number of _shortOtoken being reduced in the user's vault * @param _index index of _shortOtoken in the user's vault.shortOtokens array */ function removeShort( Vault storage _vault, address _shortOtoken, uint256 _amount, uint256 _index ) external { // check that the removed short oToken exists in the vault at the specified index require(_index < _vault.shortOtokens.length, "V2"); require(_vault.shortOtokens[_index] == _shortOtoken, "V3"); uint256 newShortAmount = _vault.shortAmounts[_index].sub(_amount); if (newShortAmount == 0) { delete _vault.shortOtokens[_index]; } _vault.shortAmounts[_index] = newShortAmount; } /** * @dev increase the long oToken balance in a vault when an oToken is deposited * @param _vault vault to add a long position to * @param _longOtoken address of the _longOtoken being added to the user's vault * @param _amount number of _longOtoken the protocol is adding to the user's vault * @param _index index of _longOtoken in the user's vault.longOtokens array */ function addLong( Vault storage _vault, address _longOtoken, uint256 _amount, uint256 _index ) external { require(_amount > 0, "V4"); // valid indexes in any array are between 0 and array.length - 1. // if adding an amount to an preexisting short oToken, check that _index is in the range of 0->length-1 if ((_index == _vault.longOtokens.length) && (_index == _vault.longAmounts.length)) { _vault.longOtokens.push(_longOtoken); _vault.longAmounts.push(_amount); } else { require((_index < _vault.longOtokens.length) && (_index < _vault.longAmounts.length), "V5"); address existingLong = _vault.longOtokens[_index]; require((existingLong == _longOtoken) || (existingLong == address(0)), "V6"); _vault.longAmounts[_index] = _vault.longAmounts[_index].add(_amount); _vault.longOtokens[_index] = _longOtoken; } } /** * @dev decrease the long oToken balance in a vault when an oToken is withdrawn * @param _vault vault to remove a long position from * @param _longOtoken address of the _longOtoken being removed from the user's vault * @param _amount number of _longOtoken the protocol is removing from the user's vault * @param _index index of _longOtoken in the user's vault.longOtokens array */ function removeLong( Vault storage _vault, address _longOtoken, uint256 _amount, uint256 _index ) external { // check that the removed long oToken exists in the vault at the specified index require(_index < _vault.longOtokens.length, "V5"); require(_vault.longOtokens[_index] == _longOtoken, "V6"); uint256 newLongAmount = _vault.longAmounts[_index].sub(_amount); if (newLongAmount == 0) { delete _vault.longOtokens[_index]; } _vault.longAmounts[_index] = newLongAmount; } /** * @dev increase the collateral balance in a vault * @param _vault vault to add collateral to * @param _collateralAsset address of the _collateralAsset being added to the user's vault * @param _amount number of _collateralAsset being added to the user's vault * @param _index index of _collateralAsset in the user's vault.collateralAssets array */ function addCollateral( Vault storage _vault, address _collateralAsset, uint256 _amount, uint256 _index ) external { require(_amount > 0, "V7"); // valid indexes in any array are between 0 and array.length - 1. // if adding an amount to an preexisting short oToken, check that _index is in the range of 0->length-1 if ((_index == _vault.collateralAssets.length) && (_index == _vault.collateralAmounts.length)) { _vault.collateralAssets.push(_collateralAsset); _vault.collateralAmounts.push(_amount); } else { require((_index < _vault.collateralAssets.length) && (_index < _vault.collateralAmounts.length), "V8"); address existingCollateral = _vault.collateralAssets[_index]; require((existingCollateral == _collateralAsset) || (existingCollateral == address(0)), "V9"); _vault.collateralAmounts[_index] = _vault.collateralAmounts[_index].add(_amount); _vault.collateralAssets[_index] = _collateralAsset; } } /** * @dev decrease the collateral balance in a vault * @param _vault vault to remove collateral from * @param _collateralAsset address of the _collateralAsset being removed from the user's vault * @param _amount number of _collateralAsset being removed from the user's vault * @param _index index of _collateralAsset in the user's vault.collateralAssets array */ function removeCollateral( Vault storage _vault, address _collateralAsset, uint256 _amount, uint256 _index ) external { // check that the removed collateral exists in the vault at the specified index require(_index < _vault.collateralAssets.length, "V8"); require(_vault.collateralAssets[_index] == _collateralAsset, "V9"); uint256 newCollateralAmount = _vault.collateralAmounts[_index].sub(_amount); if (newCollateralAmount == 0) { delete _vault.collateralAssets[_index]; } _vault.collateralAmounts[_index] = newCollateralAmount; } } // File: contracts/libs/Actions.sol /** * @title Actions * @author Opyn Team * @notice A library that provides a ActionArgs struct, sub types of Action structs, and functions to parse ActionArgs into specific Actions. * errorCode * A1 can only parse arguments for open vault actions * A2 cannot open vault for an invalid account * A3 cannot open vault with an invalid type * A4 can only parse arguments for mint actions * A5 cannot mint from an invalid account * A6 can only parse arguments for burn actions * A7 cannot burn from an invalid account * A8 can only parse arguments for deposit actions * A9 cannot deposit to an invalid account * A10 can only parse arguments for withdraw actions * A11 cannot withdraw from an invalid account * A12 cannot withdraw to an invalid account * A13 can only parse arguments for redeem actions * A14 cannot redeem to an invalid account * A15 can only parse arguments for settle vault actions * A16 cannot settle vault for an invalid account * A17 cannot withdraw payout to an invalid account * A18 can only parse arguments for liquidate action * A19 cannot liquidate vault for an invalid account owner * A20 cannot send collateral to an invalid account * A21 cannot parse liquidate action with no round id * A22 can only parse arguments for call actions * A23 target address cannot be address(0) */ library Actions { // possible actions that can be performed enum ActionType { OpenVault, MintShortOption, BurnShortOption, DepositLongOption, WithdrawLongOption, DepositCollateral, WithdrawCollateral, SettleVault, Redeem, Call, Liquidate } struct ActionArgs { // type of action that is being performed on the system ActionType actionType; // address of the account owner address owner; // address which we move assets from or to (depending on the action type) address secondAddress; // asset that is to be transfered address asset; // index of the vault that is to be modified (if any) uint256 vaultId; // amount of asset that is to be transfered uint256 amount; // each vault can hold multiple short / long / collateral assets but we are restricting the scope to only 1 of each in this version // in future versions this would be the index of the short / long / collateral asset that needs to be modified uint256 index; // any other data that needs to be passed in for arbitrary function calls bytes data; } struct MintArgs { // address of the account owner address owner; // index of the vault from which the asset will be minted uint256 vaultId; // address to which we transfer the minted oTokens address to; // oToken that is to be minted address otoken; // each vault can hold multiple short / long / collateral assets but we are restricting the scope to only 1 of each in this version // in future versions this would be the index of the short / long / collateral asset that needs to be modified uint256 index; // amount of oTokens that is to be minted uint256 amount; } struct BurnArgs { // address of the account owner address owner; // index of the vault from which the oToken will be burned uint256 vaultId; // address from which we transfer the oTokens address from; // oToken that is to be burned address otoken; // each vault can hold multiple short / long / collateral assets but we are restricting the scope to only 1 of each in this version // in future versions this would be the index of the short / long / collateral asset that needs to be modified uint256 index; // amount of oTokens that is to be burned uint256 amount; } struct OpenVaultArgs { // address of the account owner address owner; // vault id to create uint256 vaultId; // vault type, 0 for spread/max loss and 1 for naked margin vault uint256 vaultType; } struct DepositArgs { // address of the account owner address owner; // index of the vault to which the asset will be added uint256 vaultId; // address from which we transfer the asset address from; // asset that is to be deposited address asset; // each vault can hold multiple short / long / collateral assets but we are restricting the scope to only 1 of each in this version // in future versions this would be the index of the short / long / collateral asset that needs to be modified uint256 index; // amount of asset that is to be deposited uint256 amount; } struct RedeemArgs { // address to which we pay out the oToken proceeds address receiver; // oToken that is to be redeemed address otoken; // amount of oTokens that is to be redeemed uint256 amount; } struct WithdrawArgs { // address of the account owner address owner; // index of the vault from which the asset will be withdrawn uint256 vaultId; // address to which we transfer the asset address to; // asset that is to be withdrawn address asset; // each vault can hold multiple short / long / collateral assets but we are restricting the scope to only 1 of each in this version // in future versions this would be the index of the short / long / collateral asset that needs to be modified uint256 index; // amount of asset that is to be withdrawn uint256 amount; } struct SettleVaultArgs { // address of the account owner address owner; // index of the vault to which is to be settled uint256 vaultId; // address to which we transfer the remaining collateral address to; } struct LiquidateArgs { // address of the vault owner to liquidate address owner; // address of the liquidated collateral receiver address receiver; // vault id to liquidate uint256 vaultId; // amount of debt(otoken) to repay uint256 amount; // chainlink round id uint256 roundId; } struct CallArgs { // address of the callee contract address callee; // data field for external calls bytes data; } /** * @notice parses the passed in action arguments to get the arguments for an open vault action * @param _args general action arguments structure * @return arguments for a open vault action */ function _parseOpenVaultArgs(ActionArgs memory _args) internal pure returns (OpenVaultArgs memory) { require(_args.actionType == ActionType.OpenVault, "A1"); require(_args.owner != address(0), "A2"); // if not _args.data included, vault type will be 0 by default uint256 vaultType; if (_args.data.length == 32) { // decode vault type from _args.data vaultType = abi.decode(_args.data, (uint256)); } // for now we only have 2 vault types require(vaultType < 2, "A3"); return OpenVaultArgs({owner: _args.owner, vaultId: _args.vaultId, vaultType: vaultType}); } /** * @notice parses the passed in action arguments to get the arguments for a mint action * @param _args general action arguments structure * @return arguments for a mint action */ function _parseMintArgs(ActionArgs memory _args) internal pure returns (MintArgs memory) { require(_args.actionType == ActionType.MintShortOption, "A4"); require(_args.owner != address(0), "A5"); return MintArgs({ owner: _args.owner, vaultId: _args.vaultId, to: _args.secondAddress, otoken: _args.asset, index: _args.index, amount: _args.amount }); } /** * @notice parses the passed in action arguments to get the arguments for a burn action * @param _args general action arguments structure * @return arguments for a burn action */ function _parseBurnArgs(ActionArgs memory _args) internal pure returns (BurnArgs memory) { require(_args.actionType == ActionType.BurnShortOption, "A6"); require(_args.owner != address(0), "A7"); return BurnArgs({ owner: _args.owner, vaultId: _args.vaultId, from: _args.secondAddress, otoken: _args.asset, index: _args.index, amount: _args.amount }); } /** * @notice parses the passed in action arguments to get the arguments for a deposit action * @param _args general action arguments structure * @return arguments for a deposit action */ function _parseDepositArgs(ActionArgs memory _args) internal pure returns (DepositArgs memory) { require( (_args.actionType == ActionType.DepositLongOption) || (_args.actionType == ActionType.DepositCollateral), "A8" ); require(_args.owner != address(0), "A9"); return DepositArgs({ owner: _args.owner, vaultId: _args.vaultId, from: _args.secondAddress, asset: _args.asset, index: _args.index, amount: _args.amount }); } /** * @notice parses the passed in action arguments to get the arguments for a withdraw action * @param _args general action arguments structure * @return arguments for a withdraw action */ function _parseWithdrawArgs(ActionArgs memory _args) internal pure returns (WithdrawArgs memory) { require( (_args.actionType == ActionType.WithdrawLongOption) || (_args.actionType == ActionType.WithdrawCollateral), "A10" ); require(_args.owner != address(0), "A11"); require(_args.secondAddress != address(0), "A12"); return WithdrawArgs({ owner: _args.owner, vaultId: _args.vaultId, to: _args.secondAddress, asset: _args.asset, index: _args.index, amount: _args.amount }); } /** * @notice parses the passed in action arguments to get the arguments for an redeem action * @param _args general action arguments structure * @return arguments for a redeem action */ function _parseRedeemArgs(ActionArgs memory _args) internal pure returns (RedeemArgs memory) { require(_args.actionType == ActionType.Redeem, "A13"); require(_args.secondAddress != address(0), "A14"); return RedeemArgs({receiver: _args.secondAddress, otoken: _args.asset, amount: _args.amount}); } /** * @notice parses the passed in action arguments to get the arguments for a settle vault action * @param _args general action arguments structure * @return arguments for a settle vault action */ function _parseSettleVaultArgs(ActionArgs memory _args) internal pure returns (SettleVaultArgs memory) { require(_args.actionType == ActionType.SettleVault, "A15"); require(_args.owner != address(0), "A16"); require(_args.secondAddress != address(0), "A17"); return SettleVaultArgs({owner: _args.owner, vaultId: _args.vaultId, to: _args.secondAddress}); } function _parseLiquidateArgs(ActionArgs memory _args) internal pure returns (LiquidateArgs memory) { require(_args.actionType == ActionType.Liquidate, "A18"); require(_args.owner != address(0), "A19"); require(_args.secondAddress != address(0), "A20"); require(_args.data.length == 32, "A21"); // decode chainlink round id from _args.data uint256 roundId = abi.decode(_args.data, (uint256)); return LiquidateArgs({ owner: _args.owner, receiver: _args.secondAddress, vaultId: _args.vaultId, amount: _args.amount, roundId: roundId }); } /** * @notice parses the passed in action arguments to get the arguments for a call action * @param _args general action arguments structure * @return arguments for a call action */ function _parseCallArgs(ActionArgs memory _args) internal pure returns (CallArgs memory) { require(_args.actionType == ActionType.Call, "A22"); require(_args.secondAddress != address(0), "A23"); return CallArgs({callee: _args.secondAddress, data: _args.data}); } } // File: contracts/interfaces/AddressBookInterface.sol interface AddressBookInterface { /* Getters */ function getOtokenImpl() external view returns (address); function getOtokenFactory() external view returns (address); function getWhitelist() external view returns (address); function getController() external view returns (address); function getOracle() external view returns (address); function getMarginPool() external view returns (address); function getMarginCalculator() external view returns (address); function getLiquidationManager() external view returns (address); function getAddress(bytes32 _id) external view returns (address); /* Setters */ function setOtokenImpl(address _otokenImpl) external; function setOtokenFactory(address _factory) external; function setOracleImpl(address _otokenImpl) external; function setWhitelist(address _whitelist) external; function setController(address _controller) external; function setMarginPool(address _marginPool) external; function setMarginCalculator(address _calculator) external; function setLiquidationManager(address _liquidationManager) external; function setAddress(bytes32 _id, address _newImpl) external; } // File: contracts/interfaces/OtokenInterface.sol interface OtokenInterface { function addressBook() external view returns (address); function underlyingAsset() external view returns (address); function strikeAsset() external view returns (address); function collateralAsset() external view returns (address); function strikePrice() external view returns (uint256); function expiryTimestamp() external view returns (uint256); function isPut() external view returns (bool); function init( address _addressBook, address _underlyingAsset, address _strikeAsset, address _collateralAsset, uint256 _strikePrice, uint256 _expiry, bool _isPut ) external; function getOtokenDetails() external view returns ( address, address, address, uint256, uint256, bool ); function mintOtoken(address account, uint256 amount) external; function burnOtoken(address account, uint256 amount) external; } // File: contracts/interfaces/MarginCalculatorInterface.sol interface MarginCalculatorInterface { function addressBook() external view returns (address); function getExpiredPayoutRate(address _otoken) external view returns (uint256); function getExcessCollateral(MarginVault.Vault calldata _vault, uint256 _vaultType) external view returns (uint256 netValue, bool isExcess); function isLiquidatable( MarginVault.Vault memory _vault, uint256 _vaultType, uint256 _vaultLatestUpdate, uint256 _roundId ) external view returns ( bool, uint256, uint256 ); } // File: contracts/interfaces/OracleInterface.sol interface OracleInterface { function isLockingPeriodOver(address _asset, uint256 _expiryTimestamp) external view returns (bool); function isDisputePeriodOver(address _asset, uint256 _expiryTimestamp) external view returns (bool); function getExpiryPrice(address _asset, uint256 _expiryTimestamp) external view returns (uint256, bool); function getDisputer() external view returns (address); function getPricer(address _asset) external view returns (address); function getPrice(address _asset) external view returns (uint256); function getPricerLockingPeriod(address _pricer) external view returns (uint256); function getPricerDisputePeriod(address _pricer) external view returns (uint256); function getChainlinkRoundData(address _asset, uint80 _roundId) external view returns (uint256, uint256); // Non-view function function setAssetPricer(address _asset, address _pricer) external; function setLockingPeriod(address _pricer, uint256 _lockingPeriod) external; function setDisputePeriod(address _pricer, uint256 _disputePeriod) external; function setExpiryPrice( address _asset, uint256 _expiryTimestamp, uint256 _price ) external; function disputeExpiryPrice( address _asset, uint256 _expiryTimestamp, uint256 _price ) external; function setDisputer(address _disputer) external; } // File: contracts/interfaces/WhitelistInterface.sol interface WhitelistInterface { /* View functions */ function addressBook() external view returns (address); function isWhitelistedProduct( address _underlying, address _strike, address _collateral, bool _isPut ) external view returns (bool); function isWhitelistedCollateral(address _collateral) external view returns (bool); function isWhitelistedOtoken(address _otoken) external view returns (bool); function isWhitelistedCallee(address _callee) external view returns (bool); /* Admin / factory only functions */ function whitelistProduct( address _underlying, address _strike, address _collateral, bool _isPut ) external; function blacklistProduct( address _underlying, address _strike, address _collateral, bool _isPut ) external; function whitelistCollateral(address _collateral) external; function blacklistCollateral(address _collateral) external; function whitelistOtoken(address _otoken) external; function blacklistOtoken(address _otoken) external; function whitelistCallee(address _callee) external; function blacklistCallee(address _callee) external; } // File: contracts/interfaces/MarginPoolInterface.sol interface MarginPoolInterface { /* Getters */ function addressBook() external view returns (address); function farmer() external view returns (address); function getStoredBalance(address _asset) external view returns (uint256); /* Admin-only functions */ function setFarmer(address _farmer) external; function farm( address _asset, address _receiver, uint256 _amount ) external; /* Controller-only functions */ function transferToPool( address _asset, address _user, uint256 _amount ) external; function transferToUser( address _asset, address _user, uint256 _amount ) external; function batchTransferToPool( address[] calldata _asset, address[] calldata _user, uint256[] calldata _amount ) external; function batchTransferToUser( address[] calldata _asset, address[] calldata _user, uint256[] calldata _amount ) external; } // File: contracts/interfaces/CalleeInterface.sol /** * @dev Contract interface that can be called from Controller as a call action. */ interface CalleeInterface { /** * Allows users to send this contract arbitrary data. * @param _sender The msg.sender to Controller * @param _data Arbitrary data given by the sender */ function callFunction(address payable _sender, bytes memory _data) external; } // File: contracts/core/Controller.sol /** * Controller Error Codes * C1: sender is not full pauser * C2: sender is not partial pauser * C3: callee is not a whitelisted address * C4: system is partially paused * C5: system is fully paused * C6: msg.sender is not authorized to run action * C7: invalid addressbook address * C8: invalid owner address * C9: invalid input * C10: fullPauser cannot be set to address zero * C11: partialPauser cannot be set to address zero * C12: can not run actions for different owners * C13: can not run actions on different vaults * C14: invalid final vault state * C15: can not run actions on inexistent vault * C16: cannot deposit long otoken from this address * C17: otoken is not whitelisted to be used as collateral * C18: otoken used as collateral is already expired * C19: can not withdraw an expired otoken * C20: cannot deposit collateral from this address * C21: asset is not whitelisted to be used as collateral * C22: can not withdraw collateral from a vault with an expired short otoken * C23: otoken is not whitelisted to be minted * C24: can not mint expired otoken * C25: cannot burn from this address * C26: can not burn expired otoken * C27: otoken is not whitelisted to be redeemed * C28: can not redeem un-expired otoken * C29: asset prices not finalized yet * C30: can't settle vault with no otoken * C31: can not settle vault with un-expired otoken * C32: can not settle undercollateralized vault * C33: can not liquidate vault * C34: can not leave less than collateral dust * C35: invalid vault id * C36: cap amount should be greater than zero * C37: collateral exceed naked margin cap */ /** * @title Controller * @author Opyn Team * @notice Contract that controls the Gamma Protocol and the interaction of all sub contracts */ contract Controller is Initializable, OwnableUpgradeSafe, ReentrancyGuardUpgradeSafe { using MarginVault for MarginVault.Vault; using SafeMath for uint256; AddressBookInterface public addressbook; WhitelistInterface public whitelist; OracleInterface public oracle; MarginCalculatorInterface public calculator; MarginPoolInterface public pool; ///@dev scale used in MarginCalculator uint256 internal constant BASE = 8; /// @notice address that has permission to partially pause the system, where system functionality is paused /// except redeem and settleVault address public partialPauser; /// @notice address that has permission to fully pause the system, where all system functionality is paused address public fullPauser; /// @notice True if all system functionality is paused other than redeem and settle vault bool public systemPartiallyPaused; /// @notice True if all system functionality is paused bool public systemFullyPaused; /// @notice True if a call action can only be executed to a whitelisted callee bool public callRestricted; /// @dev mapping between an owner address and the number of owner address vaults mapping(address => uint256) internal accountVaultCounter; /// @dev mapping between an owner address and a specific vault using a vault id mapping(address => mapping(uint256 => MarginVault.Vault)) internal vaults; /// @dev mapping between an account owner and their approved or unapproved account operators mapping(address => mapping(address => bool)) internal operators; /******************************************************************** V2.0.0 storage upgrade ******************************************************/ /// @dev mapping to map vault by each vault type, naked margin vault should be set to 1, spread/max loss vault should be set to 0 mapping(address => mapping(uint256 => uint256)) internal vaultType; /// @dev mapping to store the timestamp at which the vault was last updated, will be updated in every action that changes the vault state or when calling sync() mapping(address => mapping(uint256 => uint256)) internal vaultLatestUpdate; /// @dev mapping to store cap amount for naked margin vault per options collateral asset (scaled by collateral asset decimals) mapping(address => uint256) internal nakedCap; /// @dev mapping to store amount of naked margin vaults in pool mapping(address => uint256) internal nakedPoolBalance; /// @notice emits an event when an account operator is updated for a specific account owner event AccountOperatorUpdated(address indexed accountOwner, address indexed operator, bool isSet); /// @notice emits an event when a new vault is opened event VaultOpened(address indexed accountOwner, uint256 vaultId, uint256 indexed vaultType); /// @notice emits an event when a long oToken is deposited into a vault event LongOtokenDeposited( address indexed otoken, address indexed accountOwner, address indexed from, uint256 vaultId, uint256 amount ); /// @notice emits an event when a long oToken is withdrawn from a vault event LongOtokenWithdrawed( address indexed otoken, address indexed AccountOwner, address indexed to, uint256 vaultId, uint256 amount ); /// @notice emits an event when a collateral asset is deposited into a vault event CollateralAssetDeposited( address indexed asset, address indexed accountOwner, address indexed from, uint256 vaultId, uint256 amount ); /// @notice emits an event when a collateral asset is withdrawn from a vault event CollateralAssetWithdrawed( address indexed asset, address indexed AccountOwner, address indexed to, uint256 vaultId, uint256 amount ); /// @notice emits an event when a short oToken is minted from a vault event ShortOtokenMinted( address indexed otoken, address indexed AccountOwner, address indexed to, uint256 vaultId, uint256 amount ); /// @notice emits an event when a short oToken is burned event ShortOtokenBurned( address indexed otoken, address indexed AccountOwner, address indexed from, uint256 vaultId, uint256 amount ); /// @notice emits an event when an oToken is redeemed event Redeem( address indexed otoken, address indexed redeemer, address indexed receiver, address collateralAsset, uint256 otokenBurned, uint256 payout ); /// @notice emits an event when a vault is settled event VaultSettled( address indexed accountOwner, address indexed oTokenAddress, address to, uint256 payout, uint256 vaultId, uint256 indexed vaultType ); /// @notice emits an event when a vault is liquidated event VaultLiquidated( address indexed liquidator, address indexed receiver, address indexed vaultOwner, uint256 auctionPrice, uint256 auctionStartingRound, uint256 collateralPayout, uint256 debtAmount, uint256 vaultId ); /// @notice emits an event when a call action is executed event CallExecuted(address indexed from, address indexed to, bytes data); /// @notice emits an event when the fullPauser address changes event FullPauserUpdated(address indexed oldFullPauser, address indexed newFullPauser); /// @notice emits an event when the partialPauser address changes event PartialPauserUpdated(address indexed oldPartialPauser, address indexed newPartialPauser); /// @notice emits an event when the system partial paused status changes event SystemPartiallyPaused(bool isPaused); /// @notice emits an event when the system fully paused status changes event SystemFullyPaused(bool isPaused); /// @notice emits an event when the call action restriction changes event CallRestricted(bool isRestricted); /// @notice emits an event when a donation transfer executed event Donated(address indexed donator, address indexed asset, uint256 amount); /// @notice emits an event when naked cap is updated event NakedCapUpdated(address indexed collateral, uint256 cap); /** * @notice modifier to check if the system is not partially paused, where only redeem and settleVault is allowed */ modifier notPartiallyPaused { _isNotPartiallyPaused(); _; } /** * @notice modifier to check if the system is not fully paused, where no functionality is allowed */ modifier notFullyPaused { _isNotFullyPaused(); _; } /** * @notice modifier to check if sender is the fullPauser address */ modifier onlyFullPauser { require(msg.sender == fullPauser, "C1"); _; } /** * @notice modifier to check if the sender is the partialPauser address */ modifier onlyPartialPauser { require(msg.sender == partialPauser, "C2"); _; } /** * @notice modifier to check if the sender is the account owner or an approved account operator * @param _sender sender address * @param _accountOwner account owner address */ modifier onlyAuthorized(address _sender, address _accountOwner) { _isAuthorized(_sender, _accountOwner); _; } /** * @notice modifier to check if the called address is a whitelisted callee address * @param _callee called address */ modifier onlyWhitelistedCallee(address _callee) { if (callRestricted) { require(_isCalleeWhitelisted(_callee), "C3"); } _; } /** * @dev check if the system is not in a partiallyPaused state */ function _isNotPartiallyPaused() internal view { require(!systemPartiallyPaused, "C4"); } /** * @dev check if the system is not in an fullyPaused state */ function _isNotFullyPaused() internal view { require(!systemFullyPaused, "C5"); } /** * @dev check if the sender is an authorized operator * @param _sender msg.sender * @param _accountOwner owner of a vault */ function _isAuthorized(address _sender, address _accountOwner) internal view { require((_sender == _accountOwner) || (operators[_accountOwner][_sender]), "C6"); } /** * @notice initalize the deployed contract * @param _addressBook addressbook module * @param _owner account owner address */ function initialize(address _addressBook, address _owner) external initializer { require(_addressBook != address(0), "C7"); require(_owner != address(0), "C8"); __Ownable_init(_owner); __ReentrancyGuard_init_unchained(); addressbook = AddressBookInterface(_addressBook); _refreshConfigInternal(); callRestricted = true; } /** * @notice send asset amount to margin pool * @dev use donate() instead of direct transfer() to store the balance in assetBalance * @param _asset asset address * @param _amount amount to donate to pool */ function donate(address _asset, uint256 _amount) external { pool.transferToPool(_asset, msg.sender, _amount); emit Donated(msg.sender, _asset, _amount); } /** * @notice allows the partialPauser to toggle the systemPartiallyPaused variable and partially pause or partially unpause the system * @dev can only be called by the partialPauser * @param _partiallyPaused new boolean value to set systemPartiallyPaused to */ function setSystemPartiallyPaused(bool _partiallyPaused) external onlyPartialPauser { require(systemPartiallyPaused != _partiallyPaused, "C9"); systemPartiallyPaused = _partiallyPaused; emit SystemPartiallyPaused(systemPartiallyPaused); } /** * @notice allows the fullPauser to toggle the systemFullyPaused variable and fully pause or fully unpause the system * @dev can only be called by the fullyPauser * @param _fullyPaused new boolean value to set systemFullyPaused to */ function setSystemFullyPaused(bool _fullyPaused) external onlyFullPauser { require(systemFullyPaused != _fullyPaused, "C9"); systemFullyPaused = _fullyPaused; emit SystemFullyPaused(systemFullyPaused); } /** * @notice allows the owner to set the fullPauser address * @dev can only be called by the owner * @param _fullPauser new fullPauser address */ function setFullPauser(address _fullPauser) external onlyOwner { require(_fullPauser != address(0), "C10"); require(fullPauser != _fullPauser, "C9"); emit FullPauserUpdated(fullPauser, _fullPauser); fullPauser = _fullPauser; } /** * @notice allows the owner to set the partialPauser address * @dev can only be called by the owner * @param _partialPauser new partialPauser address */ function setPartialPauser(address _partialPauser) external onlyOwner { require(_partialPauser != address(0), "C11"); require(partialPauser != _partialPauser, "C9"); emit PartialPauserUpdated(partialPauser, _partialPauser); partialPauser = _partialPauser; } /** * @notice allows the owner to toggle the restriction on whitelisted call actions and only allow whitelisted * call addresses or allow any arbitrary call addresses * @dev can only be called by the owner * @param _isRestricted new call restriction state */ function setCallRestriction(bool _isRestricted) external onlyOwner { require(callRestricted != _isRestricted, "C9"); callRestricted = _isRestricted; emit CallRestricted(callRestricted); } /** * @notice allows a user to give or revoke privileges to an operator which can act on their behalf on their vaults * @dev can only be updated by the vault owner * @param _operator operator that the sender wants to give privileges to or revoke them from * @param _isOperator new boolean value that expresses if the sender is giving or revoking privileges for _operator */ function setOperator(address _operator, bool _isOperator) external { require(operators[msg.sender][_operator] != _isOperator, "C9"); operators[msg.sender][_operator] = _isOperator; emit AccountOperatorUpdated(msg.sender, _operator, _isOperator); } /** * @dev updates the configuration of the controller. can only be called by the owner */ function refreshConfiguration() external onlyOwner { _refreshConfigInternal(); } /** * @notice set cap amount for collateral asset used in naked margin * @dev can only be called by owner * @param _collateral collateral asset address * @param _cap cap amount, should be scaled by collateral asset decimals */ function setNakedCap(address _collateral, uint256 _cap) external onlyOwner { require(_cap > 0, "C36"); nakedCap[_collateral] = _cap; emit NakedCapUpdated(_collateral, _cap); } /** * @notice execute a number of actions on specific vaults * @dev can only be called when the system is not fully paused * @param _actions array of actions arguments */ function operate(Actions.ActionArgs[] memory _actions) external nonReentrant notFullyPaused { (bool vaultUpdated, address vaultOwner, uint256 vaultId) = _runActions(_actions); if (vaultUpdated) { _verifyFinalState(vaultOwner, vaultId); vaultLatestUpdate[vaultOwner][vaultId] = now; } } /** * @notice sync vault latest update timestamp * @dev anyone can update the latest time the vault was touched by calling this function * vaultLatestUpdate will sync if the vault is well collateralized * @param _owner vault owner address * @param _vaultId vault id */ function sync(address _owner, uint256 _vaultId) external nonReentrant notFullyPaused { _verifyFinalState(_owner, _vaultId); vaultLatestUpdate[_owner][_vaultId] = now; } /** * @notice check if a specific address is an operator for an owner account * @param _owner account owner address * @param _operator account operator address * @return True if the _operator is an approved operator for the _owner account */ function isOperator(address _owner, address _operator) external view returns (bool) { return operators[_owner][_operator]; } /** * @notice returns the current controller configuration * @return whitelist, the address of the whitelist module * @return oracle, the address of the oracle module * @return calculator, the address of the calculator module * @return pool, the address of the pool module */ function getConfiguration() external view returns ( address, address, address, address ) { return (address(whitelist), address(oracle), address(calculator), address(pool)); } /** * @notice return a vault's proceeds pre or post expiry, the amount of collateral that can be removed from a vault * @param _owner account owner of the vault * @param _vaultId vaultId to return balances for * @return amount of collateral that can be taken out */ function getProceed(address _owner, uint256 _vaultId) external view returns (uint256) { (MarginVault.Vault memory vault, uint256 typeVault, ) = getVaultWithDetails(_owner, _vaultId); (uint256 netValue, bool isExcess) = calculator.getExcessCollateral(vault, typeVault); if (!isExcess) return 0; return netValue; } /** * @notice check if a vault is liquidatable in a specific round id * @param _owner vault owner address * @param _vaultId vault id to check * @param _roundId chainlink round id to check vault status at * @return isUnderCollat, true if vault is undercollateralized, the price of 1 repaid otoken and the otoken collateral dust amount */ function isLiquidatable( address _owner, uint256 _vaultId, uint256 _roundId ) external view returns ( bool, uint256, uint256 ) { (, bool isUnderCollat, uint256 price, uint256 dust) = _isLiquidatable(_owner, _vaultId, _roundId); return (isUnderCollat, price, dust); } /** * @notice get an oToken's payout/cash value after expiry, in the collateral asset * @param _otoken oToken address * @param _amount amount of the oToken to calculate the payout for, always represented in 1e8 * @return amount of collateral to pay out */ function getPayout(address _otoken, uint256 _amount) public view returns (uint256) { return calculator.getExpiredPayoutRate(_otoken).mul(_amount).div(10**BASE); } /** * @dev return if an expired oToken is ready to be settled, only true when price for underlying, * strike and collateral assets at this specific expiry is available in our Oracle module * @param _otoken oToken */ function isSettlementAllowed(address _otoken) external view returns (bool) { (address underlying, address strike, address collateral, uint256 expiry) = _getOtokenDetails(_otoken); return _canSettleAssets(underlying, strike, collateral, expiry); } /** * @dev return if underlying, strike, collateral are all allowed to be settled * @param _underlying oToken underlying asset * @param _strike oToken strike asset * @param _collateral oToken collateral asset * @param _expiry otoken expiry timestamp * @return True if the oToken has expired AND all oracle prices at the expiry timestamp have been finalized, False if not */ function canSettleAssets( address _underlying, address _strike, address _collateral, uint256 _expiry ) external view returns (bool) { return _canSettleAssets(_underlying, _strike, _collateral, _expiry); } /** * @notice get the number of vaults for a specified account owner * @param _accountOwner account owner address * @return number of vaults */ function getAccountVaultCounter(address _accountOwner) external view returns (uint256) { return accountVaultCounter[_accountOwner]; } /** * @notice check if an oToken has expired * @param _otoken oToken address * @return True if the otoken has expired, False if not */ function hasExpired(address _otoken) external view returns (bool) { return now >= OtokenInterface(_otoken).expiryTimestamp(); } /** * @notice return a specific vault * @param _owner account owner * @param _vaultId vault id of vault to return * @return Vault struct that corresponds to the _vaultId of _owner */ function getVault(address _owner, uint256 _vaultId) external view returns (MarginVault.Vault memory) { return (vaults[_owner][_vaultId]); } /** * @notice return a specific vault * @param _owner account owner * @param _vaultId vault id of vault to return * @return Vault struct that corresponds to the _vaultId of _owner, vault type and the latest timestamp when the vault was updated */ function getVaultWithDetails(address _owner, uint256 _vaultId) public view returns ( MarginVault.Vault memory, uint256, uint256 ) { return (vaults[_owner][_vaultId], vaultType[_owner][_vaultId], vaultLatestUpdate[_owner][_vaultId]); } /** * @notice get cap amount for collateral asset * @param _asset collateral asset address * @return cap amount */ function getNakedCap(address _asset) external view returns (uint256) { return nakedCap[_asset]; } /** * @notice get amount of collateral deposited in all naked margin vaults * @param _asset collateral asset address * @return naked pool balance */ function getNakedPoolBalance(address _asset) external view returns (uint256) { return nakedPoolBalance[_asset]; } /** * @notice execute a variety of actions * @dev for each action in the action array, execute the corresponding action, only one vault can be modified * for all actions except SettleVault, Redeem, and Call * @param _actions array of type Actions.ActionArgs[], which expresses which actions the user wants to execute * @return vaultUpdated, indicates if a vault has changed * @return owner, the vault owner if a vault has changed * @return vaultId, the vault Id if a vault has changed */ function _runActions(Actions.ActionArgs[] memory _actions) internal returns ( bool, address, uint256 ) { address vaultOwner; uint256 vaultId; bool vaultUpdated; for (uint256 i = 0; i < _actions.length; i++) { Actions.ActionArgs memory action = _actions[i]; Actions.ActionType actionType = action.actionType; // actions except Settle, Redeem, Liquidate and Call are "Vault-updating actinos" // only allow update 1 vault in each operate call if ( (actionType != Actions.ActionType.SettleVault) && (actionType != Actions.ActionType.Redeem) && (actionType != Actions.ActionType.Liquidate) && (actionType != Actions.ActionType.Call) ) { // check if this action is manipulating the same vault as all other actions, if a vault has already been updated if (vaultUpdated) { require(vaultOwner == action.owner, "C12"); require(vaultId == action.vaultId, "C13"); } vaultUpdated = true; vaultId = action.vaultId; vaultOwner = action.owner; } if (actionType == Actions.ActionType.OpenVault) { _openVault(Actions._parseOpenVaultArgs(action)); } else if (actionType == Actions.ActionType.DepositLongOption) { _depositLong(Actions._parseDepositArgs(action)); } else if (actionType == Actions.ActionType.WithdrawLongOption) { _withdrawLong(Actions._parseWithdrawArgs(action)); } else if (actionType == Actions.ActionType.DepositCollateral) { _depositCollateral(Actions._parseDepositArgs(action)); } else if (actionType == Actions.ActionType.WithdrawCollateral) { _withdrawCollateral(Actions._parseWithdrawArgs(action)); } else if (actionType == Actions.ActionType.MintShortOption) { _mintOtoken(Actions._parseMintArgs(action)); } else if (actionType == Actions.ActionType.BurnShortOption) { _burnOtoken(Actions._parseBurnArgs(action)); } else if (actionType == Actions.ActionType.Redeem) { _redeem(Actions._parseRedeemArgs(action)); } else if (actionType == Actions.ActionType.SettleVault) { _settleVault(Actions._parseSettleVaultArgs(action)); } else if (actionType == Actions.ActionType.Liquidate) { _liquidate(Actions._parseLiquidateArgs(action)); } else if (actionType == Actions.ActionType.Call) { _call(Actions._parseCallArgs(action)); } } return (vaultUpdated, vaultOwner, vaultId); } /** * @notice verify the vault final state after executing all actions * @param _owner account owner address * @param _vaultId vault id of the final vault */ function _verifyFinalState(address _owner, uint256 _vaultId) internal view { (MarginVault.Vault memory vault, uint256 typeVault, ) = getVaultWithDetails(_owner, _vaultId); (, bool isValidVault) = calculator.getExcessCollateral(vault, typeVault); require(isValidVault, "C14"); } /** * @notice open a new vault inside an account * @dev only the account owner or operator can open a vault, cannot be called when system is partiallyPaused or fullyPaused * @param _args OpenVaultArgs structure */ function _openVault(Actions.OpenVaultArgs memory _args) internal notPartiallyPaused onlyAuthorized(msg.sender, _args.owner) { uint256 vaultId = accountVaultCounter[_args.owner].add(1); require(_args.vaultId == vaultId, "C15"); // store new vault accountVaultCounter[_args.owner] = vaultId; vaultType[_args.owner][vaultId] = _args.vaultType; emit VaultOpened(_args.owner, vaultId, _args.vaultType); } /** * @notice deposit a long oToken into a vault * @dev only the account owner or operator can deposit a long oToken, cannot be called when system is partiallyPaused or fullyPaused * @param _args DepositArgs structure */ function _depositLong(Actions.DepositArgs memory _args) internal notPartiallyPaused onlyAuthorized(msg.sender, _args.owner) { require(_checkVaultId(_args.owner, _args.vaultId), "C35"); // only allow vault owner or vault operator to deposit long otoken require((_args.from == msg.sender) || (_args.from == _args.owner), "C16"); require(whitelist.isWhitelistedOtoken(_args.asset), "C17"); OtokenInterface otoken = OtokenInterface(_args.asset); require(now < otoken.expiryTimestamp(), "C18"); vaults[_args.owner][_args.vaultId].addLong(_args.asset, _args.amount, _args.index); pool.transferToPool(_args.asset, _args.from, _args.amount); emit LongOtokenDeposited(_args.asset, _args.owner, _args.from, _args.vaultId, _args.amount); } /** * @notice withdraw a long oToken from a vault * @dev only the account owner or operator can withdraw a long oToken, cannot be called when system is partiallyPaused or fullyPaused * @param _args WithdrawArgs structure */ function _withdrawLong(Actions.WithdrawArgs memory _args) internal notPartiallyPaused onlyAuthorized(msg.sender, _args.owner) { require(_checkVaultId(_args.owner, _args.vaultId), "C35"); OtokenInterface otoken = OtokenInterface(_args.asset); require(now < otoken.expiryTimestamp(), "C19"); vaults[_args.owner][_args.vaultId].removeLong(_args.asset, _args.amount, _args.index); pool.transferToUser(_args.asset, _args.to, _args.amount); emit LongOtokenWithdrawed(_args.asset, _args.owner, _args.to, _args.vaultId, _args.amount); } /** * @notice deposit a collateral asset into a vault * @dev only the account owner or operator can deposit collateral, cannot be called when system is partiallyPaused or fullyPaused * @param _args DepositArgs structure */ function _depositCollateral(Actions.DepositArgs memory _args) internal notPartiallyPaused onlyAuthorized(msg.sender, _args.owner) { require(_checkVaultId(_args.owner, _args.vaultId), "C35"); // only allow vault owner or vault operator to deposit collateral require((_args.from == msg.sender) || (_args.from == _args.owner), "C20"); require(whitelist.isWhitelistedCollateral(_args.asset), "C21"); (, uint256 typeVault, ) = getVaultWithDetails(_args.owner, _args.vaultId); if (typeVault == 1) { nakedPoolBalance[_args.asset] = nakedPoolBalance[_args.asset].add(_args.amount); require(nakedPoolBalance[_args.asset] <= nakedCap[_args.asset], "C37"); } vaults[_args.owner][_args.vaultId].addCollateral(_args.asset, _args.amount, _args.index); pool.transferToPool(_args.asset, _args.from, _args.amount); emit CollateralAssetDeposited(_args.asset, _args.owner, _args.from, _args.vaultId, _args.amount); } /** * @notice withdraw a collateral asset from a vault * @dev only the account owner or operator can withdraw collateral, cannot be called when system is partiallyPaused or fullyPaused * @param _args WithdrawArgs structure */ function _withdrawCollateral(Actions.WithdrawArgs memory _args) internal notPartiallyPaused onlyAuthorized(msg.sender, _args.owner) { require(_checkVaultId(_args.owner, _args.vaultId), "C35"); (MarginVault.Vault memory vault, uint256 typeVault, ) = getVaultWithDetails(_args.owner, _args.vaultId); if (_isNotEmpty(vault.shortOtokens)) { OtokenInterface otoken = OtokenInterface(vault.shortOtokens[0]); require(now < otoken.expiryTimestamp(), "C22"); } if (typeVault == 1) { nakedPoolBalance[_args.asset] = nakedPoolBalance[_args.asset].sub(_args.amount); } vaults[_args.owner][_args.vaultId].removeCollateral(_args.asset, _args.amount, _args.index); pool.transferToUser(_args.asset, _args.to, _args.amount); emit CollateralAssetWithdrawed(_args.asset, _args.owner, _args.to, _args.vaultId, _args.amount); } /** * @notice mint short oTokens from a vault which creates an obligation that is recorded in the vault * @dev only the account owner or operator can mint an oToken, cannot be called when system is partiallyPaused or fullyPaused * @param _args MintArgs structure */ function _mintOtoken(Actions.MintArgs memory _args) internal notPartiallyPaused onlyAuthorized(msg.sender, _args.owner) { require(_checkVaultId(_args.owner, _args.vaultId), "C35"); require(whitelist.isWhitelistedOtoken(_args.otoken), "C23"); OtokenInterface otoken = OtokenInterface(_args.otoken); require(now < otoken.expiryTimestamp(), "C24"); vaults[_args.owner][_args.vaultId].addShort(_args.otoken, _args.amount, _args.index); otoken.mintOtoken(_args.to, _args.amount); emit ShortOtokenMinted(_args.otoken, _args.owner, _args.to, _args.vaultId, _args.amount); } /** * @notice burn oTokens to reduce or remove the minted oToken obligation recorded in a vault * @dev only the account owner or operator can burn an oToken, cannot be called when system is partiallyPaused or fullyPaused * @param _args MintArgs structure */ function _burnOtoken(Actions.BurnArgs memory _args) internal notPartiallyPaused onlyAuthorized(msg.sender, _args.owner) { // check that vault id is valid for this vault owner require(_checkVaultId(_args.owner, _args.vaultId), "C35"); // only allow vault owner or vault operator to burn otoken require((_args.from == msg.sender) || (_args.from == _args.owner), "C25"); OtokenInterface otoken = OtokenInterface(_args.otoken); // do not allow burning expired otoken require(now < otoken.expiryTimestamp(), "C26"); // remove otoken from vault vaults[_args.owner][_args.vaultId].removeShort(_args.otoken, _args.amount, _args.index); // burn otoken otoken.burnOtoken(_args.from, _args.amount); emit ShortOtokenBurned(_args.otoken, _args.owner, _args.from, _args.vaultId, _args.amount); } /** * @notice redeem an oToken after expiry, receiving the payout of the oToken in the collateral asset * @dev cannot be called when system is fullyPaused * @param _args RedeemArgs structure */ function _redeem(Actions.RedeemArgs memory _args) internal { OtokenInterface otoken = OtokenInterface(_args.otoken); // check that otoken to redeem is whitelisted require(whitelist.isWhitelistedOtoken(_args.otoken), "C27"); (address collateral, address underlying, address strike, uint256 expiry) = _getOtokenDetails(address(otoken)); // only allow redeeming expired otoken require(now >= expiry, "C28"); require(_canSettleAssets(underlying, strike, collateral, expiry), "C29"); uint256 payout = getPayout(_args.otoken, _args.amount); otoken.burnOtoken(msg.sender, _args.amount); pool.transferToUser(collateral, _args.receiver, payout); emit Redeem(_args.otoken, msg.sender, _args.receiver, collateral, _args.amount, payout); } /** * @notice settle a vault after expiry, removing the net proceeds/collateral after both long and short oToken payouts have settled * @dev deletes a vault of vaultId after net proceeds/collateral is removed, cannot be called when system is fullyPaused * @param _args SettleVaultArgs structure */ function _settleVault(Actions.SettleVaultArgs memory _args) internal onlyAuthorized(msg.sender, _args.owner) { require(_checkVaultId(_args.owner, _args.vaultId), "C35"); (MarginVault.Vault memory vault, uint256 typeVault, ) = getVaultWithDetails(_args.owner, _args.vaultId); OtokenInterface otoken; // new scope to avoid stack too deep error // check if there is short or long otoken in vault // do not allow settling vault that have no short or long otoken // if there is a long otoken, burn it // store otoken address outside of this scope { bool hasShort = _isNotEmpty(vault.shortOtokens); bool hasLong = _isNotEmpty(vault.longOtokens); require(hasShort || hasLong, "C30"); otoken = hasShort ? OtokenInterface(vault.shortOtokens[0]) : OtokenInterface(vault.longOtokens[0]); if (hasLong) { OtokenInterface longOtoken = OtokenInterface(vault.longOtokens[0]); longOtoken.burnOtoken(address(pool), vault.longAmounts[0]); } } (address collateral, address underlying, address strike, uint256 expiry) = _getOtokenDetails(address(otoken)); // do not allow settling vault with un-expired otoken require(now >= expiry, "C31"); require(_canSettleAssets(underlying, strike, collateral, expiry), "C29"); (uint256 payout, bool isValidVault) = calculator.getExcessCollateral(vault, typeVault); // require that vault is valid (has excess collateral) before settling // to avoid allowing settling undercollateralized naked margin vault require(isValidVault, "C32"); delete vaults[_args.owner][_args.vaultId]; if (typeVault == 1) { nakedPoolBalance[collateral] = nakedPoolBalance[collateral].sub(payout); } pool.transferToUser(collateral, _args.to, payout); uint256 vaultId = _args.vaultId; address payoutRecipient = _args.to; emit VaultSettled(_args.owner, address(otoken), payoutRecipient, payout, vaultId, typeVault); } /** * @notice liquidate naked margin vault * @dev can liquidate different vaults id in the same operate() call * @param _args liquidation action arguments struct */ function _liquidate(Actions.LiquidateArgs memory _args) internal notPartiallyPaused { require(_checkVaultId(_args.owner, _args.vaultId), "C35"); // check if vault is undercollateralized // the price is the amount of collateral asset to pay per 1 repaid debt(otoken) // collateralDust is the minimum amount of collateral that can be left in the vault when a partial liquidation occurs (MarginVault.Vault memory vault, bool isUnderCollat, uint256 price, uint256 collateralDust) = _isLiquidatable( _args.owner, _args.vaultId, _args.roundId ); require(isUnderCollat, "C33"); // amount of collateral to offer to liquidator uint256 collateralToSell = _args.amount.mul(price).div(1e8); // if vault is partially liquidated (amount of short otoken is still greater than zero) // make sure remaining collateral amount is greater than dust amount if (vault.shortAmounts[0].sub(_args.amount) > 0) { require(vault.collateralAmounts[0].sub(collateralToSell) >= collateralDust, "C34"); } // burn short otoken from liquidator address, index of short otoken hardcoded at 0 // this should always work, if vault have no short otoken, it will not reach this step OtokenInterface(vault.shortOtokens[0]).burnOtoken(msg.sender, _args.amount); // decrease amount of collateral in liquidated vault, index of collateral to decrease is hardcoded at 0 vaults[_args.owner][_args.vaultId].removeCollateral(vault.collateralAssets[0], collateralToSell, 0); // decrease amount of short otoken in liquidated vault, index of short otoken to decrease is hardcoded at 0 vaults[_args.owner][_args.vaultId].removeShort(vault.shortOtokens[0], _args.amount, 0); // decrease internal naked margin collateral amount nakedPoolBalance[vault.collateralAssets[0]] = nakedPoolBalance[vault.collateralAssets[0]].sub(collateralToSell); pool.transferToUser(vault.collateralAssets[0], _args.receiver, collateralToSell); emit VaultLiquidated( msg.sender, _args.receiver, _args.owner, price, _args.roundId, collateralToSell, _args.amount, _args.vaultId ); } /** * @notice execute arbitrary calls * @dev cannot be called when system is partiallyPaused or fullyPaused * @param _args Call action */ function _call(Actions.CallArgs memory _args) internal notPartiallyPaused onlyWhitelistedCallee(_args.callee) { CalleeInterface(_args.callee).callFunction(msg.sender, _args.data); emit CallExecuted(msg.sender, _args.callee, _args.data); } /** * @notice check if a vault id is valid for a given account owner address * @param _accountOwner account owner address * @param _vaultId vault id to check * @return True if the _vaultId is valid, False if not */ function _checkVaultId(address _accountOwner, uint256 _vaultId) internal view returns (bool) { return ((_vaultId > 0) && (_vaultId <= accountVaultCounter[_accountOwner])); } function _isNotEmpty(address[] memory _array) internal pure returns (bool) { return (_array.length > 0) && (_array[0] != address(0)); } /** * @notice return if a callee address is whitelisted or not * @param _callee callee address * @return True if callee address is whitelisted, False if not */ function _isCalleeWhitelisted(address _callee) internal view returns (bool) { return whitelist.isWhitelistedCallee(_callee); } /** * @notice check if a vault is liquidatable in a specific round id * @param _owner vault owner address * @param _vaultId vault id to check * @param _roundId chainlink round id to check vault status at * @return vault struct, isLiquidatable, true if vault is undercollateralized, the price of 1 repaid otoken and the otoken collateral dust amount */ function _isLiquidatable( address _owner, uint256 _vaultId, uint256 _roundId ) internal view returns ( MarginVault.Vault memory, bool, uint256, uint256 ) { (MarginVault.Vault memory vault, uint256 typeVault, uint256 latestUpdateTimestamp) = getVaultWithDetails( _owner, _vaultId ); (bool isUnderCollat, uint256 price, uint256 collateralDust) = calculator.isLiquidatable( vault, typeVault, latestUpdateTimestamp, _roundId ); return (vault, isUnderCollat, price, collateralDust); } /** * @dev get otoken detail, from both otoken versions */ function _getOtokenDetails(address _otoken) internal view returns ( address, address, address, uint256 ) { OtokenInterface otoken = OtokenInterface(_otoken); try otoken.getOtokenDetails() returns ( address collateral, address underlying, address strike, uint256, uint256 expiry, bool ) { return (collateral, underlying, strike, expiry); } catch { return (otoken.collateralAsset(), otoken.underlyingAsset(), otoken.strikeAsset(), otoken.expiryTimestamp()); } } /** * @dev return if an expired oToken is ready to be settled, only true when price for underlying, * strike and collateral assets at this specific expiry is available in our Oracle module * @return True if the oToken has expired AND all oracle prices at the expiry timestamp have been finalized, False if not */ function _canSettleAssets( address _underlying, address _strike, address _collateral, uint256 _expiry ) internal view returns (bool) { return oracle.isDisputePeriodOver(_underlying, _expiry) && oracle.isDisputePeriodOver(_strike, _expiry) && oracle.isDisputePeriodOver(_collateral, _expiry); } /** * @dev updates the internal configuration of the controller */ function _refreshConfigInternal() internal { whitelist = WhitelistInterface(addressbook.getWhitelist()); oracle = OracleInterface(addressbook.getOracle()); calculator = MarginCalculatorInterface(addressbook.getMarginCalculator()); pool = MarginPoolInterface(addressbook.getMarginPool()); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"accountOwner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"isSet","type":"bool"}],"name":"AccountOperatorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"CallExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isRestricted","type":"bool"}],"name":"CallRestricted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"accountOwner","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"CollateralAssetDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"AccountOwner","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"CollateralAssetWithdrawed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"donator","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Donated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldFullPauser","type":"address"},{"indexed":true,"internalType":"address","name":"newFullPauser","type":"address"}],"name":"FullPauserUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"otoken","type":"address"},{"indexed":true,"internalType":"address","name":"accountOwner","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LongOtokenDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"otoken","type":"address"},{"indexed":true,"internalType":"address","name":"AccountOwner","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LongOtokenWithdrawed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collateral","type":"address"},{"indexed":false,"internalType":"uint256","name":"cap","type":"uint256"}],"name":"NakedCapUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldPartialPauser","type":"address"},{"indexed":true,"internalType":"address","name":"newPartialPauser","type":"address"}],"name":"PartialPauserUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"otoken","type":"address"},{"indexed":true,"internalType":"address","name":"redeemer","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"address","name":"collateralAsset","type":"address"},{"indexed":false,"internalType":"uint256","name":"otokenBurned","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"payout","type":"uint256"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"otoken","type":"address"},{"indexed":true,"internalType":"address","name":"AccountOwner","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ShortOtokenBurned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"otoken","type":"address"},{"indexed":true,"internalType":"address","name":"AccountOwner","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ShortOtokenMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isPaused","type":"bool"}],"name":"SystemFullyPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isPaused","type":"bool"}],"name":"SystemPartiallyPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"liquidator","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"address","name":"vaultOwner","type":"address"},{"indexed":false,"internalType":"uint256","name":"auctionPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"auctionStartingRound","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"collateralPayout","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"debtAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"vaultId","type":"uint256"}],"name":"VaultLiquidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"accountOwner","type":"address"},{"indexed":false,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"vaultType","type":"uint256"}],"name":"VaultOpened","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"accountOwner","type":"address"},{"indexed":true,"internalType":"address","name":"oTokenAddress","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"payout","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"vaultType","type":"uint256"}],"name":"VaultSettled","type":"event"},{"inputs":[],"name":"addressbook","outputs":[{"internalType":"contract AddressBookInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"calculator","outputs":[{"internalType":"contract MarginCalculatorInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"callRestricted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_underlying","type":"address"},{"internalType":"address","name":"_strike","type":"address"},{"internalType":"address","name":"_collateral","type":"address"},{"internalType":"uint256","name":"_expiry","type":"uint256"}],"name":"canSettleAssets","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"donate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fullPauser","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_accountOwner","type":"address"}],"name":"getAccountVaultCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConfiguration","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"getNakedCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"getNakedPoolBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_otoken","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"getPayout","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_vaultId","type":"uint256"}],"name":"getProceed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_vaultId","type":"uint256"}],"name":"getVault","outputs":[{"components":[{"internalType":"address[]","name":"shortOtokens","type":"address[]"},{"internalType":"address[]","name":"longOtokens","type":"address[]"},{"internalType":"address[]","name":"collateralAssets","type":"address[]"},{"internalType":"uint256[]","name":"shortAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"longAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"collateralAmounts","type":"uint256[]"}],"internalType":"struct MarginVault.Vault","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_vaultId","type":"uint256"}],"name":"getVaultWithDetails","outputs":[{"components":[{"internalType":"address[]","name":"shortOtokens","type":"address[]"},{"internalType":"address[]","name":"longOtokens","type":"address[]"},{"internalType":"address[]","name":"collateralAssets","type":"address[]"},{"internalType":"uint256[]","name":"shortAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"longAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"collateralAmounts","type":"uint256[]"}],"internalType":"struct MarginVault.Vault","name":"","type":"tuple"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_otoken","type":"address"}],"name":"hasExpired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addressBook","type":"address"},{"internalType":"address","name":"_owner","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_vaultId","type":"uint256"},{"internalType":"uint256","name":"_roundId","type":"uint256"}],"name":"isLiquidatable","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"isOperator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_otoken","type":"address"}],"name":"isSettlementAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"enum Actions.ActionType","name":"actionType","type":"uint8"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"secondAddress","type":"address"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Actions.ActionArgs[]","name":"_actions","type":"tuple[]"}],"name":"operate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"oracle","outputs":[{"internalType":"contract OracleInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"partialPauser","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pool","outputs":[{"internalType":"contract MarginPoolInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refreshConfiguration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_isRestricted","type":"bool"}],"name":"setCallRestriction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fullPauser","type":"address"}],"name":"setFullPauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_collateral","type":"address"},{"internalType":"uint256","name":"_cap","type":"uint256"}],"name":"setNakedCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"bool","name":"_isOperator","type":"bool"}],"name":"setOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_partialPauser","type":"address"}],"name":"setPartialPauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_fullyPaused","type":"bool"}],"name":"setSystemFullyPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_partiallyPaused","type":"bool"}],"name":"setSystemPartiallyPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_vaultId","type":"uint256"}],"name":"sync","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"systemFullyPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"systemPartiallyPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"whitelist","outputs":[{"internalType":"contract WhitelistInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50615d8f80620000216000396000f3fe608060405234801561001057600080fd5b50600436106102325760003560e01c8063b617f0c611610130578063ce3e39c0116100b8578063eaa33e141161007c578063eaa33e1414610479578063eab7775b1461049b578063ef4fcafa146104a3578063f2fde38b146104b6578063f77bc88b146104c957610232565b8063ce3e39c014610418578063d66dd43e14610420578063d99d13f514610433578063e69d849d14610453578063e723406c1461046657610232565b8063c220101d116100ff578063c220101d146103c4578063c644d3a2146103d7578063caa6d21a146103ea578063cab2e805146103fd578063cdee058a1461041057610232565b8063b617f0c614610378578063b6363cf21461038b578063bc463a3d1461039e578063beca75d7146103b157610232565b80636bd50cef116101be5780638da5cb5b116101825780638da5cb5b1461032b57806393e59dc1146103335780639daafbe81461033b5780639db938911461035d5780639f677ed91461036557610232565b80636bd50cef146102f35780636c0c3b991461030b57806370dc320c14610313578063715018a61461031b5780637dc0d1d01461032357610232565b8063485cc95511610205578063485cc95514610292578063558a7297146102a5578063565eea19146102b8578063573c473e146102d857806364681083146102eb57610232565b806314b93faf1461023757806316f0115b1461026057806329729d88146102755780632eb1c3a71461027d575b600080fd5b61024a610245366004614e73565b6104dc565b60405161025791906153c0565b60405180910390f35b6102686104f3565b60405161025791906152f7565b610268610502565b61029061028b366004614f63565b610511565b005b6102906102a0366004614e3b565b6105c6565b6102906102b3366004614f36565b6106de565b6102cb6102c6366004614f63565b610797565b6040516102579190615cd5565b6102906102e63660046150f8565b610849565b610290610900565b6102fb61093f565b6040516102579493929190615374565b61024a610964565b610268610974565b610290610983565b610268610a02565b610268610a11565b610268610a21565b61034e610349366004614f63565b610a30565b60405161025793929190615c5d565b610268610cc9565b6102906103733660046150f8565b610cd8565b610290610386366004614fc2565b610d84565b61024a610399366004614e3b565b610e16565b6102906103ac366004614e03565b610e44565b6102906103bf366004614e03565b610f29565b6102cb6103d2366004614f63565b61100e565b6102cb6103e5366004614e03565b6110cf565b6102cb6103f8366004614e03565b6110ea565b61029061040b3660046150f8565b611105565b61024a6111bc565b6102686111cc565b6102cb61042e366004614e03565b6111db565b610446610441366004614f63565b6111f6565b6040516102579190615c28565b610290610461366004614f63565b611457565b61024a610474366004614e03565b611500565b61048c610487366004614f8e565b61152f565b604051610257939291906153cb565b61024a611556565b6102906104b1366004614f63565b611566565b6102906104c4366004614e03565b6115d9565b61024a6104d7366004614e03565b611690565b60006104ea8585858561170c565b95945050505050565b60cd546001600160a01b031681565b60cf546001600160a01b031681565b6105196118a1565b6065546001600160a01b0390811691161461054f5760405162461bcd60e51b8152600401610546906158a3565b60405180910390fd5b6000811161056f5760405162461bcd60e51b81526004016105469061575f565b6001600160a01b038216600081815260d5602052604090819020839055517f6ff730ba70e34bd5ca823424bd15ab869cadc6bad079b527c71bde444ad6402b906105ba908490615cd5565b60405180910390a25050565b600054610100900460ff16806105df57506105df6118a5565b806105ed575060005460ff16155b6106095760405162461bcd60e51b8152600401610546906158f5565b600054610100900460ff16158015610634576000805460ff1961ff0019909116610100171660011790555b6001600160a01b03831661065a5760405162461bcd60e51b81526004016105469061580c565b6001600160a01b0382166106805760405162461bcd60e51b815260040161054690615bd4565b610689826118ab565b610691611940565b60c980546001600160a01b0319166001600160a01b0385161790556106b46119d0565b60cf805460ff60b01b1916600160b01b17905580156106d9576000805461ff00191690555b505050565b33600090815260d2602090815260408083206001600160a01b038616845290915290205460ff16151581151514156107285760405162461bcd60e51b815260040161054690615af2565b33600081815260d2602090815260408083206001600160a01b038716808552925291829020805460ff191685151517905590519091907f1ae45540b0875932452da603b351ce2f1758258ba1345e79f8fc94f044cb07879061078b9085906153c0565b60405180910390a35050565b60cc54604051630478409360e41b8152600091610840916305f5e100916108349186916001600160a01b0316906347840930906107d8908a906004016152f7565b60206040518083038186803b1580156107f057600080fd5b505afa158015610804573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108289190615166565b9063ffffffff611c2b16565b9063ffffffff611c6516565b90505b92915050565b60ce546001600160a01b031633146108735760405162461bcd60e51b81526004016105469061553f565b60cf5460ff600160a01b90910416151581151514156108a45760405162461bcd60e51b815260040161054690615af2565b60cf805460ff60a01b1916600160a01b831515810291909117918290556040517f531c3d7229f510a8da00a0f5792686958cdd9c8a120c3c030a6053cd66b68556926108f59260ff910416906153c0565b60405180910390a150565b6109086118a1565b6065546001600160a01b039081169116146109355760405162461bcd60e51b8152600401610546906158a3565b61093d6119d0565b565b60ca5460cb5460cc5460cd546001600160a01b03938416949284169391821692911690565b60cf54600160b01b900460ff1681565b60c9546001600160a01b031681565b61098b6118a1565b6065546001600160a01b039081169116146109b85760405162461bcd60e51b8152600401610546906158a3565b6065546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3606580546001600160a01b0319169055565b60cb546001600160a01b031681565b6065546001600160a01b03165b90565b60ca546001600160a01b031681565b610a38614bb9565b6001600160a01b038316600081815260d160209081526040808320868452825280832084845260d3835281842087855283528184205494845260d483528184208785528352818420548251825460e09581028201860190945260c081018481529596879693959094929391928692849290918491840182828015610ae557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ac7575b5050505050815260200160018201805480602002602001604051908101604052809291908181526020018280548015610b4757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b29575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015610ba957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b8b575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610c0157602002820191906000526020600020905b815481526020019060010190808311610bed575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020018280548015610c5957602002820191906000526020600020905b815481526020019060010190808311610c45575b5050505050815260200160058201805480602002602001604051908101604052809291908181526020018280548015610cb157602002820191906000526020600020905b815481526020019060010190808311610c9d575b50505050508152505092509250925092509250925092565b60ce546001600160a01b031681565b60cf546001600160a01b03163314610d025760405162461bcd60e51b81526004016105469061577c565b60cf5460ff600160a81b9091041615158115151415610d335760405162461bcd60e51b815260040161054690615af2565b60cf805460ff60a81b1916600160a81b831515810291909117918290556040517f4f1d0445688d95c99ca9fc036f551b205fd18ff26a4443b1979c16d1ba66b535926108f59260ff910416906153c0565b60975460ff16610da65760405162461bcd60e51b815260040161054690615b9d565b6097805460ff19169055610db8611ca7565b6000806000610dc684611cd1565b9250925092508215610e0357610ddc8282611f87565b6001600160a01b038216600090815260d46020908152604080832084845290915290204290555b50506097805460ff191660011790555050565b6001600160a01b03918216600090815260d26020908152604080832093909416825291909152205460ff1690565b610e4c6118a1565b6065546001600160a01b03908116911614610e795760405162461bcd60e51b8152600401610546906158a3565b6001600160a01b038116610e9f5760405162461bcd60e51b815260040161054690615679565b60ce546001600160a01b0382811691161415610ecd5760405162461bcd60e51b815260040161054690615af2565b60ce546040516001600160a01b038084169216907f1440312dbc326ddc21bfa95078324bf5aaf6899e8a27cba3057c60adfc84e40b90600090a360ce80546001600160a01b0319166001600160a01b0392909216919091179055565b610f316118a1565b6065546001600160a01b03908116911614610f5e5760405162461bcd60e51b8152600401610546906158a3565b6001600160a01b038116610f845760405162461bcd60e51b8152600401610546906155af565b60cf546001600160a01b0382811691161415610fb25760405162461bcd60e51b815260040161054690615af2565b60cf546040516001600160a01b038084169216907f44f3e9e7b454118e9fcb2e3026396f57ca21d7bd7dcabd31d7f986806422f4df90600090a360cf80546001600160a01b0319166001600160a01b0392909216919091179055565b6000611018614bb9565b60006110248585610a30565b5060cc5460405163cd43fbfb60e01b815292945090925060009182916001600160a01b03169063cd43fbfb906110609087908790600401615c3b565b604080518083038186803b15801561107757600080fd5b505afa15801561108b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110af919061517e565b91509150806110c5576000945050505050610843565b5095945050505050565b6001600160a01b0316600090815260d5602052604090205490565b6001600160a01b0316600090815260d0602052604090205490565b61110d6118a1565b6065546001600160a01b0390811691161461113a5760405162461bcd60e51b8152600401610546906158a3565b60cf5460ff600160b01b909104161515811515141561116b5760405162461bcd60e51b815260040161054690615af2565b60cf805460ff60b01b1916600160b01b831515810291909117918290556040517f26d614575a4c104c181c87003d4bb00cc7ade00d5b47bf8775171c12a376b255926108f59260ff910416906153c0565b60cf54600160a01b900460ff1681565b60cc546001600160a01b031681565b6001600160a01b0316600090815260d6602052604090205490565b6111fe614bb9565b6001600160a01b038316600090815260d1602090815260408083208584528252918290208251815460e09381028201840190945260c08101848152909391928492849184018282801561127a57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161125c575b50505050508152602001600182018054806020026020016040519081016040528092919081815260200182805480156112dc57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116112be575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561133e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611320575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561139657602002820191906000526020600020905b815481526020019060010190808311611382575b50505050508152602001600482018054806020026020016040519081016040528092919081815260200182805480156113ee57602002820191906000526020600020905b8154815260200190600101908083116113da575b505050505081526020016005820180548060200260200160405190810160405280929190818152602001828054801561144657602002820191906000526020600020905b815481526020019060010190808311611432575b505050505081525050905092915050565b60cd5460405163dd2c99f760e01b81526001600160a01b039091169063dd2c99f79061148b90859033908690600401615350565b600060405180830381600087803b1580156114a557600080fd5b505af11580156114b9573d6000803e3d6000fd5b50505050816001600160a01b0316336001600160a01b03167f4dfff917e1fbb261a082e98cc7d43029621f6a6eb05ff3fef1510d5f1eb4857c8360405161078b9190615cd5565b60008060008060006115118661204d565b93509350935093506115258484848461170c565b9695505050505050565b6000806000806000806115438989896122b2565b919c909b50909950975050505050505050565b60cf54600160a81b900460ff1681565b60975460ff166115885760405162461bcd60e51b815260040161054690615b9d565b6097805460ff1916905561159a611ca7565b6115a48282611f87565b6001600160a01b03909116600090815260d460209081526040808320938352929052204290556097805460ff19166001179055565b6115e16118a1565b6065546001600160a01b0390811691161461160e5760405162461bcd60e51b8152600401610546906158a3565b6001600160a01b0381166116345760405162461bcd60e51b8152600401610546906154f9565b6065546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b6000816001600160a01b031663ade6e2aa6040518163ffffffff1660e01b815260040160206040518083038186803b1580156116cb57600080fd5b505afa1580156116df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117039190615166565b42101592915050565b60cb54604051635fdc714960e01b81526000916001600160a01b031690635fdc71499061173f9088908690600401615337565b60206040518083038186803b15801561175757600080fd5b505afa15801561176b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061178f9190615114565b8015611818575060cb54604051635fdc714960e01b81526001600160a01b0390911690635fdc7149906117c89087908690600401615337565b60206040518083038186803b1580156117e057600080fd5b505afa1580156117f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118189190615114565b80156104ea575060cb54604051635fdc714960e01b81526001600160a01b0390911690635fdc7149906118519086908690600401615337565b60206040518083038186803b15801561186957600080fd5b505afa15801561187d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ea9190615114565b3390565b303b1590565b600054610100900460ff16806118c457506118c46118a5565b806118d2575060005460ff16155b6118ee5760405162461bcd60e51b8152600401610546906158f5565b600054610100900460ff16158015611919576000805460ff1961ff0019909116610100171660011790555b61192161238d565b61192a8261240f565b801561193c576000805461ff00191690555b5050565b600054610100900460ff168061195957506119596118a5565b80611967575060005460ff16155b6119835760405162461bcd60e51b8152600401610546906158f5565b600054610100900460ff161580156119ae576000805460ff1961ff0019909116610100171660011790555b6097805460ff1916600117905580156119cd576000805461ff00191690555b50565b60c960009054906101000a90046001600160a01b03166001600160a01b031663d01f63f56040518163ffffffff1660e01b815260040160206040518083038186803b158015611a1e57600080fd5b505afa158015611a32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a569190614e1f565b60ca80546001600160a01b0319166001600160a01b0392831617905560c9546040805163419d8fe760e11b81529051919092169163833b1fce916004808301926020929190829003018186803b158015611aaf57600080fd5b505afa158015611ac3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae79190614e1f565b60cb80546001600160a01b0319166001600160a01b0392831617905560c9546040805163cf28493f60e01b81529051919092169163cf28493f916004808301926020929190829003018186803b158015611b4057600080fd5b505afa158015611b54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b789190614e1f565b60cc80546001600160a01b0319166001600160a01b0392831617905560c95460408051633aa431a160e11b8152905191909216916375486342916004808301926020929190829003018186803b158015611bd157600080fd5b505afa158015611be5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c099190614e1f565b60cd80546001600160a01b0319166001600160a01b0392909216919091179055565b600082611c3a57506000610843565b82820282848281611c4757fe5b04146108405760405162461bcd60e51b815260040161054690615845565b600061084083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506124db565b60cf54600160a81b900460ff161561093d5760405162461bcd60e51b815260040161054690615c0c565b60008080808080805b8751811015611f7b57611ceb614bef565b888281518110611cf757fe5b60209081029190910101518051909150600781600a811115611d1557fe5b14158015611d2f5750600881600a811115611d2c57fe5b14155b8015611d475750600a81600a811115611d4457fe5b14155b8015611d5f5750600981600a811115611d5c57fe5b14155b15611dd5578315611dc25781602001516001600160a01b0316866001600160a01b031614611d9f5760405162461bcd60e51b8152600401610546906157d2565b81608001518514611dc25760405162461bcd60e51b8152600401610546906155e9565b6001935081608001519450816020015195505b600081600a811115611de357fe5b1415611dff57611dfa611df583612512565b6125ea565b611f71565b600381600a811115611e0d57fe5b1415611e2457611dfa611e1f836126d9565b6127b5565b600481600a811115611e3257fe5b1415611e4957611dfa611e4483612b06565b612ba5565b600581600a811115611e5757fe5b1415611e6e57611dfa611e69836126d9565b612df9565b600681600a811115611e7c57fe5b1415611e9357611dfa611e8e83612b06565b613157565b600181600a811115611ea157fe5b1415611eb857611dfa611eb38361345b565b6134b9565b600281600a811115611ec657fe5b1415611edd57611dfa611ed8836137a1565b6137ff565b600881600a811115611eeb57fe5b1415611f0257611dfa611efd83613a98565b613b2a565b600781600a811115611f1057fe5b1415611f2757611dfa611f2283613d79565b613e41565b600a81600a811115611f3557fe5b1415611f4c57611dfa611f478361429e565b6143b8565b600981600a811115611f5a57fe5b1415611f7157611f71611f6c83614837565b6148bc565b5050600101611cda565b50969195509350915050565b611f8f614bb9565b6000611f9b8484610a30565b5060cc5460405163cd43fbfb60e01b81529294509092506000916001600160a01b039091169063cd43fbfb90611fd79086908690600401615c3b565b604080518083038186803b158015611fee57600080fd5b505afa158015612002573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612026919061517e565b915050806120465760405162461bcd60e51b815260040161054690615412565b5050505050565b6000806000806000859050806001600160a01b031663af0968fc6040518163ffffffff1660e01b815260040160c06040518083038186803b15801561209157600080fd5b505afa9250505080156120c1575060408051601f3d908101601f191682019092526120be91810190614ec3565b60015b61229757806001600160a01b031663aabaecd66040518163ffffffff1660e01b815260040160206040518083038186803b1580156120fe57600080fd5b505afa158015612112573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121369190614e1f565b816001600160a01b0316637158da7c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561216f57600080fd5b505afa158015612183573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a79190614e1f565b826001600160a01b03166317d69bc86040518163ffffffff1660e01b815260040160206040518083038186803b1580156121e057600080fd5b505afa1580156121f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122189190614e1f565b836001600160a01b031663ade6e2aa6040518163ffffffff1660e01b815260040160206040518083038186803b15801561225157600080fd5b505afa158015612265573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122899190615166565b9450945094509450506122ab565b5093985091965094509092506122ab915050565b9193509193565b6122ba614bb9565b60008060006122c7614bb9565b6000806122d48a8a610a30565b925092509250600080600060cc60009054906101000a90046001600160a01b03166001600160a01b031663a6c569078787878f6040518563ffffffff1660e01b81526004016123269493929190615c82565b60606040518083038186803b15801561233e57600080fd5b505afa158015612352573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123769190615130565b979f919e509c50959a509498505050505050505050565b600054610100900460ff16806123a657506123a66118a5565b806123b4575060005460ff16155b6123d05760405162461bcd60e51b8152600401610546906158f5565b600054610100900460ff161580156123fb576000805460ff1961ff0019909116610100171660011790555b80156119cd576000805461ff001916905550565b600054610100900460ff168061242857506124286118a5565b80612436575060005460ff16155b6124525760405162461bcd60e51b8152600401610546906158f5565b600054610100900460ff1615801561247d576000805460ff1961ff0019909116610100171660011790555b606580546001600160a01b0319166001600160a01b0384169081179091556040516000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3801561193c576000805461ff00191690555050565b600081836124fc5760405162461bcd60e51b815260040161054691906153e3565b50600083858161250857fe5b0495945050505050565b61251a614c50565b60008251600a81111561252957fe5b146125465760405162461bcd60e51b815260040161054690615623565b60208201516001600160a01b03166125705760405162461bcd60e51b8152600401610546906156b2565b60008260e00151516020141561259b578260e001518060200190518101906125989190615166565b90505b600281106125bb5760405162461bcd60e51b8152600401610546906154c0565b604080516060810182526020808601516001600160a01b03168252608090950151948101949094528301525090565b6125f26149af565b8051339061260082826149d9565b82516001600160a01b0316600090815260d0602052604081205461262b90600163ffffffff614a3a16565b9050808460200151146126505760405162461bcd60e51b8152600401610546906157b5565b83516001600160a01b03908116600090815260d060209081526040808320859055808801805189518616855260d384528285208786529093529281902091909155905186519151909291909116907f5d66689e2c864b4f21efd3988c0ce5dc8a197981b68e81ce73660e92394fe25f906126cb908590615cd5565b60405180910390a350505050565b6126e1614c7a565b60038251600a8111156126f057fe5b1480612708575060058251600a81111561270657fe5b145b6127245760405162461bcd60e51b8152600401610546906159f1565b60208201516001600160a01b031661274e5760405162461bcd60e51b815260040161054690615a0d565b6040518060c0016040528083602001516001600160a01b031681526020018360800151815260200183604001516001600160a01b0316815260200183606001516001600160a01b031681526020018360c0015181526020018360a001518152509050919050565b6127bd6149af565b805133906127cb82826149d9565b6127dd83600001518460200151614a5f565b6127f95760405162461bcd60e51b815260040161054690615725565b60408301516001600160a01b031633148061282d575082600001516001600160a01b031683604001516001600160a01b0316145b6128495760405162461bcd60e51b81526004016105469061555b565b60ca5460608401516040516302328d7360e31b81526001600160a01b03909216916311946b989161287c916004016152f7565b60206040518083038186803b15801561289457600080fd5b505afa1580156128a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128cc9190615114565b6128e85760405162461bcd60e51b815260040161054690615b63565b600083606001519050806001600160a01b031663ade6e2aa6040518163ffffffff1660e01b815260040160206040518083038186803b15801561292a57600080fd5b505afa15801561293e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129629190615166565b42106129805760405162461bcd60e51b8152600401610546906156ce565b83516001600160a01b0316600090815260d16020908152604080832082880151845290915290819020606086015160a08701516080880151935163155bf27360e31b8152734d3a52a0e98144caf46ac226d83e8f144b5c654d9463aadf9398946129f39490939092909190600401615cb1565b60006040518083038186803b158015612a0b57600080fd5b505af4158015612a1f573d6000803e3d6000fd5b505060cd54606087015160408089015160a08a0151915163dd2c99f760e01b81526001600160a01b03909416955063dd2c99f79450612a6393909190600401615350565b600060405180830381600087803b158015612a7d57600080fd5b505af1158015612a91573d6000803e3d6000fd5b5050505083604001516001600160a01b031684600001516001600160a01b031685606001516001600160a01b03167f2607e210004cef0ad6b3e6aedb778bffb03c1586f8dcf55d49afffde210d8bb187602001518860a00151604051612af8929190615cde565b60405180910390a450505050565b612b0e614c7a565b60048251600a811115612b1d57fe5b1480612b35575060068251600a811115612b3357fe5b145b612b515760405162461bcd60e51b8152600401610546906158d8565b60208201516001600160a01b0316612b7b5760405162461bcd60e51b815260040161054690615469565b60408201516001600160a01b031661274e5760405162461bcd60e51b815260040161054690615960565b612bad6149af565b80513390612bbb82826149d9565b612bcd83600001518460200151614a5f565b612be95760405162461bcd60e51b815260040161054690615725565b600083606001519050806001600160a01b031663ade6e2aa6040518163ffffffff1660e01b815260040160206040518083038186803b158015612c2b57600080fd5b505afa158015612c3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c639190615166565b4210612c815760405162461bcd60e51b815260040161054690615a7f565b83516001600160a01b0316600090815260d16020908152604080832082880151845290915290819020606086015160a08701516080880151935163951dd8d360e01b8152734d3a52a0e98144caf46ac226d83e8f144b5c654d9463951dd8d394612cf49490939092909190600401615cb1565b60006040518083038186803b158015612d0c57600080fd5b505af4158015612d20573d6000803e3d6000fd5b505060cd54606087015160408089015160a08a0151915163fa93b2a560e01b81526001600160a01b03909416955063fa93b2a59450612d6493909190600401615350565b600060405180830381600087803b158015612d7e57600080fd5b505af1158015612d92573d6000803e3d6000fd5b5050505083604001516001600160a01b031684600001516001600160a01b031685606001516001600160a01b03167fbd023c53d293da163d185720d4274f4ddabc09d5304491a55abb296cc811d9fa87602001518860a00151604051612af8929190615cde565b612e016149af565b80513390612e0f82826149d9565b612e2183600001518460200151614a5f565b612e3d5760405162461bcd60e51b815260040161054690615725565b60408301516001600160a01b0316331480612e71575082600001516001600160a01b031683604001516001600160a01b0316145b612e8d5760405162461bcd60e51b81526004016105469061542f565b60ca54606084015160405163f9839d8960e01b81526001600160a01b039092169163f9839d8991612ec0916004016152f7565b60206040518083038186803b158015612ed857600080fd5b505afa158015612eec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f109190615114565b612f2c5760405162461bcd60e51b815260040161054690615708565b6000612f4084600001518560200151610a30565b509150508060011415612fdf5760a084015160608501516001600160a01b0316600090815260d66020526040902054612f7e9163ffffffff614a3a16565b6060850180516001600160a01b03908116600090815260d6602081815260408084209690965584518416835260d58152858320549451909316825290915291909120541115612fdf5760405162461bcd60e51b815260040161054690615886565b83516001600160a01b0316600090815260d16020908152604080832082880151845290915290819020606086015160a0870151608088015193516301f974ab60e61b8152734d3a52a0e98144caf46ac226d83e8f144b5c654d94637e5d2ac0946130529490939092909190600401615cb1565b60006040518083038186803b15801561306a57600080fd5b505af415801561307e573d6000803e3d6000fd5b505060cd54606087015160408089015160a08a0151915163dd2c99f760e01b81526001600160a01b03909416955063dd2c99f794506130c293909190600401615350565b600060405180830381600087803b1580156130dc57600080fd5b505af11580156130f0573d6000803e3d6000fd5b5050505083604001516001600160a01b031684600001516001600160a01b031685606001516001600160a01b03167fbfab88b861f171b7db714f00e5966131253918d55ddba816c3eb94657d10239087602001518860a00151604051612af8929190615cde565b61315f6149af565b8051339061316d82826149d9565b61317f83600001518460200151614a5f565b61319b5760405162461bcd60e51b815260040161054690615725565b6131a3614bb9565b60006131b785600001518660200151610a30565b50915091506131c98260000151614a8c565b1561327c57600082600001516000815181106131e157fe5b60200260200101519050806001600160a01b031663ade6e2aa6040518163ffffffff1660e01b815260040160206040518083038186803b15801561322457600080fd5b505afa158015613238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061325c9190615166565b421061327a5760405162461bcd60e51b815260040161054690615943565b505b80600114156132d45760a085015160608601516001600160a01b0316600090815260d660205260409020546132b69163ffffffff614aca16565b60608601516001600160a01b0316600090815260d660205260409020555b84516001600160a01b0316600090815260d16020908152604080832082890151845290915290819020606087015160a088015160808901519351630380bfdd60e61b8152734d3a52a0e98144caf46ac226d83e8f144b5c654d9463e02ff740946133479490939092909190600401615cb1565b60006040518083038186803b15801561335f57600080fd5b505af4158015613373573d6000803e3d6000fd5b505060cd5460608801516040808a015160a08b0151915163fa93b2a560e01b81526001600160a01b03909416955063fa93b2a594506133b793909190600401615350565b600060405180830381600087803b1580156133d157600080fd5b505af11580156133e5573d6000803e3d6000fd5b5050505084604001516001600160a01b031685600001516001600160a01b031686606001516001600160a01b03167ffe86f7694b6c54a528acbe27be61dd4a85e9a89aeef7f650a1b439045ccee5a488602001518960a0015160405161344c929190615cde565b60405180910390a45050505050565b613463614c7a565b60018251600a81111561347257fe5b1461348f5760405162461bcd60e51b815260040161054690615b0e565b60208201516001600160a01b031661274e5760405162461bcd60e51b815260040161054690615b47565b6134c16149af565b805133906134cf82826149d9565b6134e183600001518460200151614a5f565b6134fd5760405162461bcd60e51b815260040161054690615725565b60ca5460608401516040516302328d7360e31b81526001600160a01b03909216916311946b9891613530916004016152f7565b60206040518083038186803b15801561354857600080fd5b505afa15801561355c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135809190615114565b61359c5760405162461bcd60e51b81526004016105469061563f565b600083606001519050806001600160a01b031663ade6e2aa6040518163ffffffff1660e01b815260040160206040518083038186803b1580156135de57600080fd5b505afa1580156135f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136169190615166565b42106136345760405162461bcd60e51b815260040161054690615828565b83516001600160a01b0316600090815260d16020908152604080832082880151845290915290819020606086015160a08701516080880151935163ef682c1b60e01b8152734d3a52a0e98144caf46ac226d83e8f144b5c654d9463ef682c1b946136a79490939092909190600401615cb1565b60006040518083038186803b1580156136bf57600080fd5b505af41580156136d3573d6000803e3d6000fd5b50505060408086015160a0870151915163051b0a4160e41b81526001600160a01b03851693506351b0a4109261370c9291600401615337565b600060405180830381600087803b15801561372657600080fd5b505af115801561373a573d6000803e3d6000fd5b5050505083604001516001600160a01b031684600001516001600160a01b031685606001516001600160a01b03167f4d7f96086c92b2f9a254ad21548b1c1f2d99502c7949508866349b96bb1a8d8a87602001518860a00151604051612af8929190615cde565b6137a9614c7a565b60028251600a8111156137b857fe5b146137d55760405162461bcd60e51b815260040161054690615a46565b60208201516001600160a01b031661274e5760405162461bcd60e51b815260040161054690615696565b6138076149af565b8051339061381582826149d9565b61382783600001518460200151614a5f565b6138435760405162461bcd60e51b815260040161054690615725565b60408301516001600160a01b0316331480613877575082600001516001600160a01b031683604001516001600160a01b0316145b6138935760405162461bcd60e51b81526004016105469061565c565b600083606001519050806001600160a01b031663ade6e2aa6040518163ffffffff1660e01b815260040160206040518083038186803b1580156138d557600080fd5b505afa1580156138e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061390d9190615166565b421061392b5760405162461bcd60e51b8152600401610546906154a3565b83516001600160a01b0316600090815260d16020908152604080832082880151845290915290819020606086015160a087015160808801519351637b5c283560e01b8152734d3a52a0e98144caf46ac226d83e8f144b5c654d94637b5c28359461399e9490939092909190600401615cb1565b60006040518083038186803b1580156139b657600080fd5b505af41580156139ca573d6000803e3d6000fd5b50505060408086015160a087015191516356d878f760e01b81526001600160a01b03851693506356d878f792613a039291600401615337565b600060405180830381600087803b158015613a1d57600080fd5b505af1158015613a31573d6000803e3d6000fd5b5050505083604001516001600160a01b031684600001516001600160a01b031685606001516001600160a01b03167fdd96b18f26fd9950581b9fd821fa907fc318845fc4d220b825a7b19bfdd174e887602001518860a00151604051612af8929190615cde565b613aa0614ccb565b60088251600a811115613aaf57fe5b14613acc5760405162461bcd60e51b815260040161054690615b2a565b60408201516001600160a01b0316613af65760405162461bcd60e51b815260040161054690615742565b506040805160608082018352838301516001600160a01b0390811683529084015116602082015260a0909201519082015290565b602081015160ca546040516302328d7360e31b81526001600160a01b03909116906311946b9890613b5f9084906004016152f7565b60206040518083038186803b158015613b7757600080fd5b505afa158015613b8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613baf9190615114565b613bcb5760405162461bcd60e51b815260040161054690615b80565b600080600080613bda8561204d565b935093509350935080421015613c025760405162461bcd60e51b815260040161054690615a29565b613c0e8383868461170c565b613c2a5760405162461bcd60e51b81526004016105469061597d565b6000613c3e87602001518860400151610797565b9050856001600160a01b03166356d878f73389604001516040518363ffffffff1660e01b8152600401613c72929190615337565b600060405180830381600087803b158015613c8c57600080fd5b505af1158015613ca0573d6000803e3d6000fd5b505060cd54895160405163fa93b2a560e01b81526001600160a01b03909216935063fa93b2a59250613cd9918991908690600401615350565b600060405180830381600087803b158015613cf357600080fd5b505af1158015613d07573d6000803e3d6000fd5b5050505086600001516001600160a01b0316336001600160a01b031688602001516001600160a01b03167f18fd144d7dbcbaa6f00fd47a84adc7dc3cc64a326ffa2dc7691a25e3837dba03888b6040015186604051613d689392919061539f565b60405180910390a450505050505050565b613d81614ccb565b60078251600a811115613d9057fe5b14613dad5760405162461bcd60e51b8152600401610546906159d4565b60208201516001600160a01b0316613dd75760405162461bcd60e51b8152600401610546906154dc565b60408201516001600160a01b0316613e015760405162461bcd60e51b815260040161054690615a9c565b604051806060016040528083602001516001600160a01b031681526020018360800151815260200183604001516001600160a01b03168152509050919050565b80513390613e4f82826149d9565b613e6183600001518460200151614a5f565b613e7d5760405162461bcd60e51b815260040161054690615725565b613e85614bb9565b6000613e9985600001518660200151610a30565b5091509150600080613eae8460000151614a8c565b90506000613ebf8560200151614a8c565b90508180613eca5750805b613ee65760405162461bcd60e51b81526004016105469061599a565b81613f09578460200151600081518110613efc57fe5b6020026020010151613f1f565b84518051600090613f1657fe5b60200260200101515b92508015613fd35760008560200151600081518110613f3a57fe5b60200260200101519050806001600160a01b03166356d878f760cd60009054906101000a90046001600160a01b03168860800151600081518110613f7a57fe5b60200260200101516040518363ffffffff1660e01b8152600401613f9f929190615337565b600060405180830381600087803b158015613fb957600080fd5b505af1158015613fcd573d6000803e3d6000fd5b50505050505b5050600080600080613fe48561204d565b93509350935093508042101561400c5760405162461bcd60e51b8152600401610546906156eb565b6140188383868461170c565b6140345760405162461bcd60e51b81526004016105469061597d565b60cc5460405163cd43fbfb60e01b815260009182916001600160a01b039091169063cd43fbfb9061406b908c908c90600401615c3b565b604080518083038186803b15801561408257600080fd5b505afa158015614096573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140ba919061517e565b91509150806140db5760405162461bcd60e51b815260040161054690615606565b60d160008d600001516001600160a01b03166001600160a01b0316815260200190815260200160002060008d6020015181526020019081526020016000206000808201600061412a9190614ceb565b614138600183016000614ceb565b614146600283016000614ceb565b614154600383016000614ceb565b614162600483016000614ceb565b614170600583016000614ceb565b505087600114156141be576001600160a01b038616600090815260d660205260409020546141a4908363ffffffff614aca16565b6001600160a01b038716600090815260d660205260409020555b60cd546040808e0151905163fa93b2a560e01b81526001600160a01b039092169163fa93b2a5916141f6918a91908790600401615350565b600060405180830381600087803b15801561421057600080fd5b505af1158015614224573d6000803e3d6000fd5b5050505060008c60200151905060008d60400151905089896001600160a01b03168f600001516001600160a01b03167f522cda7dd0677ee4c9512efd8aa92af93de64b4c2fe2f8bfe7a9234a655a9bf58488876040516142869392919061539f565b60405180910390a45050505050505050505050505050565b6142a6614d09565b600a8251600a8111156142b557fe5b146142d25760405162461bcd60e51b81526004016105469061544c565b60208201516001600160a01b03166142fc5760405162461bcd60e51b8152600401610546906155cc565b60408201516001600160a01b03166143265760405162461bcd60e51b815260040161054690615486565b8160e001515160201461434b5760405162461bcd60e51b815260040161054690615a62565b60008260e001518060200190518101906143659190615166565b90506040518060a0016040528084602001516001600160a01b0316815260200184604001516001600160a01b03168152602001846080015181526020018460a00151815260200182815250915050919050565b6143c06149af565b6143d281600001518260400151614a5f565b6143ee5760405162461bcd60e51b815260040161054690615725565b6143f6614bb9565b60008060006144128560000151866040015187608001516122b2565b9350935093509350826144375760405162461bcd60e51b815260040161054690615ab9565b60006144586305f5e100610834858960600151611c2b90919063ffffffff16565b9050600061448b8760600151876060015160008151811061447557fe5b6020026020010151614aca90919063ffffffff16565b11156144c557816144a7828760a0015160008151811061447557fe5b10156144c55760405162461bcd60e51b815260040161054690615798565b845180516000906144d257fe5b60200260200101516001600160a01b03166356d878f73388606001516040518363ffffffff1660e01b815260040161450b929190615337565b600060405180830381600087803b15801561452557600080fd5b505af1158015614539573d6000803e3d6000fd5b505087516001600160a01b0316600090815260d160209081526040808320818c01518452909152808220908901518051734d3a52a0e98144caf46ac226d83e8f144b5c654d955063e02ff74094509192909161459157fe5b60200260200101518460006040518563ffffffff1660e01b81526004016145bb9493929190615cb1565b60006040518083038186803b1580156145d357600080fd5b505af41580156145e7573d6000803e3d6000fd5b505087516001600160a01b0316600090815260d160209081526040808320818c01518452909152812088518051734d3a52a0e98144caf46ac226d83e8f144b5c654d9550637b5c283594509192909161463c57fe5b6020026020010151896060015160006040518563ffffffff1660e01b815260040161466a9493929190615cb1565b60006040518083038186803b15801561468257600080fd5b505af4158015614696573d6000803e3d6000fd5b505050506146ea8160d6600088604001516000815181106146b357fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054614aca90919063ffffffff16565b60d6600087604001516000815181106146ff57fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000208190555060cd60009054906101000a90046001600160a01b03166001600160a01b031663fa93b2a5866040015160008151811061476057fe5b60200260200101518860200151846040518463ffffffff1660e01b815260040161478c93929190615350565b600060405180830381600087803b1580156147a657600080fd5b505af11580156147ba573d6000803e3d6000fd5b5050505085600001516001600160a01b031686602001516001600160a01b0316336001600160a01b03167f93e59ec97820bb1ed9fb6ddc10619d1574e803b1f79b937414feb8f6b7051f9d868a60800151868c606001518d60400151604051614827959493929190615cec565b60405180910390a4505050505050565b61483f614d4a565b60098251600a81111561484e57fe5b1461486b5760405162461bcd60e51b8152600401610546906157ef565b60408201516001600160a01b03166148955760405162461bcd60e51b8152600401610546906159b7565b50604080518082018252908201516001600160a01b0316815260e090910151602082015290565b6148c46149af565b805160cf54600160b01b900460ff16156148fd576148e181614b0c565b6148fd5760405162461bcd60e51b815260040161054690615bf0565b815160208301516040516309c23da560e41b81526001600160a01b0390921691639c23da50916149329133919060040161530b565b600060405180830381600087803b15801561494c57600080fd5b505af1158015614960573d6000803e3d6000fd5b5050505081600001516001600160a01b0316336001600160a01b03167f8750bdaf6e88201790ee2765fea3ac73b514a52658c818723a30de91029ad000846020015160405161078b91906153e3565b60cf54600160a01b900460ff161561093d5760405162461bcd60e51b815260040161054690615ad6565b806001600160a01b0316826001600160a01b03161480614a1e57506001600160a01b03808216600090815260d2602090815260408083209386168352929052205460ff165b61193c5760405162461bcd60e51b8152600401610546906153f6565b6000828201838110156108405760405162461bcd60e51b815260040161054690615578565b600080821180156108405750506001600160a01b0391909116600090815260d06020526040902054101590565b6000808251118015610843575060006001600160a01b031682600081518110614ab157fe5b60200260200101516001600160a01b0316141592915050565b600061084083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614b8d565b60ca546040516351572a2d60e11b81526000916001600160a01b03169063a2ae545a90614b3d9085906004016152f7565b60206040518083038186803b158015614b5557600080fd5b505afa158015614b69573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108439190615114565b60008184841115614bb15760405162461bcd60e51b815260040161054691906153e3565b505050900390565b6040518060c001604052806060815260200160608152602001606081526020016060815260200160608152602001606081525090565b604080516101008101909152806000815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001606081525090565b604051806060016040528060006001600160a01b0316815260200160008152602001600081525090565b6040518060c0016040528060006001600160a01b031681526020016000815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160008152602001600081525090565b604080516060810182526000808252602082018190529181019190915290565b50805460008255906000526020600020908101906119cd9190614d62565b6040518060a0016040528060006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b60408051808201909152600081526060602082015290565b610a1e91905b80821115614d7c5760008155600101614d68565b5090565b803561084381615d36565b600082601f830112614d9b578081fd5b813567ffffffffffffffff811115614db1578182fd5b614dc4601f8201601f1916602001615d0f565b9150808252836020828501011115614ddb57600080fd5b8060208401602084013760009082016020015292915050565b8035600b811061084357600080fd5b600060208284031215614e14578081fd5b813561084081615d36565b600060208284031215614e30578081fd5b815161084081615d36565b60008060408385031215614e4d578081fd5b8235614e5881615d36565b91506020830135614e6881615d36565b809150509250929050565b60008060008060808587031215614e88578182fd5b8435614e9381615d36565b93506020850135614ea381615d36565b92506040850135614eb381615d36565b9396929550929360600135925050565b60008060008060008060c08789031215614edb578182fd5b8651614ee681615d36565b6020880151909650614ef781615d36565b6040880151909550614f0881615d36565b80945050606087015192506080870151915060a0870151614f2881615d4b565b809150509295509295509295565b60008060408385031215614f48578182fd5b8235614f5381615d36565b91506020830135614e6881615d4b565b60008060408385031215614f75578182fd5b8235614f8081615d36565b946020939093013593505050565b600080600060608486031215614fa2578283fd5b8335614fad81615d36565b95602085013595506040909401359392505050565b60006020808385031215614fd4578182fd5b823567ffffffffffffffff80821115614feb578384fd5b81850186601f820112614ffc578485fd5b803592508183111561500c578485fd5b6150198485850201615d0f565b83815284810190828601875b868110156150e9578135850161010080601f19838f03011215615046578a8bfd5b61504f81615d0f565b61505b8e8c8501614df4565b815261506a8e60408501614d80565b8b820152606061507c8f828601614d80565b604083015261508e8f60808601614d80565b818301525060a0830135608082015260c083013560a082015260e083013560c082015281830135898111156150c1578c8dfd5b6150cf8f8d83870101614d8b565b60e083015250865250509287019290870190600101615025565b50909998505050505050505050565b600060208284031215615109578081fd5b813561084081615d4b565b600060208284031215615125578081fd5b815161084081615d4b565b600080600060608486031215615144578081fd5b835161514f81615d4b565b602085015160409095015190969495509392505050565b600060208284031215615177578081fd5b5051919050565b60008060408385031215615190578182fd5b825191506020830151614e6881615d4b565b6000815180845260208085019450808401835b838110156151da5781516001600160a01b0316875295820195908201906001016151b5565b509495945050505050565b6000815180845260208085019450808401835b838110156151da578151875295820195908201906001016151f8565b60008151808452815b818110156152395760208185018101518683018201520161521d565b8181111561524a5782602083870101525b50601f01601f19169290920160200192915050565b6000815160c0845261527460c08501826151a2565b60208401519150848103602086015261528d81836151a2565b6040850151925085810360408701526152a681846151a2565b9150506060840151915084810360608601526152c281836151e5565b6080850151925085810360808701526152db81846151e5565b91505060a0840151915084810360a08601526104ea81836151e5565b6001600160a01b0391909116815260200190565b6001600160a01b038316815260406020820181905260009061532f90830184615214565b949350505050565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03948516815292841660208401529083166040830152909116606082015260800190565b6001600160a01b039390931683526020830191909152604082015260600190565b901515815260200190565b92151583526020830191909152604082015260600190565b6000602082526108406020830184615214565b602080825260029082015261219b60f11b604082015260600190565b60208082526003908201526210cc4d60ea1b604082015260600190565b60208082526003908201526204332360ec1b604082015260600190565b60208082526003908201526208262760eb1b604082015260600190565b60208082526003908201526241313160e81b604082015260600190565b60208082526003908201526204132360ec1b604082015260600190565b60208082526003908201526221991b60e91b604082015260600190565b602080825260029082015261413360f01b604082015260600190565b60208082526003908201526220989b60e91b604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b602080825260029082015261219960f11b604082015260600190565b60208082526003908201526221989b60e91b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526003908201526204331360ec1b604082015260600190565b60208082526003908201526241313960e81b604082015260600190565b60208082526003908201526243313360e81b604082015260600190565b60208082526003908201526221999960e91b604082015260600190565b602080825260029082015261413160f01b604082015260600190565b60208082526003908201526243323360e81b604082015260600190565b60208082526003908201526243323560e81b604082015260600190565b60208082526003908201526243313160e81b604082015260600190565b602080825260029082015261413760f01b604082015260600190565b602080825260029082015261209960f11b604082015260600190565b60208082526003908201526208662760eb1b604082015260600190565b60208082526003908201526243333160e81b604082015260600190565b60208082526003908201526243323160e81b604082015260600190565b60208082526003908201526243333560e81b604082015260600190565b602080825260039082015262104c4d60ea1b604082015260600190565b60208082526003908201526221999b60e91b604082015260600190565b602080825260029082015261433160f01b604082015260600190565b60208082526003908201526210cccd60ea1b604082015260600190565b60208082526003908201526243313560e81b604082015260600190565b60208082526003908201526221989960e91b604082015260600190565b60208082526003908201526220991960e91b604082015260600190565b602080825260029082015261433760f01b604082015260600190565b60208082526003908201526210cc8d60ea1b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b60208082526003908201526243333760e81b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526003908201526204131360ec1b604082015260600190565b6020808252602e908201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560408201526d195b881a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526003908201526221991960e91b604082015260600190565b60208082526003908201526220989960e91b604082015260600190565b60208082526003908201526243323960e81b604082015260600190565b60208082526003908201526204333360ec1b604082015260600190565b60208082526003908201526241323360e81b604082015260600190565b60208082526003908201526241313560e81b604082015260600190565b602080825260029082015261082760f31b604082015260600190565b602080825260029082015261413960f01b604082015260600190565b60208082526003908201526208664760eb1b604082015260600190565b602080825260029082015261209b60f11b604082015260600190565b60208082526003908201526241323160e81b604082015260600190565b60208082526003908201526243313960e81b604082015260600190565b60208082526003908201526241313760e81b604082015260600190565b60208082526003908201526243333360e81b604082015260600190565b60208082526002908201526110cd60f21b604082015260600190565b602080825260029082015261433960f01b604082015260600190565b602080825260029082015261104d60f21b604082015260600190565b60208082526003908201526241313360e81b604082015260600190565b602080825260029082015261413560f01b604082015260600190565b60208082526003908201526243313760e81b604082015260600190565b60208082526003908201526243323760e81b604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b602080825260029082015261086760f31b604082015260600190565b602080825260029082015261433360f01b604082015260600190565b602080825260029082015261433560f01b604082015260600190565b600060208252610840602083018461525f565b600060408252615c4e604083018561525f565b90508260208301529392505050565b600060608252615c70606083018661525f565b60208301949094525060400152919050565b600060808252615c95608083018761525f565b6020830195909552506040810192909252606090910152919050565b9384526001600160a01b039290921660208401526040830152606082015260800190565b90815260200190565b918252602082015260400190565b948552602085019390935260408401919091526060830152608082015260a00190565b60405181810167ffffffffffffffff81118282101715615d2e57600080fd5b604052919050565b6001600160a01b03811681146119cd57600080fd5b80151581146119cd57600080fdfea2646970667358221220a7e19740a045ca277745868a9ac88b87f050c6954895e10f38c411c53312ad6f64736f6c634300060a0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102325760003560e01c8063b617f0c611610130578063ce3e39c0116100b8578063eaa33e141161007c578063eaa33e1414610479578063eab7775b1461049b578063ef4fcafa146104a3578063f2fde38b146104b6578063f77bc88b146104c957610232565b8063ce3e39c014610418578063d66dd43e14610420578063d99d13f514610433578063e69d849d14610453578063e723406c1461046657610232565b8063c220101d116100ff578063c220101d146103c4578063c644d3a2146103d7578063caa6d21a146103ea578063cab2e805146103fd578063cdee058a1461041057610232565b8063b617f0c614610378578063b6363cf21461038b578063bc463a3d1461039e578063beca75d7146103b157610232565b80636bd50cef116101be5780638da5cb5b116101825780638da5cb5b1461032b57806393e59dc1146103335780639daafbe81461033b5780639db938911461035d5780639f677ed91461036557610232565b80636bd50cef146102f35780636c0c3b991461030b57806370dc320c14610313578063715018a61461031b5780637dc0d1d01461032357610232565b8063485cc95511610205578063485cc95514610292578063558a7297146102a5578063565eea19146102b8578063573c473e146102d857806364681083146102eb57610232565b806314b93faf1461023757806316f0115b1461026057806329729d88146102755780632eb1c3a71461027d575b600080fd5b61024a610245366004614e73565b6104dc565b60405161025791906153c0565b60405180910390f35b6102686104f3565b60405161025791906152f7565b610268610502565b61029061028b366004614f63565b610511565b005b6102906102a0366004614e3b565b6105c6565b6102906102b3366004614f36565b6106de565b6102cb6102c6366004614f63565b610797565b6040516102579190615cd5565b6102906102e63660046150f8565b610849565b610290610900565b6102fb61093f565b6040516102579493929190615374565b61024a610964565b610268610974565b610290610983565b610268610a02565b610268610a11565b610268610a21565b61034e610349366004614f63565b610a30565b60405161025793929190615c5d565b610268610cc9565b6102906103733660046150f8565b610cd8565b610290610386366004614fc2565b610d84565b61024a610399366004614e3b565b610e16565b6102906103ac366004614e03565b610e44565b6102906103bf366004614e03565b610f29565b6102cb6103d2366004614f63565b61100e565b6102cb6103e5366004614e03565b6110cf565b6102cb6103f8366004614e03565b6110ea565b61029061040b3660046150f8565b611105565b61024a6111bc565b6102686111cc565b6102cb61042e366004614e03565b6111db565b610446610441366004614f63565b6111f6565b6040516102579190615c28565b610290610461366004614f63565b611457565b61024a610474366004614e03565b611500565b61048c610487366004614f8e565b61152f565b604051610257939291906153cb565b61024a611556565b6102906104b1366004614f63565b611566565b6102906104c4366004614e03565b6115d9565b61024a6104d7366004614e03565b611690565b60006104ea8585858561170c565b95945050505050565b60cd546001600160a01b031681565b60cf546001600160a01b031681565b6105196118a1565b6065546001600160a01b0390811691161461054f5760405162461bcd60e51b8152600401610546906158a3565b60405180910390fd5b6000811161056f5760405162461bcd60e51b81526004016105469061575f565b6001600160a01b038216600081815260d5602052604090819020839055517f6ff730ba70e34bd5ca823424bd15ab869cadc6bad079b527c71bde444ad6402b906105ba908490615cd5565b60405180910390a25050565b600054610100900460ff16806105df57506105df6118a5565b806105ed575060005460ff16155b6106095760405162461bcd60e51b8152600401610546906158f5565b600054610100900460ff16158015610634576000805460ff1961ff0019909116610100171660011790555b6001600160a01b03831661065a5760405162461bcd60e51b81526004016105469061580c565b6001600160a01b0382166106805760405162461bcd60e51b815260040161054690615bd4565b610689826118ab565b610691611940565b60c980546001600160a01b0319166001600160a01b0385161790556106b46119d0565b60cf805460ff60b01b1916600160b01b17905580156106d9576000805461ff00191690555b505050565b33600090815260d2602090815260408083206001600160a01b038616845290915290205460ff16151581151514156107285760405162461bcd60e51b815260040161054690615af2565b33600081815260d2602090815260408083206001600160a01b038716808552925291829020805460ff191685151517905590519091907f1ae45540b0875932452da603b351ce2f1758258ba1345e79f8fc94f044cb07879061078b9085906153c0565b60405180910390a35050565b60cc54604051630478409360e41b8152600091610840916305f5e100916108349186916001600160a01b0316906347840930906107d8908a906004016152f7565b60206040518083038186803b1580156107f057600080fd5b505afa158015610804573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108289190615166565b9063ffffffff611c2b16565b9063ffffffff611c6516565b90505b92915050565b60ce546001600160a01b031633146108735760405162461bcd60e51b81526004016105469061553f565b60cf5460ff600160a01b90910416151581151514156108a45760405162461bcd60e51b815260040161054690615af2565b60cf805460ff60a01b1916600160a01b831515810291909117918290556040517f531c3d7229f510a8da00a0f5792686958cdd9c8a120c3c030a6053cd66b68556926108f59260ff910416906153c0565b60405180910390a150565b6109086118a1565b6065546001600160a01b039081169116146109355760405162461bcd60e51b8152600401610546906158a3565b61093d6119d0565b565b60ca5460cb5460cc5460cd546001600160a01b03938416949284169391821692911690565b60cf54600160b01b900460ff1681565b60c9546001600160a01b031681565b61098b6118a1565b6065546001600160a01b039081169116146109b85760405162461bcd60e51b8152600401610546906158a3565b6065546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3606580546001600160a01b0319169055565b60cb546001600160a01b031681565b6065546001600160a01b03165b90565b60ca546001600160a01b031681565b610a38614bb9565b6001600160a01b038316600081815260d160209081526040808320868452825280832084845260d3835281842087855283528184205494845260d483528184208785528352818420548251825460e09581028201860190945260c081018481529596879693959094929391928692849290918491840182828015610ae557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ac7575b5050505050815260200160018201805480602002602001604051908101604052809291908181526020018280548015610b4757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b29575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015610ba957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610b8b575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015610c0157602002820191906000526020600020905b815481526020019060010190808311610bed575b5050505050815260200160048201805480602002602001604051908101604052809291908181526020018280548015610c5957602002820191906000526020600020905b815481526020019060010190808311610c45575b5050505050815260200160058201805480602002602001604051908101604052809291908181526020018280548015610cb157602002820191906000526020600020905b815481526020019060010190808311610c9d575b50505050508152505092509250925092509250925092565b60ce546001600160a01b031681565b60cf546001600160a01b03163314610d025760405162461bcd60e51b81526004016105469061577c565b60cf5460ff600160a81b9091041615158115151415610d335760405162461bcd60e51b815260040161054690615af2565b60cf805460ff60a81b1916600160a81b831515810291909117918290556040517f4f1d0445688d95c99ca9fc036f551b205fd18ff26a4443b1979c16d1ba66b535926108f59260ff910416906153c0565b60975460ff16610da65760405162461bcd60e51b815260040161054690615b9d565b6097805460ff19169055610db8611ca7565b6000806000610dc684611cd1565b9250925092508215610e0357610ddc8282611f87565b6001600160a01b038216600090815260d46020908152604080832084845290915290204290555b50506097805460ff191660011790555050565b6001600160a01b03918216600090815260d26020908152604080832093909416825291909152205460ff1690565b610e4c6118a1565b6065546001600160a01b03908116911614610e795760405162461bcd60e51b8152600401610546906158a3565b6001600160a01b038116610e9f5760405162461bcd60e51b815260040161054690615679565b60ce546001600160a01b0382811691161415610ecd5760405162461bcd60e51b815260040161054690615af2565b60ce546040516001600160a01b038084169216907f1440312dbc326ddc21bfa95078324bf5aaf6899e8a27cba3057c60adfc84e40b90600090a360ce80546001600160a01b0319166001600160a01b0392909216919091179055565b610f316118a1565b6065546001600160a01b03908116911614610f5e5760405162461bcd60e51b8152600401610546906158a3565b6001600160a01b038116610f845760405162461bcd60e51b8152600401610546906155af565b60cf546001600160a01b0382811691161415610fb25760405162461bcd60e51b815260040161054690615af2565b60cf546040516001600160a01b038084169216907f44f3e9e7b454118e9fcb2e3026396f57ca21d7bd7dcabd31d7f986806422f4df90600090a360cf80546001600160a01b0319166001600160a01b0392909216919091179055565b6000611018614bb9565b60006110248585610a30565b5060cc5460405163cd43fbfb60e01b815292945090925060009182916001600160a01b03169063cd43fbfb906110609087908790600401615c3b565b604080518083038186803b15801561107757600080fd5b505afa15801561108b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110af919061517e565b91509150806110c5576000945050505050610843565b5095945050505050565b6001600160a01b0316600090815260d5602052604090205490565b6001600160a01b0316600090815260d0602052604090205490565b61110d6118a1565b6065546001600160a01b0390811691161461113a5760405162461bcd60e51b8152600401610546906158a3565b60cf5460ff600160b01b909104161515811515141561116b5760405162461bcd60e51b815260040161054690615af2565b60cf805460ff60b01b1916600160b01b831515810291909117918290556040517f26d614575a4c104c181c87003d4bb00cc7ade00d5b47bf8775171c12a376b255926108f59260ff910416906153c0565b60cf54600160a01b900460ff1681565b60cc546001600160a01b031681565b6001600160a01b0316600090815260d6602052604090205490565b6111fe614bb9565b6001600160a01b038316600090815260d1602090815260408083208584528252918290208251815460e09381028201840190945260c08101848152909391928492849184018282801561127a57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161125c575b50505050508152602001600182018054806020026020016040519081016040528092919081815260200182805480156112dc57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116112be575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801561133e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611320575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561139657602002820191906000526020600020905b815481526020019060010190808311611382575b50505050508152602001600482018054806020026020016040519081016040528092919081815260200182805480156113ee57602002820191906000526020600020905b8154815260200190600101908083116113da575b505050505081526020016005820180548060200260200160405190810160405280929190818152602001828054801561144657602002820191906000526020600020905b815481526020019060010190808311611432575b505050505081525050905092915050565b60cd5460405163dd2c99f760e01b81526001600160a01b039091169063dd2c99f79061148b90859033908690600401615350565b600060405180830381600087803b1580156114a557600080fd5b505af11580156114b9573d6000803e3d6000fd5b50505050816001600160a01b0316336001600160a01b03167f4dfff917e1fbb261a082e98cc7d43029621f6a6eb05ff3fef1510d5f1eb4857c8360405161078b9190615cd5565b60008060008060006115118661204d565b93509350935093506115258484848461170c565b9695505050505050565b6000806000806000806115438989896122b2565b919c909b50909950975050505050505050565b60cf54600160a81b900460ff1681565b60975460ff166115885760405162461bcd60e51b815260040161054690615b9d565b6097805460ff1916905561159a611ca7565b6115a48282611f87565b6001600160a01b03909116600090815260d460209081526040808320938352929052204290556097805460ff19166001179055565b6115e16118a1565b6065546001600160a01b0390811691161461160e5760405162461bcd60e51b8152600401610546906158a3565b6001600160a01b0381166116345760405162461bcd60e51b8152600401610546906154f9565b6065546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b6000816001600160a01b031663ade6e2aa6040518163ffffffff1660e01b815260040160206040518083038186803b1580156116cb57600080fd5b505afa1580156116df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117039190615166565b42101592915050565b60cb54604051635fdc714960e01b81526000916001600160a01b031690635fdc71499061173f9088908690600401615337565b60206040518083038186803b15801561175757600080fd5b505afa15801561176b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061178f9190615114565b8015611818575060cb54604051635fdc714960e01b81526001600160a01b0390911690635fdc7149906117c89087908690600401615337565b60206040518083038186803b1580156117e057600080fd5b505afa1580156117f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118189190615114565b80156104ea575060cb54604051635fdc714960e01b81526001600160a01b0390911690635fdc7149906118519086908690600401615337565b60206040518083038186803b15801561186957600080fd5b505afa15801561187d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ea9190615114565b3390565b303b1590565b600054610100900460ff16806118c457506118c46118a5565b806118d2575060005460ff16155b6118ee5760405162461bcd60e51b8152600401610546906158f5565b600054610100900460ff16158015611919576000805460ff1961ff0019909116610100171660011790555b61192161238d565b61192a8261240f565b801561193c576000805461ff00191690555b5050565b600054610100900460ff168061195957506119596118a5565b80611967575060005460ff16155b6119835760405162461bcd60e51b8152600401610546906158f5565b600054610100900460ff161580156119ae576000805460ff1961ff0019909116610100171660011790555b6097805460ff1916600117905580156119cd576000805461ff00191690555b50565b60c960009054906101000a90046001600160a01b03166001600160a01b031663d01f63f56040518163ffffffff1660e01b815260040160206040518083038186803b158015611a1e57600080fd5b505afa158015611a32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a569190614e1f565b60ca80546001600160a01b0319166001600160a01b0392831617905560c9546040805163419d8fe760e11b81529051919092169163833b1fce916004808301926020929190829003018186803b158015611aaf57600080fd5b505afa158015611ac3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae79190614e1f565b60cb80546001600160a01b0319166001600160a01b0392831617905560c9546040805163cf28493f60e01b81529051919092169163cf28493f916004808301926020929190829003018186803b158015611b4057600080fd5b505afa158015611b54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b789190614e1f565b60cc80546001600160a01b0319166001600160a01b0392831617905560c95460408051633aa431a160e11b8152905191909216916375486342916004808301926020929190829003018186803b158015611bd157600080fd5b505afa158015611be5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c099190614e1f565b60cd80546001600160a01b0319166001600160a01b0392909216919091179055565b600082611c3a57506000610843565b82820282848281611c4757fe5b04146108405760405162461bcd60e51b815260040161054690615845565b600061084083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506124db565b60cf54600160a81b900460ff161561093d5760405162461bcd60e51b815260040161054690615c0c565b60008080808080805b8751811015611f7b57611ceb614bef565b888281518110611cf757fe5b60209081029190910101518051909150600781600a811115611d1557fe5b14158015611d2f5750600881600a811115611d2c57fe5b14155b8015611d475750600a81600a811115611d4457fe5b14155b8015611d5f5750600981600a811115611d5c57fe5b14155b15611dd5578315611dc25781602001516001600160a01b0316866001600160a01b031614611d9f5760405162461bcd60e51b8152600401610546906157d2565b81608001518514611dc25760405162461bcd60e51b8152600401610546906155e9565b6001935081608001519450816020015195505b600081600a811115611de357fe5b1415611dff57611dfa611df583612512565b6125ea565b611f71565b600381600a811115611e0d57fe5b1415611e2457611dfa611e1f836126d9565b6127b5565b600481600a811115611e3257fe5b1415611e4957611dfa611e4483612b06565b612ba5565b600581600a811115611e5757fe5b1415611e6e57611dfa611e69836126d9565b612df9565b600681600a811115611e7c57fe5b1415611e9357611dfa611e8e83612b06565b613157565b600181600a811115611ea157fe5b1415611eb857611dfa611eb38361345b565b6134b9565b600281600a811115611ec657fe5b1415611edd57611dfa611ed8836137a1565b6137ff565b600881600a811115611eeb57fe5b1415611f0257611dfa611efd83613a98565b613b2a565b600781600a811115611f1057fe5b1415611f2757611dfa611f2283613d79565b613e41565b600a81600a811115611f3557fe5b1415611f4c57611dfa611f478361429e565b6143b8565b600981600a811115611f5a57fe5b1415611f7157611f71611f6c83614837565b6148bc565b5050600101611cda565b50969195509350915050565b611f8f614bb9565b6000611f9b8484610a30565b5060cc5460405163cd43fbfb60e01b81529294509092506000916001600160a01b039091169063cd43fbfb90611fd79086908690600401615c3b565b604080518083038186803b158015611fee57600080fd5b505afa158015612002573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612026919061517e565b915050806120465760405162461bcd60e51b815260040161054690615412565b5050505050565b6000806000806000859050806001600160a01b031663af0968fc6040518163ffffffff1660e01b815260040160c06040518083038186803b15801561209157600080fd5b505afa9250505080156120c1575060408051601f3d908101601f191682019092526120be91810190614ec3565b60015b61229757806001600160a01b031663aabaecd66040518163ffffffff1660e01b815260040160206040518083038186803b1580156120fe57600080fd5b505afa158015612112573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121369190614e1f565b816001600160a01b0316637158da7c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561216f57600080fd5b505afa158015612183573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a79190614e1f565b826001600160a01b03166317d69bc86040518163ffffffff1660e01b815260040160206040518083038186803b1580156121e057600080fd5b505afa1580156121f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122189190614e1f565b836001600160a01b031663ade6e2aa6040518163ffffffff1660e01b815260040160206040518083038186803b15801561225157600080fd5b505afa158015612265573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122899190615166565b9450945094509450506122ab565b5093985091965094509092506122ab915050565b9193509193565b6122ba614bb9565b60008060006122c7614bb9565b6000806122d48a8a610a30565b925092509250600080600060cc60009054906101000a90046001600160a01b03166001600160a01b031663a6c569078787878f6040518563ffffffff1660e01b81526004016123269493929190615c82565b60606040518083038186803b15801561233e57600080fd5b505afa158015612352573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123769190615130565b979f919e509c50959a509498505050505050505050565b600054610100900460ff16806123a657506123a66118a5565b806123b4575060005460ff16155b6123d05760405162461bcd60e51b8152600401610546906158f5565b600054610100900460ff161580156123fb576000805460ff1961ff0019909116610100171660011790555b80156119cd576000805461ff001916905550565b600054610100900460ff168061242857506124286118a5565b80612436575060005460ff16155b6124525760405162461bcd60e51b8152600401610546906158f5565b600054610100900460ff1615801561247d576000805460ff1961ff0019909116610100171660011790555b606580546001600160a01b0319166001600160a01b0384169081179091556040516000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3801561193c576000805461ff00191690555050565b600081836124fc5760405162461bcd60e51b815260040161054691906153e3565b50600083858161250857fe5b0495945050505050565b61251a614c50565b60008251600a81111561252957fe5b146125465760405162461bcd60e51b815260040161054690615623565b60208201516001600160a01b03166125705760405162461bcd60e51b8152600401610546906156b2565b60008260e00151516020141561259b578260e001518060200190518101906125989190615166565b90505b600281106125bb5760405162461bcd60e51b8152600401610546906154c0565b604080516060810182526020808601516001600160a01b03168252608090950151948101949094528301525090565b6125f26149af565b8051339061260082826149d9565b82516001600160a01b0316600090815260d0602052604081205461262b90600163ffffffff614a3a16565b9050808460200151146126505760405162461bcd60e51b8152600401610546906157b5565b83516001600160a01b03908116600090815260d060209081526040808320859055808801805189518616855260d384528285208786529093529281902091909155905186519151909291909116907f5d66689e2c864b4f21efd3988c0ce5dc8a197981b68e81ce73660e92394fe25f906126cb908590615cd5565b60405180910390a350505050565b6126e1614c7a565b60038251600a8111156126f057fe5b1480612708575060058251600a81111561270657fe5b145b6127245760405162461bcd60e51b8152600401610546906159f1565b60208201516001600160a01b031661274e5760405162461bcd60e51b815260040161054690615a0d565b6040518060c0016040528083602001516001600160a01b031681526020018360800151815260200183604001516001600160a01b0316815260200183606001516001600160a01b031681526020018360c0015181526020018360a001518152509050919050565b6127bd6149af565b805133906127cb82826149d9565b6127dd83600001518460200151614a5f565b6127f95760405162461bcd60e51b815260040161054690615725565b60408301516001600160a01b031633148061282d575082600001516001600160a01b031683604001516001600160a01b0316145b6128495760405162461bcd60e51b81526004016105469061555b565b60ca5460608401516040516302328d7360e31b81526001600160a01b03909216916311946b989161287c916004016152f7565b60206040518083038186803b15801561289457600080fd5b505afa1580156128a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128cc9190615114565b6128e85760405162461bcd60e51b815260040161054690615b63565b600083606001519050806001600160a01b031663ade6e2aa6040518163ffffffff1660e01b815260040160206040518083038186803b15801561292a57600080fd5b505afa15801561293e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129629190615166565b42106129805760405162461bcd60e51b8152600401610546906156ce565b83516001600160a01b0316600090815260d16020908152604080832082880151845290915290819020606086015160a08701516080880151935163155bf27360e31b8152734d3a52a0e98144caf46ac226d83e8f144b5c654d9463aadf9398946129f39490939092909190600401615cb1565b60006040518083038186803b158015612a0b57600080fd5b505af4158015612a1f573d6000803e3d6000fd5b505060cd54606087015160408089015160a08a0151915163dd2c99f760e01b81526001600160a01b03909416955063dd2c99f79450612a6393909190600401615350565b600060405180830381600087803b158015612a7d57600080fd5b505af1158015612a91573d6000803e3d6000fd5b5050505083604001516001600160a01b031684600001516001600160a01b031685606001516001600160a01b03167f2607e210004cef0ad6b3e6aedb778bffb03c1586f8dcf55d49afffde210d8bb187602001518860a00151604051612af8929190615cde565b60405180910390a450505050565b612b0e614c7a565b60048251600a811115612b1d57fe5b1480612b35575060068251600a811115612b3357fe5b145b612b515760405162461bcd60e51b8152600401610546906158d8565b60208201516001600160a01b0316612b7b5760405162461bcd60e51b815260040161054690615469565b60408201516001600160a01b031661274e5760405162461bcd60e51b815260040161054690615960565b612bad6149af565b80513390612bbb82826149d9565b612bcd83600001518460200151614a5f565b612be95760405162461bcd60e51b815260040161054690615725565b600083606001519050806001600160a01b031663ade6e2aa6040518163ffffffff1660e01b815260040160206040518083038186803b158015612c2b57600080fd5b505afa158015612c3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c639190615166565b4210612c815760405162461bcd60e51b815260040161054690615a7f565b83516001600160a01b0316600090815260d16020908152604080832082880151845290915290819020606086015160a08701516080880151935163951dd8d360e01b8152734d3a52a0e98144caf46ac226d83e8f144b5c654d9463951dd8d394612cf49490939092909190600401615cb1565b60006040518083038186803b158015612d0c57600080fd5b505af4158015612d20573d6000803e3d6000fd5b505060cd54606087015160408089015160a08a0151915163fa93b2a560e01b81526001600160a01b03909416955063fa93b2a59450612d6493909190600401615350565b600060405180830381600087803b158015612d7e57600080fd5b505af1158015612d92573d6000803e3d6000fd5b5050505083604001516001600160a01b031684600001516001600160a01b031685606001516001600160a01b03167fbd023c53d293da163d185720d4274f4ddabc09d5304491a55abb296cc811d9fa87602001518860a00151604051612af8929190615cde565b612e016149af565b80513390612e0f82826149d9565b612e2183600001518460200151614a5f565b612e3d5760405162461bcd60e51b815260040161054690615725565b60408301516001600160a01b0316331480612e71575082600001516001600160a01b031683604001516001600160a01b0316145b612e8d5760405162461bcd60e51b81526004016105469061542f565b60ca54606084015160405163f9839d8960e01b81526001600160a01b039092169163f9839d8991612ec0916004016152f7565b60206040518083038186803b158015612ed857600080fd5b505afa158015612eec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f109190615114565b612f2c5760405162461bcd60e51b815260040161054690615708565b6000612f4084600001518560200151610a30565b509150508060011415612fdf5760a084015160608501516001600160a01b0316600090815260d66020526040902054612f7e9163ffffffff614a3a16565b6060850180516001600160a01b03908116600090815260d6602081815260408084209690965584518416835260d58152858320549451909316825290915291909120541115612fdf5760405162461bcd60e51b815260040161054690615886565b83516001600160a01b0316600090815260d16020908152604080832082880151845290915290819020606086015160a0870151608088015193516301f974ab60e61b8152734d3a52a0e98144caf46ac226d83e8f144b5c654d94637e5d2ac0946130529490939092909190600401615cb1565b60006040518083038186803b15801561306a57600080fd5b505af415801561307e573d6000803e3d6000fd5b505060cd54606087015160408089015160a08a0151915163dd2c99f760e01b81526001600160a01b03909416955063dd2c99f794506130c293909190600401615350565b600060405180830381600087803b1580156130dc57600080fd5b505af11580156130f0573d6000803e3d6000fd5b5050505083604001516001600160a01b031684600001516001600160a01b031685606001516001600160a01b03167fbfab88b861f171b7db714f00e5966131253918d55ddba816c3eb94657d10239087602001518860a00151604051612af8929190615cde565b61315f6149af565b8051339061316d82826149d9565b61317f83600001518460200151614a5f565b61319b5760405162461bcd60e51b815260040161054690615725565b6131a3614bb9565b60006131b785600001518660200151610a30565b50915091506131c98260000151614a8c565b1561327c57600082600001516000815181106131e157fe5b60200260200101519050806001600160a01b031663ade6e2aa6040518163ffffffff1660e01b815260040160206040518083038186803b15801561322457600080fd5b505afa158015613238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061325c9190615166565b421061327a5760405162461bcd60e51b815260040161054690615943565b505b80600114156132d45760a085015160608601516001600160a01b0316600090815260d660205260409020546132b69163ffffffff614aca16565b60608601516001600160a01b0316600090815260d660205260409020555b84516001600160a01b0316600090815260d16020908152604080832082890151845290915290819020606087015160a088015160808901519351630380bfdd60e61b8152734d3a52a0e98144caf46ac226d83e8f144b5c654d9463e02ff740946133479490939092909190600401615cb1565b60006040518083038186803b15801561335f57600080fd5b505af4158015613373573d6000803e3d6000fd5b505060cd5460608801516040808a015160a08b0151915163fa93b2a560e01b81526001600160a01b03909416955063fa93b2a594506133b793909190600401615350565b600060405180830381600087803b1580156133d157600080fd5b505af11580156133e5573d6000803e3d6000fd5b5050505084604001516001600160a01b031685600001516001600160a01b031686606001516001600160a01b03167ffe86f7694b6c54a528acbe27be61dd4a85e9a89aeef7f650a1b439045ccee5a488602001518960a0015160405161344c929190615cde565b60405180910390a45050505050565b613463614c7a565b60018251600a81111561347257fe5b1461348f5760405162461bcd60e51b815260040161054690615b0e565b60208201516001600160a01b031661274e5760405162461bcd60e51b815260040161054690615b47565b6134c16149af565b805133906134cf82826149d9565b6134e183600001518460200151614a5f565b6134fd5760405162461bcd60e51b815260040161054690615725565b60ca5460608401516040516302328d7360e31b81526001600160a01b03909216916311946b9891613530916004016152f7565b60206040518083038186803b15801561354857600080fd5b505afa15801561355c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135809190615114565b61359c5760405162461bcd60e51b81526004016105469061563f565b600083606001519050806001600160a01b031663ade6e2aa6040518163ffffffff1660e01b815260040160206040518083038186803b1580156135de57600080fd5b505afa1580156135f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136169190615166565b42106136345760405162461bcd60e51b815260040161054690615828565b83516001600160a01b0316600090815260d16020908152604080832082880151845290915290819020606086015160a08701516080880151935163ef682c1b60e01b8152734d3a52a0e98144caf46ac226d83e8f144b5c654d9463ef682c1b946136a79490939092909190600401615cb1565b60006040518083038186803b1580156136bf57600080fd5b505af41580156136d3573d6000803e3d6000fd5b50505060408086015160a0870151915163051b0a4160e41b81526001600160a01b03851693506351b0a4109261370c9291600401615337565b600060405180830381600087803b15801561372657600080fd5b505af115801561373a573d6000803e3d6000fd5b5050505083604001516001600160a01b031684600001516001600160a01b031685606001516001600160a01b03167f4d7f96086c92b2f9a254ad21548b1c1f2d99502c7949508866349b96bb1a8d8a87602001518860a00151604051612af8929190615cde565b6137a9614c7a565b60028251600a8111156137b857fe5b146137d55760405162461bcd60e51b815260040161054690615a46565b60208201516001600160a01b031661274e5760405162461bcd60e51b815260040161054690615696565b6138076149af565b8051339061381582826149d9565b61382783600001518460200151614a5f565b6138435760405162461bcd60e51b815260040161054690615725565b60408301516001600160a01b0316331480613877575082600001516001600160a01b031683604001516001600160a01b0316145b6138935760405162461bcd60e51b81526004016105469061565c565b600083606001519050806001600160a01b031663ade6e2aa6040518163ffffffff1660e01b815260040160206040518083038186803b1580156138d557600080fd5b505afa1580156138e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061390d9190615166565b421061392b5760405162461bcd60e51b8152600401610546906154a3565b83516001600160a01b0316600090815260d16020908152604080832082880151845290915290819020606086015160a087015160808801519351637b5c283560e01b8152734d3a52a0e98144caf46ac226d83e8f144b5c654d94637b5c28359461399e9490939092909190600401615cb1565b60006040518083038186803b1580156139b657600080fd5b505af41580156139ca573d6000803e3d6000fd5b50505060408086015160a087015191516356d878f760e01b81526001600160a01b03851693506356d878f792613a039291600401615337565b600060405180830381600087803b158015613a1d57600080fd5b505af1158015613a31573d6000803e3d6000fd5b5050505083604001516001600160a01b031684600001516001600160a01b031685606001516001600160a01b03167fdd96b18f26fd9950581b9fd821fa907fc318845fc4d220b825a7b19bfdd174e887602001518860a00151604051612af8929190615cde565b613aa0614ccb565b60088251600a811115613aaf57fe5b14613acc5760405162461bcd60e51b815260040161054690615b2a565b60408201516001600160a01b0316613af65760405162461bcd60e51b815260040161054690615742565b506040805160608082018352838301516001600160a01b0390811683529084015116602082015260a0909201519082015290565b602081015160ca546040516302328d7360e31b81526001600160a01b03909116906311946b9890613b5f9084906004016152f7565b60206040518083038186803b158015613b7757600080fd5b505afa158015613b8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613baf9190615114565b613bcb5760405162461bcd60e51b815260040161054690615b80565b600080600080613bda8561204d565b935093509350935080421015613c025760405162461bcd60e51b815260040161054690615a29565b613c0e8383868461170c565b613c2a5760405162461bcd60e51b81526004016105469061597d565b6000613c3e87602001518860400151610797565b9050856001600160a01b03166356d878f73389604001516040518363ffffffff1660e01b8152600401613c72929190615337565b600060405180830381600087803b158015613c8c57600080fd5b505af1158015613ca0573d6000803e3d6000fd5b505060cd54895160405163fa93b2a560e01b81526001600160a01b03909216935063fa93b2a59250613cd9918991908690600401615350565b600060405180830381600087803b158015613cf357600080fd5b505af1158015613d07573d6000803e3d6000fd5b5050505086600001516001600160a01b0316336001600160a01b031688602001516001600160a01b03167f18fd144d7dbcbaa6f00fd47a84adc7dc3cc64a326ffa2dc7691a25e3837dba03888b6040015186604051613d689392919061539f565b60405180910390a450505050505050565b613d81614ccb565b60078251600a811115613d9057fe5b14613dad5760405162461bcd60e51b8152600401610546906159d4565b60208201516001600160a01b0316613dd75760405162461bcd60e51b8152600401610546906154dc565b60408201516001600160a01b0316613e015760405162461bcd60e51b815260040161054690615a9c565b604051806060016040528083602001516001600160a01b031681526020018360800151815260200183604001516001600160a01b03168152509050919050565b80513390613e4f82826149d9565b613e6183600001518460200151614a5f565b613e7d5760405162461bcd60e51b815260040161054690615725565b613e85614bb9565b6000613e9985600001518660200151610a30565b5091509150600080613eae8460000151614a8c565b90506000613ebf8560200151614a8c565b90508180613eca5750805b613ee65760405162461bcd60e51b81526004016105469061599a565b81613f09578460200151600081518110613efc57fe5b6020026020010151613f1f565b84518051600090613f1657fe5b60200260200101515b92508015613fd35760008560200151600081518110613f3a57fe5b60200260200101519050806001600160a01b03166356d878f760cd60009054906101000a90046001600160a01b03168860800151600081518110613f7a57fe5b60200260200101516040518363ffffffff1660e01b8152600401613f9f929190615337565b600060405180830381600087803b158015613fb957600080fd5b505af1158015613fcd573d6000803e3d6000fd5b50505050505b5050600080600080613fe48561204d565b93509350935093508042101561400c5760405162461bcd60e51b8152600401610546906156eb565b6140188383868461170c565b6140345760405162461bcd60e51b81526004016105469061597d565b60cc5460405163cd43fbfb60e01b815260009182916001600160a01b039091169063cd43fbfb9061406b908c908c90600401615c3b565b604080518083038186803b15801561408257600080fd5b505afa158015614096573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140ba919061517e565b91509150806140db5760405162461bcd60e51b815260040161054690615606565b60d160008d600001516001600160a01b03166001600160a01b0316815260200190815260200160002060008d6020015181526020019081526020016000206000808201600061412a9190614ceb565b614138600183016000614ceb565b614146600283016000614ceb565b614154600383016000614ceb565b614162600483016000614ceb565b614170600583016000614ceb565b505087600114156141be576001600160a01b038616600090815260d660205260409020546141a4908363ffffffff614aca16565b6001600160a01b038716600090815260d660205260409020555b60cd546040808e0151905163fa93b2a560e01b81526001600160a01b039092169163fa93b2a5916141f6918a91908790600401615350565b600060405180830381600087803b15801561421057600080fd5b505af1158015614224573d6000803e3d6000fd5b5050505060008c60200151905060008d60400151905089896001600160a01b03168f600001516001600160a01b03167f522cda7dd0677ee4c9512efd8aa92af93de64b4c2fe2f8bfe7a9234a655a9bf58488876040516142869392919061539f565b60405180910390a45050505050505050505050505050565b6142a6614d09565b600a8251600a8111156142b557fe5b146142d25760405162461bcd60e51b81526004016105469061544c565b60208201516001600160a01b03166142fc5760405162461bcd60e51b8152600401610546906155cc565b60408201516001600160a01b03166143265760405162461bcd60e51b815260040161054690615486565b8160e001515160201461434b5760405162461bcd60e51b815260040161054690615a62565b60008260e001518060200190518101906143659190615166565b90506040518060a0016040528084602001516001600160a01b0316815260200184604001516001600160a01b03168152602001846080015181526020018460a00151815260200182815250915050919050565b6143c06149af565b6143d281600001518260400151614a5f565b6143ee5760405162461bcd60e51b815260040161054690615725565b6143f6614bb9565b60008060006144128560000151866040015187608001516122b2565b9350935093509350826144375760405162461bcd60e51b815260040161054690615ab9565b60006144586305f5e100610834858960600151611c2b90919063ffffffff16565b9050600061448b8760600151876060015160008151811061447557fe5b6020026020010151614aca90919063ffffffff16565b11156144c557816144a7828760a0015160008151811061447557fe5b10156144c55760405162461bcd60e51b815260040161054690615798565b845180516000906144d257fe5b60200260200101516001600160a01b03166356d878f73388606001516040518363ffffffff1660e01b815260040161450b929190615337565b600060405180830381600087803b15801561452557600080fd5b505af1158015614539573d6000803e3d6000fd5b505087516001600160a01b0316600090815260d160209081526040808320818c01518452909152808220908901518051734d3a52a0e98144caf46ac226d83e8f144b5c654d955063e02ff74094509192909161459157fe5b60200260200101518460006040518563ffffffff1660e01b81526004016145bb9493929190615cb1565b60006040518083038186803b1580156145d357600080fd5b505af41580156145e7573d6000803e3d6000fd5b505087516001600160a01b0316600090815260d160209081526040808320818c01518452909152812088518051734d3a52a0e98144caf46ac226d83e8f144b5c654d9550637b5c283594509192909161463c57fe5b6020026020010151896060015160006040518563ffffffff1660e01b815260040161466a9493929190615cb1565b60006040518083038186803b15801561468257600080fd5b505af4158015614696573d6000803e3d6000fd5b505050506146ea8160d6600088604001516000815181106146b357fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054614aca90919063ffffffff16565b60d6600087604001516000815181106146ff57fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000208190555060cd60009054906101000a90046001600160a01b03166001600160a01b031663fa93b2a5866040015160008151811061476057fe5b60200260200101518860200151846040518463ffffffff1660e01b815260040161478c93929190615350565b600060405180830381600087803b1580156147a657600080fd5b505af11580156147ba573d6000803e3d6000fd5b5050505085600001516001600160a01b031686602001516001600160a01b0316336001600160a01b03167f93e59ec97820bb1ed9fb6ddc10619d1574e803b1f79b937414feb8f6b7051f9d868a60800151868c606001518d60400151604051614827959493929190615cec565b60405180910390a4505050505050565b61483f614d4a565b60098251600a81111561484e57fe5b1461486b5760405162461bcd60e51b8152600401610546906157ef565b60408201516001600160a01b03166148955760405162461bcd60e51b8152600401610546906159b7565b50604080518082018252908201516001600160a01b0316815260e090910151602082015290565b6148c46149af565b805160cf54600160b01b900460ff16156148fd576148e181614b0c565b6148fd5760405162461bcd60e51b815260040161054690615bf0565b815160208301516040516309c23da560e41b81526001600160a01b0390921691639c23da50916149329133919060040161530b565b600060405180830381600087803b15801561494c57600080fd5b505af1158015614960573d6000803e3d6000fd5b5050505081600001516001600160a01b0316336001600160a01b03167f8750bdaf6e88201790ee2765fea3ac73b514a52658c818723a30de91029ad000846020015160405161078b91906153e3565b60cf54600160a01b900460ff161561093d5760405162461bcd60e51b815260040161054690615ad6565b806001600160a01b0316826001600160a01b03161480614a1e57506001600160a01b03808216600090815260d2602090815260408083209386168352929052205460ff165b61193c5760405162461bcd60e51b8152600401610546906153f6565b6000828201838110156108405760405162461bcd60e51b815260040161054690615578565b600080821180156108405750506001600160a01b0391909116600090815260d06020526040902054101590565b6000808251118015610843575060006001600160a01b031682600081518110614ab157fe5b60200260200101516001600160a01b0316141592915050565b600061084083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614b8d565b60ca546040516351572a2d60e11b81526000916001600160a01b03169063a2ae545a90614b3d9085906004016152f7565b60206040518083038186803b158015614b5557600080fd5b505afa158015614b69573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108439190615114565b60008184841115614bb15760405162461bcd60e51b815260040161054691906153e3565b505050900390565b6040518060c001604052806060815260200160608152602001606081526020016060815260200160608152602001606081525090565b604080516101008101909152806000815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001606081525090565b604051806060016040528060006001600160a01b0316815260200160008152602001600081525090565b6040518060c0016040528060006001600160a01b031681526020016000815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160008152602001600081525090565b604080516060810182526000808252602082018190529181019190915290565b50805460008255906000526020600020908101906119cd9190614d62565b6040518060a0016040528060006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b60408051808201909152600081526060602082015290565b610a1e91905b80821115614d7c5760008155600101614d68565b5090565b803561084381615d36565b600082601f830112614d9b578081fd5b813567ffffffffffffffff811115614db1578182fd5b614dc4601f8201601f1916602001615d0f565b9150808252836020828501011115614ddb57600080fd5b8060208401602084013760009082016020015292915050565b8035600b811061084357600080fd5b600060208284031215614e14578081fd5b813561084081615d36565b600060208284031215614e30578081fd5b815161084081615d36565b60008060408385031215614e4d578081fd5b8235614e5881615d36565b91506020830135614e6881615d36565b809150509250929050565b60008060008060808587031215614e88578182fd5b8435614e9381615d36565b93506020850135614ea381615d36565b92506040850135614eb381615d36565b9396929550929360600135925050565b60008060008060008060c08789031215614edb578182fd5b8651614ee681615d36565b6020880151909650614ef781615d36565b6040880151909550614f0881615d36565b80945050606087015192506080870151915060a0870151614f2881615d4b565b809150509295509295509295565b60008060408385031215614f48578182fd5b8235614f5381615d36565b91506020830135614e6881615d4b565b60008060408385031215614f75578182fd5b8235614f8081615d36565b946020939093013593505050565b600080600060608486031215614fa2578283fd5b8335614fad81615d36565b95602085013595506040909401359392505050565b60006020808385031215614fd4578182fd5b823567ffffffffffffffff80821115614feb578384fd5b81850186601f820112614ffc578485fd5b803592508183111561500c578485fd5b6150198485850201615d0f565b83815284810190828601875b868110156150e9578135850161010080601f19838f03011215615046578a8bfd5b61504f81615d0f565b61505b8e8c8501614df4565b815261506a8e60408501614d80565b8b820152606061507c8f828601614d80565b604083015261508e8f60808601614d80565b818301525060a0830135608082015260c083013560a082015260e083013560c082015281830135898111156150c1578c8dfd5b6150cf8f8d83870101614d8b565b60e083015250865250509287019290870190600101615025565b50909998505050505050505050565b600060208284031215615109578081fd5b813561084081615d4b565b600060208284031215615125578081fd5b815161084081615d4b565b600080600060608486031215615144578081fd5b835161514f81615d4b565b602085015160409095015190969495509392505050565b600060208284031215615177578081fd5b5051919050565b60008060408385031215615190578182fd5b825191506020830151614e6881615d4b565b6000815180845260208085019450808401835b838110156151da5781516001600160a01b0316875295820195908201906001016151b5565b509495945050505050565b6000815180845260208085019450808401835b838110156151da578151875295820195908201906001016151f8565b60008151808452815b818110156152395760208185018101518683018201520161521d565b8181111561524a5782602083870101525b50601f01601f19169290920160200192915050565b6000815160c0845261527460c08501826151a2565b60208401519150848103602086015261528d81836151a2565b6040850151925085810360408701526152a681846151a2565b9150506060840151915084810360608601526152c281836151e5565b6080850151925085810360808701526152db81846151e5565b91505060a0840151915084810360a08601526104ea81836151e5565b6001600160a01b0391909116815260200190565b6001600160a01b038316815260406020820181905260009061532f90830184615214565b949350505050565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03948516815292841660208401529083166040830152909116606082015260800190565b6001600160a01b039390931683526020830191909152604082015260600190565b901515815260200190565b92151583526020830191909152604082015260600190565b6000602082526108406020830184615214565b602080825260029082015261219b60f11b604082015260600190565b60208082526003908201526210cc4d60ea1b604082015260600190565b60208082526003908201526204332360ec1b604082015260600190565b60208082526003908201526208262760eb1b604082015260600190565b60208082526003908201526241313160e81b604082015260600190565b60208082526003908201526204132360ec1b604082015260600190565b60208082526003908201526221991b60e91b604082015260600190565b602080825260029082015261413360f01b604082015260600190565b60208082526003908201526220989b60e91b604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b602080825260029082015261219960f11b604082015260600190565b60208082526003908201526221989b60e91b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526003908201526204331360ec1b604082015260600190565b60208082526003908201526241313960e81b604082015260600190565b60208082526003908201526243313360e81b604082015260600190565b60208082526003908201526221999960e91b604082015260600190565b602080825260029082015261413160f01b604082015260600190565b60208082526003908201526243323360e81b604082015260600190565b60208082526003908201526243323560e81b604082015260600190565b60208082526003908201526243313160e81b604082015260600190565b602080825260029082015261413760f01b604082015260600190565b602080825260029082015261209960f11b604082015260600190565b60208082526003908201526208662760eb1b604082015260600190565b60208082526003908201526243333160e81b604082015260600190565b60208082526003908201526243323160e81b604082015260600190565b60208082526003908201526243333560e81b604082015260600190565b602080825260039082015262104c4d60ea1b604082015260600190565b60208082526003908201526221999b60e91b604082015260600190565b602080825260029082015261433160f01b604082015260600190565b60208082526003908201526210cccd60ea1b604082015260600190565b60208082526003908201526243313560e81b604082015260600190565b60208082526003908201526221989960e91b604082015260600190565b60208082526003908201526220991960e91b604082015260600190565b602080825260029082015261433760f01b604082015260600190565b60208082526003908201526210cc8d60ea1b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b60208082526003908201526243333760e81b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526003908201526204131360ec1b604082015260600190565b6020808252602e908201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560408201526d195b881a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526003908201526221991960e91b604082015260600190565b60208082526003908201526220989960e91b604082015260600190565b60208082526003908201526243323960e81b604082015260600190565b60208082526003908201526204333360ec1b604082015260600190565b60208082526003908201526241323360e81b604082015260600190565b60208082526003908201526241313560e81b604082015260600190565b602080825260029082015261082760f31b604082015260600190565b602080825260029082015261413960f01b604082015260600190565b60208082526003908201526208664760eb1b604082015260600190565b602080825260029082015261209b60f11b604082015260600190565b60208082526003908201526241323160e81b604082015260600190565b60208082526003908201526243313960e81b604082015260600190565b60208082526003908201526241313760e81b604082015260600190565b60208082526003908201526243333360e81b604082015260600190565b60208082526002908201526110cd60f21b604082015260600190565b602080825260029082015261433960f01b604082015260600190565b602080825260029082015261104d60f21b604082015260600190565b60208082526003908201526241313360e81b604082015260600190565b602080825260029082015261413560f01b604082015260600190565b60208082526003908201526243313760e81b604082015260600190565b60208082526003908201526243323760e81b604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b602080825260029082015261086760f31b604082015260600190565b602080825260029082015261433360f01b604082015260600190565b602080825260029082015261433560f01b604082015260600190565b600060208252610840602083018461525f565b600060408252615c4e604083018561525f565b90508260208301529392505050565b600060608252615c70606083018661525f565b60208301949094525060400152919050565b600060808252615c95608083018761525f565b6020830195909552506040810192909252606090910152919050565b9384526001600160a01b039290921660208401526040830152606082015260800190565b90815260200190565b918252602082015260400190565b948552602085019390935260408401919091526060830152608082015260a00190565b60405181810167ffffffffffffffff81118282101715615d2e57600080fd5b604052919050565b6001600160a01b03811681146119cd57600080fd5b80151581146119cd57600080fdfea2646970667358221220a7e19740a045ca277745868a9ac88b87f050c6954895e10f38c411c53312ad6f64736f6c634300060a0033
Deployed Bytecode Sourcemap
46247:43399:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64951:259;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;46594:31;;;:::i;:::-;;;;;;;;47023:25;;;:::i;59770:211::-;;;;;;;;;:::i;:::-;;55213:395;;;;;;;;;:::i;59007:283::-;;;;;;;;;:::i;63824:176::-;;;;;;;;;:::i;:::-;;;;;;;;56337:274;;;;;;;;;:::i;59406:94::-;;;:::i;61789:281::-;;;:::i;:::-;;;;;;;;;;;47376:26;;;:::i;46420:39::-;;;:::i;5484:148::-;;;:::i;46508:29::-;;;:::i;4842:79::-;;;:::i;46466:35::-;;;:::i;66520:328::-;;;;;;;;;:::i;:::-;;;;;;;;;;46873:28;;;:::i;56885:239::-;;;;;;;;;:::i;60189:343::-;;;;;;;;;:::i;61326:138::-;;;;;;;;;:::i;57768:297::-;;;;;;;;;:::i;57308:267::-;;;;;;;;;:::i;62379:359::-;;;;;;;;;:::i;67000:111::-;;;;;;;;;:::i;65391:147::-;;;;;;;;;:::i;58367:223::-;;;;;;;;;:::i;47152:33::-;;;:::i;46544:43::-;;;:::i;67297:127::-;;;;;;;;;:::i;66077:153::-;;;;;;;;;:::i;:::-;;;;;;;;55859:179;;;;;;;;;:::i;64253:269::-;;;;;;;;;:::i;63124:401::-;;;;;;;;;:::i;:::-;;;;;;;;;;47254:29;;;:::i;60850:191::-;;;;;;;;;:::i;5787:244::-;;;;;;;;;:::i;65710:141::-;;;;;;;;;:::i;64951:259::-;65118:4;65142:60;65159:11;65172:7;65181:11;65194:7;65142:16;:60::i;:::-;65135:67;64951:259;-1:-1:-1;;;;;64951:259:0:o;46594:31::-;;;-1:-1:-1;;;;;46594:31:0;;:::o;47023:25::-;;;-1:-1:-1;;;;;47023:25:0;;:::o;59770:211::-;5064:12;:10;:12::i;:::-;5054:6;;-1:-1:-1;;;;;5054:6:0;;;:22;;;5046:67;;;;-1:-1:-1;;;5046:67:0;;;;;;;;;;;;;;;;;59871:1:::1;59864:4;:8;59856:24;;;;-1:-1:-1::0;;;59856:24:0::1;;;;;;;;;-1:-1:-1::0;;;;;59893:21:0;::::1;;::::0;;;:8:::1;:21;::::0;;;;;;:28;;;59939:34;::::1;::::0;::::1;::::0;59917:4;;59939:34:::1;;;;;;;;;;59770:211:::0;;:::o;55213:395::-;1225:12;;;;;;;;:31;;;1241:15;:13;:15::i;:::-;1225:47;;;-1:-1:-1;1261:11:0;;;;1260:12;1225:47;1217:106;;;;-1:-1:-1;;;1217:106:0;;;;;;;;;1336:19;1359:12;;;;;;1358:13;1382:99;;;;1417:12;:19;;-1:-1:-1;;;;1417:19:0;;;;;1451:18;1432:4;1451:18;;;1382:99;-1:-1:-1;;;;;55311:26:0;::::1;55303:41;;;;-1:-1:-1::0;;;55303:41:0::1;;;;;;;;;-1:-1:-1::0;;;;;55363:20:0;::::1;55355:35;;;;-1:-1:-1::0;;;55355:35:0::1;;;;;;;;;55403:22;55418:6;55403:14;:22::i;:::-;55436:34;:32;:34::i;:::-;55483:11;:48:::0;;-1:-1:-1;;;;;;55483:48:0::1;-1:-1:-1::0;;;;;55483:48:0;::::1;;::::0;;55542:24:::1;:22;:24::i;:::-;55579:14;:21:::0;;-1:-1:-1;;;;55579:21:0::1;-1:-1:-1::0;;;55579:21:0::1;::::0;;1507:67;;;;1557:5;1542:20;;-1:-1:-1;;1542:20:0;;;1507:67;55213:395;;;:::o;59007:283::-;59103:10;59093:21;;;;:9;:21;;;;;;;;-1:-1:-1;;;;;59093:32:0;;;;;;;;;;;;:47;;;;;;;59085:62;;;;-1:-1:-1;;;59085:62:0;;;;;;;;;59170:10;59160:21;;;;:9;:21;;;;;;;;-1:-1:-1;;;;;59160:32:0;;;;;;;;;;;:46;;-1:-1:-1;;59160:46:0;;;;;;;59224:58;;59160:32;;59170:10;59224:58;;;;59160:46;;59224:58;;;;;;;;;;59007:283;;:::o;63824:176::-;63925:10;;:40;;-1:-1:-1;;;63925:40:0;;63898:7;;63925:67;;63983:8;;63925:53;;63970:7;;-1:-1:-1;;;;;63925:10:0;;:31;;:40;;63957:7;;63925:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:44;:53;:44;:53;:::i;:::-;:57;:67;:57;:67;:::i;:::-;63918:74;;63824:176;;;;;:::o;56337:274::-;53611:13;;-1:-1:-1;;;;;53611:13:0;53597:10;:27;53589:42;;;;-1:-1:-1;;;53589:42:0;;;;;;;;;56440:21:::1;::::0;::::1;-1:-1:-1::0;;;56440:21:0;;::::1;;:41;;::::0;::::1;;;;56432:56;;;;-1:-1:-1::0;;;56432:56:0::1;;;;;;;;;56501:21;:40:::0;;-1:-1:-1;;;;56501:40:0::1;-1:-1:-1::0;;;56501:40:0;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;;56559:44:::1;::::0;::::1;::::0;::::1;::::0;56501:40:::1;56581:21:::0;::::1;;::::0;56559:44:::1;;;;;;;;;;56337:274:::0;:::o;59406:94::-;5064:12;:10;:12::i;:::-;5054:6;;-1:-1:-1;;;;;5054:6:0;;;:22;;;5046:67;;;;-1:-1:-1;;;5046:67:0;;;;;;;;;59468:24:::1;:22;:24::i;:::-;59406:94::o:0;61789:281::-;61998:9;;62018:6;;62035:10;;62056:4;;-1:-1:-1;;;;;61998:9:0;;;;62018:6;;;;62035:10;;;;62056:4;;;61789:281::o;47376:26::-;;;-1:-1:-1;;;47376:26:0;;;;;:::o;46420:39::-;;;-1:-1:-1;;;;;46420:39:0;;:::o;5484:148::-;5064:12;:10;:12::i;:::-;5054:6;;-1:-1:-1;;;;;5054:6:0;;;:22;;;5046:67;;;;-1:-1:-1;;;5046:67:0;;;;;;;;;5575:6:::1;::::0;5554:40:::1;::::0;5591:1:::1;::::0;-1:-1:-1;;;;;5575:6:0::1;::::0;5554:40:::1;::::0;5591:1;;5554:40:::1;5605:6;:19:::0;;-1:-1:-1;;;;;;5605:19:0::1;::::0;;5484:148::o;46508:29::-;;;-1:-1:-1;;;;;46508:29:0;;:::o;4842:79::-;4907:6;;-1:-1:-1;;;;;4907:6:0;4842:79;;:::o;46466:35::-;;;-1:-1:-1;;;;;46466:35:0;;:::o;66520:328::-;66645:24;;:::i;:::-;-1:-1:-1;;;;;66749:14:0;;66684:7;66749:14;;;:6;:14;;;;;;;;:24;;;;;;;;66775:17;;;:9;:17;;;;;:27;;;;;;;;;66804:25;;;:17;:25;;;;;:35;;;;;;;;;66741:99;;;;;;;;;;;;;;;;;;;;;66684:7;;;;66749:24;;66775:27;;66804:35;;66741:99;;66749:24;;66741:99;;;;66749:24;;66741:99;;66749:24;66741:99;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;66741:99:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;66741:99:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;66741:99:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66520:328;;;;;:::o;46873:28::-;;;-1:-1:-1;;;;;46873:28:0;;:::o;56885:239::-;53409:10;;-1:-1:-1;;;;;53409:10:0;53395;:24;53387:39;;;;-1:-1:-1;;;53387:39:0;;;;;;;;;56977:17:::1;::::0;::::1;-1:-1:-1::0;;;56977:17:0;;::::1;;:33;;::::0;::::1;;;;56969:48;;;;-1:-1:-1::0;;;56969:48:0::1;;;;;;;;;57030:17;:32:::0;;-1:-1:-1;;;;57030:32:0::1;-1:-1:-1::0;;;57030:32:0;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;;57080:36:::1;::::0;::::1;::::0;::::1;::::0;57030:32:::1;57098:17:::0;::::1;;::::0;57080:36:::1;;60189:343:::0;8147:11;;;;8139:55;;;;-1:-1:-1;;;8139:55:0;;;;;;;;;8272:11;:19;;-1:-1:-1;;8272:19:0;;;53215::::1;:17;:19::i;:::-;60293:17:::2;60312:18:::0;60332:15:::2;60351:21;60363:8;60351:11;:21::i;:::-;60292:80;;;;;;60387:12;60383:142;;;60416:38;60434:10;60446:7;60416:17;:38::i;:::-;-1:-1:-1::0;;;;;60469:29:0;::::2;;::::0;;;:17:::2;:29;::::0;;;;;;;:38;;;;;;;;60510:3:::2;60469:44:::0;;60383:142:::2;-1:-1:-1::0;;8452:11:0;:18;;-1:-1:-1;;8452:18:0;8466:4;8452:18;;;-1:-1:-1;;60189:343:0:o;61326:138::-;-1:-1:-1;;;;;61428:17:0;;;61404:4;61428:17;;;:9;:17;;;;;;;;:28;;;;;;;;;;;;;;;61326:138::o;57768:297::-;5064:12;:10;:12::i;:::-;5054:6;;-1:-1:-1;;;;;5054:6:0;;;:22;;;5046:67;;;;-1:-1:-1;;;5046:67:0;;;;;;;;;-1:-1:-1;;;;;57856:28:0;::::1;57848:44;;;;-1:-1:-1::0;;;57848:44:0::1;;;;;;;;;57911:13;::::0;-1:-1:-1;;;;;57911:31:0;;::::1;:13:::0;::::1;:31;;57903:46;;;;-1:-1:-1::0;;;57903:46:0::1;;;;;;;;;57986:13;::::0;57965:51:::1;::::0;-1:-1:-1;;;;;57965:51:0;;::::1;::::0;57986:13:::1;::::0;57965:51:::1;::::0;57986:13:::1;::::0;57965:51:::1;58027:13;:30:::0;;-1:-1:-1;;;;;;58027:30:0::1;-1:-1:-1::0;;;;;58027:30:0;;;::::1;::::0;;;::::1;::::0;;57768:297::o;57308:267::-;5064:12;:10;:12::i;:::-;5054:6;;-1:-1:-1;;;;;5054:6:0;;;:22;;;5046:67;;;;-1:-1:-1;;;5046:67:0;;;;;;;;;-1:-1:-1;;;;;57390:25:0;::::1;57382:41;;;;-1:-1:-1::0;;;57382:41:0::1;;;;;;;;;57442:10;::::0;-1:-1:-1;;;;;57442:25:0;;::::1;:10:::0;::::1;:25;;57434:40;;;;-1:-1:-1::0;;;57434:40:0::1;;;;;;;;;57508:10;::::0;57490:42:::1;::::0;-1:-1:-1;;;;;57490:42:0;;::::1;::::0;57508:10:::1;::::0;57490:42:::1;::::0;57508:10:::1;::::0;57490:42:::1;57543:10;:24:::0;;-1:-1:-1;;;;;;57543:24:0::1;-1:-1:-1::0;;;;;57543:24:0;;;::::1;::::0;;;::::1;::::0;;57308:267::o;62379:359::-;62456:7;62477:30;;:::i;:::-;62509:17;62532:37;62552:6;62560:8;62532:19;:37::i;:::-;-1:-1:-1;62618:10:0;;:48;;-1:-1:-1;;;62618:48:0;;62476:93;;-1:-1:-1;62476:93:0;;-1:-1:-1;62583:16:0;;;;-1:-1:-1;;;;;62618:10:0;;:30;;:48;;62476:93;;;;62618:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62582:84;;;;62684:8;62679:23;;62701:1;62694:8;;;;;;;;62679:23;-1:-1:-1;62722:8:0;62379:359;-1:-1:-1;;;;;62379:359:0:o;67000:111::-;-1:-1:-1;;;;;67087:16:0;67060:7;67087:16;;;:8;:16;;;;;;;67000:111::o;65391:147::-;-1:-1:-1;;;;;65496:34:0;65469:7;65496:34;;;:19;:34;;;;;;;65391:147::o;58367:223::-;5064:12;:10;:12::i;:::-;5054:6;;-1:-1:-1;;;;;5054:6:0;;;:22;;;5046:67;;;;-1:-1:-1;;;5046:67:0;;;;;;;;;58453:14:::1;::::0;::::1;-1:-1:-1::0;;;58453:14:0;;::::1;;:31;;::::0;::::1;;;;58445:46;;;;-1:-1:-1::0;;;58445:46:0::1;;;;;;;;;58504:14;:30:::0;;-1:-1:-1;;;;58504:30:0::1;-1:-1:-1::0;;;58504:30:0;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;;58552::::1;::::0;::::1;::::0;::::1;::::0;58504::::1;58567:14:::0;::::1;;::::0;58552:30:::1;;47152:33:::0;;;-1:-1:-1;;;47152:33:0;;;;;:::o;46544:43::-;;;-1:-1:-1;;;;;46544:43:0;;:::o;67297:127::-;-1:-1:-1;;;;;67392:24:0;67365:7;67392:24;;;:16;:24;;;;;;;67297:127::o;66077:153::-;66152:24;;:::i;:::-;-1:-1:-1;;;;;66197:14:0;;;;;;:6;:14;;;;;;;;:24;;;;;;;;;66189:33;;;;;;;;;;;;;;;;;;;;;;;66197:24;;66189:33;;66197:24;;66189:33;;66197:24;66189:33;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;66189:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;66189:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;66189:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66077:153;;;;:::o;55859:179::-;55928:4;;:48;;-1:-1:-1;;;55928:48:0;;-1:-1:-1;;;;;55928:4:0;;;;:19;;:48;;55948:6;;55956:10;;55968:7;;55928:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56014:6;-1:-1:-1;;;;;55994:36:0;56002:10;-1:-1:-1;;;;;55994:36:0;;56022:7;55994:36;;;;;;;64253:269;64322:4;64340:18;64360:14;64376:18;64396:14;64414:26;64432:7;64414:17;:26::i;:::-;64339:101;;;;;;;;64458:56;64475:10;64487:6;64495:10;64507:6;64458:16;:56::i;:::-;64451:63;64253:269;-1:-1:-1;;;;;;64253:269:0:o;63124:401::-;63298:4;63317:7;63339;63377:18;63397:13;63412:12;63428:43;63444:6;63452:8;63462;63428:15;:43::i;:::-;63374:97;;;;-1:-1:-1;63374:97:0;;-1:-1:-1;63124:401:0;-1:-1:-1;;;;;;;;63124:401:0:o;47254:29::-;;;-1:-1:-1;;;47254:29:0;;;;;:::o;60850:191::-;8147:11;;;;8139:55;;;;-1:-1:-1;;;8139:55:0;;;;;;;;;8272:11;:19;;-1:-1:-1;;8272:19:0;;;53215::::1;:17;:19::i;:::-;60946:35:::2;60964:6;60972:8;60946:17;:35::i;:::-;-1:-1:-1::0;;;;;60992:25:0;;::::2;;::::0;;;:17:::2;:25;::::0;;;;;;;:35;;;;;;;61030:3:::2;60992:41:::0;;8452:11;:18;;-1:-1:-1;;8452:18:0;8466:4;8452:18;;;60850:191::o;5787:244::-;5064:12;:10;:12::i;:::-;5054:6;;-1:-1:-1;;;;;5054:6:0;;;:22;;;5046:67;;;;-1:-1:-1;;;5046:67:0;;;;;;;;;-1:-1:-1;;;;;5876:22:0;::::1;5868:73;;;;-1:-1:-1::0;;;5868:73:0::1;;;;;;;;;5978:6;::::0;5957:38:::1;::::0;-1:-1:-1;;;;;5957:38:0;;::::1;::::0;5978:6:::1;::::0;5957:38:::1;::::0;5978:6:::1;::::0;5957:38:::1;6006:6;:17:::0;;-1:-1:-1;;;;;;6006:17:0::1;-1:-1:-1::0;;;;;6006:17:0;;;::::1;::::0;;;::::1;::::0;;5787:244::o;65710:141::-;65770:4;65817:7;-1:-1:-1;;;;;65801:40:0;;:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65794:3;:49;;;65710:141;-1:-1:-1;;65710:141:0:o;88834:387::-;89039:6;;:48;;-1:-1:-1;;;89039:48:0;;89002:4;;-1:-1:-1;;;;;89039:6:0;;:26;;:48;;89066:11;;89079:7;;89039:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:109;;;;-1:-1:-1;89104:6:0;;:44;;-1:-1:-1;;;89104:44:0;;-1:-1:-1;;;;;89104:6:0;;;;:26;;:44;;89131:7;;89140;;89104:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89039:174;;;;-1:-1:-1;89165:6:0;;:48;;-1:-1:-1;;;89165:48:0;;-1:-1:-1;;;;;89165:6:0;;;;:26;;:48;;89192:11;;89205:7;;89165:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3175:106;3263:10;3175:106;:::o;1674:568::-;2115:4;2182:17;2227:7;1674:568;:::o;4438:151::-;1225:12;;;;;;;;:31;;;1241:15;:13;:15::i;:::-;1225:47;;;-1:-1:-1;1261:11:0;;;;1260:12;1225:47;1217:106;;;;-1:-1:-1;;;1217:106:0;;;;;;;;;1336:19;1359:12;;;;;;1358:13;1382:99;;;;1417:12;:19;;-1:-1:-1;;;;1417:19:0;;;;;1451:18;1432:4;1451:18;;;1382:99;4511:26:::1;:24;:26::i;:::-;4548:33;4573:7;4548:24;:33::i;:::-;1511:14:::0;1507:67;;;1557:5;1542:20;;-1:-1:-1;;1542:20:0;;;1507:67;4438:151;;:::o;7128:520::-;1225:12;;;;;;;;:31;;;1241:15;:13;:15::i;:::-;1225:47;;;-1:-1:-1;1261:11:0;;;;1260:12;1225:47;1217:106;;;;-1:-1:-1;;;1217:106:0;;;;;;;;;1336:19;1359:12;;;;;;1358:13;1382:99;;;;1417:12;:19;;-1:-1:-1;;;;1417:19:0;;;;;1451:18;1432:4;1451:18;;;1382:99;7622:11:::1;:18:::0;;-1:-1:-1;;7622:18:0::1;7636:4;7622:18;::::0;;1507:67;;;;1557:5;1542:20;;-1:-1:-1;;1542:20:0;;;1507:67;7128:520;:::o;89313:330::-;89398:11;;;;;;;;;-1:-1:-1;;;;;89398:11:0;-1:-1:-1;;;;;89398:24:0;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89367:9;:58;;-1:-1:-1;;;;;;89367:58:0;-1:-1:-1;;;;;89367:58:0;;;;;;89461:11;;:23;;;-1:-1:-1;;;89461:23:0;;;;:11;;;;;:21;;:23;;;;;;;;;;;;;;:11;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89436:6;:49;;-1:-1:-1;;;;;;89436:49:0;-1:-1:-1;;;;;89436:49:0;;;;;;89535:11;;:33;;;-1:-1:-1;;;89535:33:0;;;;:11;;;;;:31;;:33;;;;;;;;;;;;;;:11;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89496:10;:73;;-1:-1:-1;;;;;;89496:73:0;-1:-1:-1;;;;;89496:73:0;;;;;;89607:11;;:27;;;-1:-1:-1;;;89607:27:0;;;;:11;;;;;:25;;:27;;;;;;;;;;;;;;:11;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89580:4;:55;;-1:-1:-1;;;;;;89580:55:0;-1:-1:-1;;;;;89580:55:0;;;;;;;;;;89313:330::o;10762:471::-;10820:7;11065:6;11061:47;;-1:-1:-1;11095:1:0;11088:8;;11061:47;11132:5;;;11136:1;11132;:5;:1;11156:5;;;;;:10;11148:56;;;;-1:-1:-1;;;11148:56:0;;;;;;;;11701:132;11759:7;11786:39;11790:1;11793;11786:39;;;;;;;;;;;;;;;;;:3;:39::i;54612:95::-;54675:17;;-1:-1:-1;;;54675:17:0;;;;54674:18;54666:33;;;;-1:-1:-1;;;54666:33:0;;;;;;;;67973:2958;68082:4;;;;;;;68243:2626;68267:8;:15;68263:1;:19;68243:2626;;;68304:32;;:::i;:::-;68339:8;68348:1;68339:11;;;;;;;;;;;;;;;;;;68397:17;;68339:11;;-1:-1:-1;68626:30:0;68612:10;:44;;;;;;;;;;68611:108;;;;-1:-1:-1;68693:25:0;68679:10;:39;;;;;;;;;;68611:108;:173;;;;-1:-1:-1;68755:28:0;68741:10;:42;;;;;;;;;;68611:173;:233;;;;-1:-1:-1;68820:23:0;68806:10;:37;;;;;;;;;;68611:233;68589:727;;;69013:12;69009:167;;;69072:6;:12;;;-1:-1:-1;;;;;69058:26:0;:10;-1:-1:-1;;;;;69058:26:0;;69050:42;;;;-1:-1:-1;;;69050:42:0;;;;;;;;;69134:6;:14;;;69123:7;:25;69115:41;;;;-1:-1:-1;;;69115:41:0;;;;;;;;;69209:4;69194:19;;69242:6;:14;;;69232:24;;69288:6;:12;;;69275:25;;68589:727;69350:28;69336:10;:42;;;;;;;;;69332:1526;;;69399:47;69410:35;69438:6;69410:27;:35::i;:::-;69399:10;:47::i;:::-;69332:1526;;;69486:36;69472:10;:50;;;;;;;;;69468:1390;;;69543:47;69556:33;69582:6;69556:25;:33::i;:::-;69543:12;:47::i;69468:1390::-;69630:37;69616:10;:51;;;;;;;;;69612:1246;;;69688:49;69702:34;69729:6;69702:26;:34::i;:::-;69688:13;:49::i;69612:1246::-;69777:36;69763:10;:50;;;;;;;;;69759:1099;;;69834:53;69853:33;69879:6;69853:25;:33::i;:::-;69834:18;:53::i;69759:1099::-;69927:37;69913:10;:51;;;;;;;;;69909:949;;;69985:55;70005:34;70032:6;70005:26;:34::i;:::-;69985:19;:55::i;69909:949::-;70080:34;70066:10;:48;;;;;;;;;70062:796;;;70135:43;70147:30;70170:6;70147:22;:30::i;:::-;70135:11;:43::i;70062:796::-;70218:34;70204:10;:48;;;;;;;;;70200:658;;;70273:43;70285:30;70308:6;70285:22;:30::i;:::-;70273:11;:43::i;70200:658::-;70356:25;70342:10;:39;;;;;;;;;70338:520;;;70402:41;70410:32;70435:6;70410:24;:32::i;:::-;70402:7;:41::i;70338:520::-;70483:30;70469:10;:44;;;;;;;;;70465:393;;;70534:51;70547:37;70577:6;70547:29;:37::i;:::-;70534:12;:51::i;70465:393::-;70625:28;70611:10;:42;;;;;;;;;70607:251;;;70674:47;70685:35;70713:6;70685:27;:35::i;:::-;70674:10;:47::i;70607:251::-;70761:23;70747:10;:37;;;;;;;;;70743:115;;;70805:37;70811:30;70834:6;70811:22;:30::i;:::-;70805:5;:37::i;:::-;-1:-1:-1;;68284:3:0;;68243:2626;;;-1:-1:-1;70889:12:0;70903:10;;-1:-1:-1;70903:10:0;-1:-1:-1;67973:2958:0;-1:-1:-1;;67973:2958:0:o;71126:311::-;71213:30;;:::i;:::-;71245:17;71268:37;71288:6;71296:8;71268:19;:37::i;:::-;-1:-1:-1;71340:10:0;;:48;;-1:-1:-1;;;71340:48:0;;71212:93;;-1:-1:-1;71212:93:0;;-1:-1:-1;71319:17:0;;-1:-1:-1;;;;;71340:10:0;;;;:30;;:48;;71212:93;;;;71340:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71316:72;;;71409:12;71401:28;;;;-1:-1:-1;;;71401:28:0;;;;;;;;;71126:311;;;;;:::o;87778:706::-;87886:7;87908;87930;87952;87987:22;88028:7;87987:49;;88051:6;-1:-1:-1;;;;;88051:23:0;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;88051:25:0;;;;;;;;-1:-1:-1;;88051:25:0;;;;;;;;;;;;;;;;88047:430;;88366:6;-1:-1:-1;;;;;88366:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88392:6;-1:-1:-1;;;;;88392:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88418:6;-1:-1:-1;;;;;88418:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88440:6;-1:-1:-1;;;;;88440:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88358:107;;;;;;;;;;;88047:430;-1:-1:-1;88285:10:0;;-1:-1:-1;88297:10:0;;-1:-1:-1;88309:6:0;-1:-1:-1;88317:6:0;;-1:-1:-1;88277:47:0;;-1:-1:-1;;88277:47:0;87778:706;;;;;;:::o;86960:734::-;87135:24;;:::i;:::-;87174:4;87193:7;87215;87251:30;;:::i;:::-;87283:17;87302:29;87335:74;87369:6;87390:8;87335:19;:74::i;:::-;87250:159;;;;;;87421:18;87441:13;87456:22;87482:10;;;;;;;;;-1:-1:-1;;;;;87482:10:0;-1:-1:-1;;;;;87482:25:0;;87522:5;87542:9;87566:21;87602:8;87482:139;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87642:5;;87420:201;;-1:-1:-1;87420:201:0;-1:-1:-1;87642:5:0;;-1:-1:-1;86960:734:0;;-1:-1:-1;;;;;;;;;86960:734:0:o;3108:59::-;1225:12;;;;;;;;:31;;;1241:15;:13;:15::i;:::-;1225:47;;;-1:-1:-1;1261:11:0;;;;1260:12;1225:47;1217:106;;;;-1:-1:-1;;;1217:106:0;;;;;;;;;1336:19;1359:12;;;;;;1358:13;1382:99;;;;1417:12;:19;;-1:-1:-1;;;;1417:19:0;;;;;1451:18;1432:4;1451:18;;;1382:99;1511:14;1507:67;;;1557:5;1542:20;;-1:-1:-1;;1542:20:0;;;3108:59;:::o;4597:164::-;1225:12;;;;;;;;:31;;;1241:15;:13;:15::i;:::-;1225:47;;;-1:-1:-1;1261:11:0;;;;1260:12;1225:47;1217:106;;;;-1:-1:-1;;;1217:106:0;;;;;;;;;1336:19;1359:12;;;;;;1358:13;1382:99;;;;1417:12;:19;;-1:-1:-1;;;;1417:19:0;;;;;1451:18;1432:4;1451:18;;;1382:99;4680:6:::1;:16:::0;;-1:-1:-1;;;;;;4680:16:0::1;-1:-1:-1::0;;;;;4680:16:0;::::1;::::0;;::::1;::::0;;;4712:41:::1;::::0;-1:-1:-1;;4712:41:0::1;::::0;-1:-1:-1;;4712:41:0::1;1511:14:::0;1507:67;;;1557:5;1542:20;;-1:-1:-1;;1542:20:0;;;4597:164;;:::o;12321:379::-;12441:7;12543:12;12536:5;12528:28;;;;-1:-1:-1;;;12528:28:0;;;;;;;;;;;12567:9;12583:1;12579;:5;;;;;;;12321:379;-1:-1:-1;;;;;12321:379:0:o;30422:678::-;30499:20;;:::i;:::-;30560;30540:16;;:40;;;;;;;;;30532:55;;;;-1:-1:-1;;;30532:55:0;;;;;;;;;30606:11;;;;-1:-1:-1;;;;;30606:25:0;30598:40;;;;-1:-1:-1;;;30598:40:0;;;;;;;;;30723:17;30757:5;:10;;;:17;30778:2;30757:23;30753:151;;;30870:5;:10;;;30859:33;;;;;;;;;;;;;;30847:45;;30753:151;30983:1;30971:9;:13;30963:28;;;;-1:-1:-1;;;30963:28:0;;;;;;;;;31011:81;;;;;;;;31033:11;;;;;-1:-1:-1;;;;;31011:81:0;;;31055:13;;;;;31011:81;;;;;;;;;;-1:-1:-1;31011:81:0;30422:678::o;71688:496::-;53006:23;:21;:23::i;:::-;71826:11;;71814:10:::1;::::0;53944:37:::1;71814:10:::0;71826:11;53944:13:::1;:37::i;:::-;71893:11:::0;;-1:-1:-1;;;;;71873:32:0::2;71855:15;71873:32:::0;;;:19:::2;:32;::::0;;;;;:39:::2;::::0;71910:1:::2;71873:39;:36;:39;:::i;:::-;71855:57;;71950:7;71933:5;:13;;;:24;71925:40;;;;-1:-1:-1::0;;;71925:40:0::2;;;;;;;;;72026:11:::0;;-1:-1:-1;;;;;72006:32:0;;::::2;;::::0;;;:19:::2;:32;::::0;;;;;;;:42;;;72093:15;;::::2;::::0;;72069:11;;72059:22;::::2;::::0;;:9:::2;:22:::0;;;;;:31;;;;;;;;;;:49;;;;72160:15;;72138:11;;72126:50;;72160:15;;72126:50;;;::::2;::::0;::::2;::::0;::::2;::::0;72041:7;;72126:50:::2;;;;;;;;;;53994:1;53042::::1;;71688:496:::0;:::o;32789:617::-;32864:18;;:::i;:::-;32938:28;32918:16;;:48;;;;;;;;;32917:104;;;-1:-1:-1;32992:28:0;32972:16;;:48;;;;;;;;;32917:104;32895:156;;;;-1:-1:-1;;;32895:156:0;;;;;;;;;33070:11;;;;-1:-1:-1;;;;;33070:25:0;33062:40;;;;-1:-1:-1;;;33062:40:0;;;;;;;;;33135:263;;;;;;;;33173:5;:11;;;-1:-1:-1;;;;;33135:263:0;;;;;33212:5;:13;;;33135:263;;;;33250:5;:19;;;-1:-1:-1;;;;;33135:263:0;;;;;33295:5;:11;;;-1:-1:-1;;;;;33135:263:0;;;;;33332:5;:11;;;33135:263;;;;33370:5;:12;;;33135:263;;;33115:283;;32789:617;;;:::o;72442:858::-;53006:23;:21;:23::i;:::-;72580:11;;72568:10:::1;::::0;53944:37:::1;72568:10:::0;72580:11;53944:13:::1;:37::i;:::-;72617:41:::2;72631:5;:11;;;72644:5;:13;;;72617;:41::i;:::-;72609:57;;;;-1:-1:-1::0;;;72609:57:0::2;;;;;;;;;72762:10;::::0;::::2;::::0;-1:-1:-1;;;;;72762:24:0::2;72776:10;72762:24;::::0;72761:57:::2;;;72806:5;:11;;;-1:-1:-1::0;;;;;72792:25:0::2;:5;:10;;;-1:-1:-1::0;;;;;72792:25:0::2;;72761:57;72753:73;;;;-1:-1:-1::0;;;72753:73:0::2;;;;;;;;;72847:9;::::0;72877:11:::2;::::0;::::2;::::0;72847:42:::2;::::0;-1:-1:-1;;;72847:42:0;;-1:-1:-1;;;;;72847:9:0;;::::2;::::0;:29:::2;::::0;:42:::2;::::0;::::2;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72839:58;;;;-1:-1:-1::0;;;72839:58:0::2;;;;;;;;;72910:22;72951:5;:11;;;72910:53;;72990:6;-1:-1:-1::0;;;;;72990:22:0::2;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72984:3;:30;72976:46;;;;-1:-1:-1::0;;;72976:46:0::2;;;;;;;;;73042:11:::0;;-1:-1:-1;;;;;73035:19:0::2;;::::0;;;:6:::2;:19;::::0;;;;;;;73055:13;;::::2;::::0;73035:34;;;;;;;;;73078:11:::2;::::0;::::2;::::0;73091:12:::2;::::0;::::2;::::0;73105:11:::2;::::0;::::2;::::0;73035:82;;-1:-1:-1;;;73035:82:0;;:42:::2;::::0;::::2;::::0;:82:::2;::::0;:34;;73078:11;;73091:12;;73105:11;73035:82:::2;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;73130:4:0::2;::::0;73150:11:::2;::::0;::::2;::::0;73163:10:::2;::::0;;::::2;::::0;73175:12:::2;::::0;::::2;::::0;73130:58;;-1:-1:-1;;;73130:58:0;;-1:-1:-1;;;;;73130:4:0;;::::2;::::0;-1:-1:-1;73130:19:0::2;::::0;-1:-1:-1;73130:58:0::2;::::0;73163:10;;73175:12;73130:58:::2;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;73252:5;:10;;;-1:-1:-1::0;;;;;73206:86:0::2;73239:5;:11;;;-1:-1:-1::0;;;;;73206:86:0::2;73226:5;:11;;;-1:-1:-1::0;;;;;73206:86:0::2;;73264:5;:13;;;73279:5;:12;;;73206:86;;;;;;;;;;;;;;;;53994:1;53042::::1;;72442:858:::0;:::o;33633:682::-;33709:19;;:::i;:::-;33784:29;33764:16;;:49;;;;;;;;;33763:106;;;-1:-1:-1;33839:29:0;33819:16;;:49;;;;;;;;;33763:106;33741:159;;;;-1:-1:-1;;;33741:159:0;;;;;;;;;33919:11;;;;-1:-1:-1;;;;;33919:25:0;33911:41;;;;-1:-1:-1;;;33911:41:0;;;;;;;;;33971:19;;;;-1:-1:-1;;;;;33971:33:0;33963:49;;;;-1:-1:-1;;;33963:49:0;;;;;;;;73561:629;53006:23;:21;:23::i;:::-;73701:11;;73689:10:::1;::::0;53944:37:::1;73689:10:::0;73701:11;53944:13:::1;:37::i;:::-;73738:41:::2;73752:5;:11;;;73765:5;:13;;;73738;:41::i;:::-;73730:57;;;;-1:-1:-1::0;;;73730:57:0::2;;;;;;;;;73800:22;73841:5;:11;;;73800:53;;73880:6;-1:-1:-1::0;;;;;73880:22:0::2;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73874:3;:30;73866:46;;;;-1:-1:-1::0;;;73866:46:0::2;;;;;;;;;73932:11:::0;;-1:-1:-1;;;;;73925:19:0::2;;::::0;;;:6:::2;:19;::::0;;;;;;;73945:13;;::::2;::::0;73925:34;;;;;;;;;73971:11:::2;::::0;::::2;::::0;73984:12:::2;::::0;::::2;::::0;73998:11:::2;::::0;::::2;::::0;73925:85;;-1:-1:-1;;;73925:85:0;;:45:::2;::::0;::::2;::::0;:85:::2;::::0;:34;;73971:11;;73984:12;;73998:11;73925:85:::2;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;74023:4:0::2;::::0;74043:11:::2;::::0;::::2;::::0;74056:8:::2;::::0;;::::2;::::0;74066:12:::2;::::0;::::2;::::0;74023:56;;-1:-1:-1;;;74023:56:0;;-1:-1:-1;;;;;74023:4:0;;::::2;::::0;-1:-1:-1;74023:19:0::2;::::0;-1:-1:-1;74023:56:0::2;::::0;74056:8;;74066:12;74023:56:::2;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;74144:5;:8;;;-1:-1:-1::0;;;;;74097:85:0::2;74131:5;:11;;;-1:-1:-1::0;;;;;74097:85:0::2;74118:5;:11;;;-1:-1:-1::0;;;;;74097:85:0::2;;74154:5;:13;;;74169:5;:12;;;74097:85;;;;;;;;74450:1064:::0;53006:23;:21;:23::i;:::-;74594:11;;74582:10:::1;::::0;53944:37:::1;74582:10:::0;74594:11;53944:13:::1;:37::i;:::-;74631:41:::2;74645:5;:11;;;74658:5;:13;;;74631;:41::i;:::-;74623:57;;;;-1:-1:-1::0;;;74623:57:0::2;;;;;;;;;74775:10;::::0;::::2;::::0;-1:-1:-1;;;;;74775:24:0::2;74789:10;74775:24;::::0;74774:57:::2;;;74819:5;:11;;;-1:-1:-1::0;;;;;74805:25:0::2;:5;:10;;;-1:-1:-1::0;;;;;74805:25:0::2;;74774:57;74766:73;;;;-1:-1:-1::0;;;74766:73:0::2;;;;;;;;;74860:9;::::0;74894:11:::2;::::0;::::2;::::0;74860:46:::2;::::0;-1:-1:-1;;;74860:46:0;;-1:-1:-1;;;;;74860:9:0;;::::2;::::0;:33:::2;::::0;:46:::2;::::0;::::2;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74852:62;;;;-1:-1:-1::0;;;74852:62:0::2;;;;;;;;;74930:17;74953:47;74973:5;:11;;;74986:5;:13;;;74953:19;:47::i;:::-;74927:73;;;;75017:9;75030:1;75017:14;75013:213;;;75114:12;::::0;::::2;::::0;75097:11:::2;::::0;::::2;::::0;-1:-1:-1;;;;;75080:29:0::2;;::::0;;;:16:::2;:29;::::0;;;;;:47:::2;::::0;::::2;:33;:47;:::i;:::-;75065:11;::::0;::::2;::::0;;-1:-1:-1;;;;;75048:29:0;;::::2;;::::0;;;:16:::2;:29;::::0;;;;;;;:79;;;;75194:11;;75185:21;::::2;::::0;;:8:::2;:21:::0;;;;;;75169:11;;75152:29;;::::2;::::0;;;;;;;;;;:54:::2;;75144:70;;;;-1:-1:-1::0;;;75144:70:0::2;;;;;;;;;75245:11:::0;;-1:-1:-1;;;;;75238:19:0::2;;::::0;;;:6:::2;:19;::::0;;;;;;;75258:13;;::::2;::::0;75238:34;;;;;;;;;75287:11:::2;::::0;::::2;::::0;75300:12:::2;::::0;::::2;::::0;75314:11:::2;::::0;::::2;::::0;75238:88;;-1:-1:-1;;;75238:88:0;;:48:::2;::::0;::::2;::::0;:88:::2;::::0;:34;;75287:11;;75300:12;;75314:11;75238:88:::2;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;75339:4:0::2;::::0;75359:11:::2;::::0;::::2;::::0;75372:10:::2;::::0;;::::2;::::0;75384:12:::2;::::0;::::2;::::0;75339:58;;-1:-1:-1;;;75339:58:0;;-1:-1:-1;;;;;75339:4:0;;::::2;::::0;-1:-1:-1;75339:19:0::2;::::0;-1:-1:-1;75339:58:0::2;::::0;75372:10;;75384:12;75339:58:::2;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;75466:5;:10;;;-1:-1:-1::0;;;;;75415:91:0::2;75453:5;:11;;;-1:-1:-1::0;;;;;75415:91:0::2;75440:5;:11;;;-1:-1:-1::0;;;;;75415:91:0::2;;75478:5;:13;;;75493:5;:12;;;75415:91;;;;;;;;75777:977:::0;53006:23;:21;:23::i;:::-;75923:11;;75911:10:::1;::::0;53944:37:::1;75911:10:::0;75923:11;53944:13:::1;:37::i;:::-;75960:41:::2;75974:5;:11;;;75987:5;:13;;;75960;:41::i;:::-;75952:57;;;;-1:-1:-1::0;;;75952:57:0::2;;;;;;;;;76023:30;;:::i;:::-;76055:17;76078:47;76098:5;:11;;;76111:5;:13;;;76078:19;:47::i;:::-;76022:103;;;;;76142:31;76154:5;:18;;;76142:11;:31::i;:::-;76138:190;;;76190:22;76231:5;:18;;;76250:1;76231:21;;;;;;;;;;;;;;76190:63;;76284:6;-1:-1:-1::0;;;;;76284:22:0::2;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76278:3;:30;76270:46;;;;-1:-1:-1::0;;;76270:46:0::2;;;;;;;;;76138:190;;76344:9;76357:1;76344:14;76340:126;;;76441:12;::::0;::::2;::::0;76424:11:::2;::::0;::::2;::::0;-1:-1:-1;;;;;76407:29:0::2;;::::0;;;:16:::2;:29;::::0;;;;;:47:::2;::::0;::::2;:33;:47;:::i;:::-;76392:11;::::0;::::2;::::0;-1:-1:-1;;;;;76375:29:0::2;;::::0;;;:16:::2;:29;::::0;;;;:79;76340:126:::2;76485:11:::0;;-1:-1:-1;;;;;76478:19:0::2;;::::0;;;:6:::2;:19;::::0;;;;;;;76498:13;;::::2;::::0;76478:34;;;;;;;;;76530:11:::2;::::0;::::2;::::0;76543:12:::2;::::0;::::2;::::0;76557:11:::2;::::0;::::2;::::0;76478:91;;-1:-1:-1;;;76478:91:0;;:51:::2;::::0;::::2;::::0;:91:::2;::::0;:34;;76530:11;;76543:12;;76557:11;76478:91:::2;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;76582:4:0::2;::::0;76602:11:::2;::::0;::::2;::::0;76615:8:::2;::::0;;::::2;::::0;76625:12:::2;::::0;::::2;::::0;76582:56;;-1:-1:-1;;;76582:56:0;;-1:-1:-1;;;;;76582:4:0;;::::2;::::0;-1:-1:-1;76582:19:0::2;::::0;-1:-1:-1;76582:56:0::2;::::0;76615:8;;76625:12;76582:56:::2;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;76708:5;:8;;;-1:-1:-1::0;;;;;76656:90:0::2;76695:5;:11;;;-1:-1:-1::0;;;;;76656:90:0::2;76682:5;:11;;;-1:-1:-1::0;;;;;76656:90:0::2;;76718:5;:13;;;76733:5;:12;;;76656:90;;;;;;;;;;;;;;;;53994:1;;53042::::1;;75777:977:::0;:::o;31319:512::-;31391:15;;:::i;:::-;31447:26;31427:16;;:46;;;;;;;;;31419:61;;;;-1:-1:-1;;;31419:61:0;;;;;;;;;31499:11;;;;-1:-1:-1;;;;;31499:25:0;31491:40;;;;-1:-1:-1;;;31491:40:0;;;;;;;;77057:676;53006:23;:21;:23::i;:::-;77191:11;;77179:10:::1;::::0;53944:37:::1;77179:10:::0;77191:11;53944:13:::1;:37::i;:::-;77228:41:::2;77242:5;:11;;;77255:5;:13;;;77228;:41::i;:::-;77220:57;;;;-1:-1:-1::0;;;77220:57:0::2;;;;;;;;;77296:9;::::0;77326:12:::2;::::0;::::2;::::0;77296:43:::2;::::0;-1:-1:-1;;;77296:43:0;;-1:-1:-1;;;;;77296:9:0;;::::2;::::0;:29:::2;::::0;:43:::2;::::0;::::2;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77288:59;;;;-1:-1:-1::0;;;77288:59:0::2;;;;;;;;;77360:22;77401:5;:12;;;77360:54;;77441:6;-1:-1:-1::0;;;;;77441:22:0::2;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77435:3;:30;77427:46;;;;-1:-1:-1::0;;;77427:46:0::2;;;;;;;;;77493:11:::0;;-1:-1:-1;;;;;77486:19:0::2;;::::0;;;:6:::2;:19;::::0;;;;;;;77506:13;;::::2;::::0;77486:34;;;;;;;;;77530:12:::2;::::0;::::2;::::0;77544::::2;::::0;::::2;::::0;77558:11:::2;::::0;::::2;::::0;77486:84;;-1:-1:-1;;;77486:84:0;;:43:::2;::::0;::::2;::::0;:84:::2;::::0;:34;;77530:12;;77544;;77558:11;77486:84:::2;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;;77601:8:0::2;::::0;;::::2;::::0;77611:12:::2;::::0;::::2;::::0;77583:41;;-1:-1:-1;;;77583:41:0;;-1:-1:-1;;;;;77583:17:0;::::2;::::0;-1:-1:-1;77583:17:0::2;::::0;:41:::2;::::0;77601:8;77583:41:::2;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;77687:5;:8;;;-1:-1:-1::0;;;;;77642:83:0::2;77674:5;:11;;;-1:-1:-1::0;;;;;77642:83:0::2;77660:5;:12;;;-1:-1:-1::0;;;;;77642:83:0::2;;77697:5;:13;;;77712:5;:12;;;77642:83;;;;;;;;32050:514:::0;32122:15;;:::i;:::-;32178:26;32158:16;;:46;;;;;;;;;32150:61;;;;-1:-1:-1;;;32150:61:0;;;;;;;;;32230:11;;;;-1:-1:-1;;;;;32230:25:0;32222:40;;;;-1:-1:-1;;;32222:40:0;;;;;;;;78028:936;53006:23;:21;:23::i;:::-;78162:11;;78150:10:::1;::::0;53944:37:::1;78150:10:::0;78162:11;53944:13:::1;:37::i;:::-;78261:41:::2;78275:5;:11;;;78288:5;:13;;;78261;:41::i;:::-;78253:57;;;;-1:-1:-1::0;;;78253:57:0::2;;;;;;;;;78398:10;::::0;::::2;::::0;-1:-1:-1;;;;;78398:24:0::2;78412:10;78398:24;::::0;78397:57:::2;;;78442:5;:11;;;-1:-1:-1::0;;;;;78428:25:0::2;:5;:10;;;-1:-1:-1::0;;;;;78428:25:0::2;;78397:57;78389:73;;;;-1:-1:-1::0;;;78389:73:0::2;;;;;;;;;78475:22;78516:5;:12;;;78475:54;;78604:6;-1:-1:-1::0;;;;;78604:22:0::2;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78598:3;:30;78590:46;;;;-1:-1:-1::0;;;78590:46:0::2;;;;;;;;;78693:11:::0;;-1:-1:-1;;;;;78686:19:0::2;;::::0;;;:6:::2;:19;::::0;;;;;;;78706:13;;::::2;::::0;78686:34;;;;;;;;;78733:12:::2;::::0;::::2;::::0;78747::::2;::::0;::::2;::::0;78761:11:::2;::::0;::::2;::::0;78686:87;;-1:-1:-1;;;78686:87:0;;:46:::2;::::0;::::2;::::0;:87:::2;::::0;:34;;78733:12;;78747;;78761:11;78686:87:::2;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;;78828:10:0::2;::::0;;::::2;::::0;78840:12:::2;::::0;::::2;::::0;78810:43;;-1:-1:-1;;;78810:43:0;;-1:-1:-1;;;;;78810:17:0;::::2;::::0;-1:-1:-1;78810:17:0::2;::::0;:43:::2;::::0;78828:10;78810:43:::2;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;78916:5;:10;;;-1:-1:-1::0;;;;;78871:85:0::2;78903:5;:11;;;-1:-1:-1::0;;;;;78871:85:0::2;78889:5;:12;;;-1:-1:-1::0;;;;;78871:85:0::2;;78928:5;:13;;;78943:5;:12;;;78871:85;;;;;;;;34539:331:::0;34613:17;;:::i;:::-;34671;34651:16;;:37;;;;;;;;;34643:53;;;;-1:-1:-1;;;34643:53:0;;;;;;;;;34715:19;;;;-1:-1:-1;;;;;34715:33:0;34707:49;;;;-1:-1:-1;;;34707:49:0;;;;;;;;;-1:-1:-1;34776:86:0;;;;;;;;;34798:19;;;;-1:-1:-1;;;;;34776:86:0;;;;;34827:11;;;;34776:86;;;;;34848:12;;;;;34776:86;;;;;34539:331::o;79195:847::-;79306:12;;;;79395:9;;:43;;-1:-1:-1;;;79395:43:0;;-1:-1:-1;;;;;79395:9:0;;;;:29;;:43;;79306:12;;79395:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79387:59;;;;-1:-1:-1;;;79387:59:0;;;;;;;;;79460:18;79480;79500:14;79516;79534:34;79560:6;79534:17;:34::i;:::-;79459:109;;;;;;;;79644:6;79637:3;:13;;79629:29;;;;-1:-1:-1;;;79629:29:0;;;;;;;;;79679:56;79696:10;79708:6;79716:10;79728:6;79679:16;:56::i;:::-;79671:72;;;;-1:-1:-1;;;79671:72:0;;;;;;;;;79756:14;79773:37;79783:5;:12;;;79797:5;:12;;;79773:9;:37::i;:::-;79756:54;;79823:6;-1:-1:-1;;;;;79823:17:0;;79841:10;79853:5;:12;;;79823:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;79879:4:0;;79911:14;;79879:55;;-1:-1:-1;;;79879:55:0;;-1:-1:-1;;;;;79879:4:0;;;;-1:-1:-1;79879:19:0;;-1:-1:-1;79879:55:0;;79899:10;;79911:14;79927:6;;79879:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79985:5;:14;;;-1:-1:-1;;;;;79952:82:0;79973:10;-1:-1:-1;;;;;79952:82:0;79959:5;:12;;;-1:-1:-1;;;;;79952:82:0;;80001:10;80013:5;:12;;;80027:6;79952:82;;;;;;;;;;;;;;;;;79195:847;;;;;;;:::o;35105:398::-;35184:22;;:::i;:::-;35247;35227:16;;:42;;;;;;;;;35219:58;;;;-1:-1:-1;;;35219:58:0;;;;;;;;;35296:11;;;;-1:-1:-1;;;;;35296:25:0;35288:41;;;;-1:-1:-1;;;35288:41:0;;;;;;;;;35348:19;;;;-1:-1:-1;;;;;35348:33:0;35340:49;;;;-1:-1:-1;;;35340:49:0;;;;;;;;;35409:86;;;;;;;;35433:5;:11;;;-1:-1:-1;;;;;35409:86:0;;;;;35455:5;:13;;;35409:86;;;;35474:5;:19;;;-1:-1:-1;;;;;35409:86:0;;;;35402:93;;35105:398;;;:::o;80377:2194::-;80473:11;;80461:10;;53944:37;80461:10;80473:11;53944:13;:37::i;:::-;80505:41:::1;80519:5;:11;;;80532:5;:13;;;80505;:41::i;:::-;80497:57;;;;-1:-1:-1::0;;;80497:57:0::1;;;;;;;;;80568:30;;:::i;:::-;80600:17;80623:47;80643:5;:11;;;80656:5;:13;;;80623:19;:47::i;:::-;80567:103;;;;;80683:22;81021:13:::0;81037:31:::1;81049:5;:18;;;81037:11;:31::i;:::-;81021:47;;81083:12;81098:30;81110:5;:17;;;81098:11;:30::i;:::-;81083:45;;81153:8;:19;;;;81165:7;81153:19;81145:35;;;;-1:-1:-1::0;;;81145:35:0::1;;;;;;;;;81206:8;:89;;81274:5;:17;;;81292:1;81274:20;;;;;;;;;;;;;;81206:89;;;81233:18:::0;;:21;;:18:::1;::::0;:21:::1;;;;;;;;;;81206:89;81197:98;;81316:7;81312:193;;;81344:26;81389:5;:17;;;81407:1;81389:20;;;;;;;;;;;;;;81344:66;;81431:10;-1:-1:-1::0;;;;;81431:21:0::1;;81461:4;;;;;;;;;-1:-1:-1::0;;;;;81461:4:0::1;81468:5;:17;;;81486:1;81468:20;;;;;;;;;;;;;;81431:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;81312:193;;53994:1;;81529:18;81549::::0;81569:14:::1;81585::::0;81603:34:::1;81629:6;81603:17;:34::i;:::-;81528:109;;;;;;;;81728:6;81721:3;:13;;81713:29;;;;-1:-1:-1::0;;;81713:29:0::1;;;;;;;;;81761:56;81778:10;81790:6;81798:10;81810:6;81761:16;:56::i;:::-;81753:72;;;;-1:-1:-1::0;;;81753:72:0::1;;;;;;;;;81876:10;::::0;:48:::1;::::0;-1:-1:-1;;;81876:48:0;;81839:14:::1;::::0;;;-1:-1:-1;;;;;81876:10:0;;::::1;::::0;:30:::1;::::0;:48:::1;::::0;81907:5;;81914:9;;81876:48:::1;;;;;;::::0;::::1;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81838:86;;;;82103:12;82095:28;;;;-1:-1:-1::0;;;82095:28:0::1;;;;;;;;;82143:6;:19;82150:5;:11;;;-1:-1:-1::0;;;;;82143:19:0::1;-1:-1:-1::0;;;;;82143:19:0::1;;;;;;;;;;;;:34;82163:5;:13;;;82143:34;;;;;;;;;;;;82136:41:::0;::::1;;;;;;;:::i;:::-;;;::::0;::::1;;;:::i;:::-;;;::::0;::::1;;;:::i;:::-;;;::::0;::::1;;;:::i;:::-;;;::::0;::::1;;;:::i;:::-;;;::::0;::::1;;;:::i;:::-;;;82194:9;82207:1;82194:14;82190:118;;;-1:-1:-1::0;;;;;82256:28:0;::::1;;::::0;;;:16:::1;:28;::::0;;;;;:40:::1;::::0;82289:6;82256:40:::1;:32;:40;:::i;:::-;-1:-1:-1::0;;;;;82225:28:0;::::1;;::::0;;;:16:::1;:28;::::0;;;;:71;82190:118:::1;82320:4;::::0;82352:8:::1;::::0;;::::1;::::0;82320:49;;-1:-1:-1;;;82320:49:0;;-1:-1:-1;;;;;82320:4:0;;::::1;::::0;:19:::1;::::0;:49:::1;::::0;82340:10;;82352:8;82362:6;;82320:49:::1;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;82382:15;82400:5;:13;;;82382:31;;82424:23;82450:5;:8;;;82424:34;;82553:9;82510:6;-1:-1:-1::0;;;;;82476:87:0::1;82489:5;:11;;;-1:-1:-1::0;;;;;82476:87:0::1;;82519:15;82536:6;82544:7;82476:87;;;;;;;;;;;;;;;;;53994:1;;;;;;;;;;;80377:2194:::0;;;:::o;35511:717::-;35588:20;;:::i;:::-;35649;35629:16;;:40;;;;;;;;;35621:56;;;;-1:-1:-1;;;35621:56:0;;;;;;;;;35696:11;;;;-1:-1:-1;;;;;35696:25:0;35688:41;;;;-1:-1:-1;;;35688:41:0;;;;;;;;;35748:19;;;;-1:-1:-1;;;;;35748:33:0;35740:49;;;;-1:-1:-1;;;35740:49:0;;;;;;;;;35808:5;:10;;;:17;35829:2;35808:23;35800:39;;;;-1:-1:-1;;;35800:39:0;;;;;;;;;35906:15;35935:5;:10;;;35924:33;;;;;;;;;;;;;;35906:51;;35990:230;;;;;;;;36030:5;:11;;;-1:-1:-1;;;;;35990:230:0;;;;;36070:5;:19;;;-1:-1:-1;;;;;35990:230:0;;;;;36117:5;:13;;;35990:230;;;;36157:5;:12;;;35990:230;;;;36197:7;35990:230;;;35970:250;;;35511:717;;;:::o;82773:2409::-;53006:23;:21;:23::i;:::-;82876:41:::1;82890:5;:11;;;82903:5;:13;;;82876;:41::i;:::-;82868:57;;;;-1:-1:-1::0;;;82868:57:0::1;;;;;;;;;83205:30;;:::i;:::-;83237:18;83257:13:::0;83272:22:::1;83298:108;83328:5;:11;;;83354:5;:13;;;83382:5;:13;;;83298:15;:108::i;:::-;83204:202;;;;;;;;83427:13;83419:29;;;;-1:-1:-1::0;;;83419:29:0::1;;;;;;;;;83517:24;83544:32;83572:3;83544:23;83561:5;83544;:12;;;:16;;:23;;;;:::i;:32::-;83517:59;;83810:1;83768:39;83794:5;:12;;;83768:5;:18;;;83787:1;83768:21;;;;;;;;;;;;;;:25;;:39;;;;:::i;:::-;:43;83764:158;;;83888:14;83836:48;83867:16;83836:5;:23;;;83860:1;83836:26;;;;;;;:48;:66;;83828:82;;;;-1:-1:-1::0;;;83828:82:0::1;;;;;;;;;84138:18:::0;;:21;;:18:::1;::::0;:21:::1;;;;;;;;;;-1:-1:-1::0;;;;;84122:49:0::1;;84172:10;84184:5;:12;;;84122:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;84330:11:0;;-1:-1:-1;;;;;84323:19:0::1;;::::0;;;:6:::1;:19;::::0;;;;;;;84343:13;;::::1;::::0;84323:34;;;;;;;;84375:22;;::::1;::::0;:25;;84323:51:::1;::::0;-1:-1:-1;84323:51:0::1;::::0;-1:-1:-1;84323:34:0;;84375:22;;:25:::1;;;;;;;;;;84402:16;84420:1;84323:99;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;84559:11:0;;-1:-1:-1;;;;;84552:19:0::1;;::::0;;;:6:::1;:19;::::0;;;;;;;84572:13;;::::1;::::0;84552:34;;;;;;;84599:18;;:21;;84552:46:::1;::::0;-1:-1:-1;84552:46:0::1;::::0;-1:-1:-1;84552:34:0;;84599:18;;:21:::1;;;;;;;;;;84622:5;:12;;;84636:1;84552:86;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;84758:65;84806:16;84758;:43;84775:5;:22;;;84798:1;84775:25;;;;;;;;;;;;;;-1:-1:-1::0;;;;;84758:43:0::1;-1:-1:-1::0;;;;;84758:43:0::1;;;;;;;;;;;;;:47;;:65;;;;:::i;:::-;84712:16;:43;84729:5;:22;;;84752:1;84729:25;;;;;;;;;;;;;;-1:-1:-1::0;;;;;84712:43:0::1;-1:-1:-1::0;;;;;84712:43:0::1;;;;;;;;;;;;:111;;;;84836:4;;;;;;;;;-1:-1:-1::0;;;;;84836:4:0::1;-1:-1:-1::0;;;;;84836:19:0::1;;84856:5;:22;;;84879:1;84856:25;;;;;;;;;;;;;;84883:5;:14;;;84899:16;84836:80;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;85018:5;:11;;;-1:-1:-1::0;;;;;84934:240:0::1;84989:5;:14;;;-1:-1:-1::0;;;;;84934:240:0::1;84964:10;-1:-1:-1::0;;;;;84934:240:0::1;;85044:5;85064;:13;;;85092:16;85123:5;:12;;;85150:5;:13;;;84934:240;;;;;;;;;;;;;;;;;;;53042:1;;;;;82773:2409:::0;:::o;36447:296::-;36519:15;;:::i;:::-;36575;36555:16;;:35;;;;;;;;;36547:51;;;;-1:-1:-1;;;36547:51:0;;;;;;;;;36617:19;;;;-1:-1:-1;;;;;36617:33:0;36609:49;;;;-1:-1:-1;;;36609:49:0;;;;;;;;;-1:-1:-1;36678:57:0;;;;;;;;36696:19;;;;-1:-1:-1;;;;;36678:57:0;;;36723:10;;;;;36678:57;;;;;36447:296::o;85357:263::-;53006:23;:21;:23::i;:::-;85453:12;;54218:14:::1;::::0;-1:-1:-1;;;54218:14:0;::::1;;;54214:91;;;54257:29;54278:7;54257:20;:29::i;:::-;54249:44;;;;-1:-1:-1::0;;;54249:44:0::1;;;;;;;;;85494:12:::0;;85533:10:::2;::::0;::::2;::::0;85478:66:::2;::::0;-1:-1:-1;;;85478:66:0;;-1:-1:-1;;;;;85478:42:0;;::::2;::::0;::::2;::::0;:66:::2;::::0;85521:10:::2;::::0;85533;85478:66:::2;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;85587:5;:12;;;-1:-1:-1::0;;;;;85562:50:0::2;85575:10;-1:-1:-1::0;;;;;85562:50:0::2;;85601:5;:10;;;85562:50;;;;;;;54419:103:::0;54486:21;;-1:-1:-1;;;54486:21:0;;;;54485:22;54477:37;;;;-1:-1:-1;;;54477:37:0;;;;;;;;54872:176;54980:13;-1:-1:-1;;;;;54969:24:0;:7;-1:-1:-1;;;;;54969:24:0;;54968:65;;;-1:-1:-1;;;;;;54999:24:0;;;;;;;:9;:24;;;;;;;;:33;;;;;;;;;;;;54968:65;54960:80;;;;-1:-1:-1;;;54960:80:0;;;;;;;;9398:181;9456:7;9488:5;;;9512:6;;;;9504:46;;;;-1:-1:-1;;;9504:46:0;;;;;;;;85878:187;85965:4;86002:1;85991:8;:12;85990:66;;;;-1:-1:-1;;;;;;;86021:34:0;;;;;;;;:19;:34;;;;;;-1:-1:-1;86009:46:0;;85878:187::o;86073:149::-;86142:4;86183:1;86167:6;:13;:17;86166:48;;;;;86211:1;-1:-1:-1;;;;;86190:23:0;:6;86197:1;86190:9;;;;;;;;;;;;;;-1:-1:-1;;;;;86190:23:0;;;86159:55;86073:149;-1:-1:-1;;86073:149:0:o;9854:136::-;9912:7;9939:43;9943:1;9946;9939:43;;;;;;;;;;;;;;;;;:3;:43::i;86419:140::-;86513:9;;:38;;-1:-1:-1;;;86513:38:0;;86489:4;;-1:-1:-1;;;;;86513:9:0;;:29;;:38;;86543:7;;86513:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10285:226;10405:7;10441:12;10433:6;;;;10425:29;;;;-1:-1:-1;;;10425:29:0;;;;;;;;;;-1:-1:-1;;;10477:5:0;;;10285:226::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;5:130;72:20;;97:33;72:20;97:33;;1356:440;;1457:3;1450:4;1442:6;1438:17;1434:27;1424:2;;-1:-1;;1465:12;1424:2;1512:6;1499:20;76511:18;76503:6;76500:30;76497:2;;;-1:-1;;76533:12;76497:2;1534:64;76606:9;76587:17;;-1:-1;;76583:33;76674:4;76664:15;1534:64;;;1525:73;;1618:6;1611:5;1604:21;1722:3;76674:4;1713:6;1646;1704:16;;1701:25;1698:2;;;1739:1;;1729:12;1698:2;81212:6;76674:4;1646:6;1642:17;76674:4;1680:5;1676:16;81189:30;81268:1;81250:16;;;76674:4;81250:16;81243:27;1680:5;1417:379;-1:-1;;1417:379;1804:160;1886:20;;81992:2;81982:13;;81972:2;;82009:1;;81999:12;3763:241;;3867:2;3855:9;3846:7;3842:23;3838:32;3835:2;;;-1:-1;;3873:12;3835:2;85:6;72:20;97:33;124:5;97:33;;4011:263;;4126:2;4114:9;4105:7;4101:23;4097:32;4094:2;;;-1:-1;;4132:12;4094:2;226:6;220:13;238:33;265:5;238:33;;4281:366;;;4402:2;4390:9;4381:7;4377:23;4373:32;4370:2;;;-1:-1;;4408:12;4370:2;85:6;72:20;97:33;124:5;97:33;;;4460:63;-1:-1;4560:2;4599:22;;72:20;97:33;72:20;97:33;;;4568:63;;;;4364:283;;;;;;4654:617;;;;;4809:3;4797:9;4788:7;4784:23;4780:33;4777:2;;;-1:-1;;4816:12;4777:2;85:6;72:20;97:33;124:5;97:33;;;4868:63;-1:-1;4968:2;5007:22;;72:20;97:33;72:20;97:33;;;4976:63;-1:-1;5076:2;5115:22;;72:20;97:33;72:20;97:33;;;4771:500;;;;-1:-1;5084:63;;5184:2;5223:22;3552:20;;-1:-1;;4771:500;5278:940;;;;;;;5475:3;5463:9;5454:7;5450:23;5446:33;5443:2;;;-1:-1;;5482:12;5443:2;226:6;220:13;238:33;265:5;238:33;;;5645:2;5695:22;;220:13;5534:74;;-1:-1;238:33;220:13;238:33;;;5764:2;5814:22;;220:13;5653:74;;-1:-1;238:33;220:13;238:33;;;5772:74;;;;5883:2;5937:9;5933:22;3700:13;5891:74;;6002:3;6057:9;6053:22;3700:13;6011:74;;6122:3;6174:9;6170:22;1295:13;1313:30;1337:5;1313:30;;;6131:71;;;;5437:781;;;;;;;;;6225:360;;;6343:2;6331:9;6322:7;6318:23;6314:32;6311:2;;;-1:-1;;6349:12;6311:2;85:6;72:20;97:33;124:5;97:33;;;6401:63;-1:-1;6501:2;6537:22;;1153:20;1178:30;1153:20;1178:30;;6592:366;;;6713:2;6701:9;6692:7;6688:23;6684:32;6681:2;;;-1:-1;;6719:12;6681:2;85:6;72:20;97:33;124:5;97:33;;;6771:63;6871:2;6910:22;;;;3552:20;;-1:-1;;;6675:283;6965:491;;;;7103:2;7091:9;7082:7;7078:23;7074:32;7071:2;;;-1:-1;;7109:12;7071:2;85:6;72:20;97:33;124:5;97:33;;;7161:63;7261:2;7300:22;;3552:20;;-1:-1;7369:2;7408:22;;;3552:20;;7065:391;-1:-1;;;7065:391;7463:433;;7620:2;;7608:9;7599:7;7595:23;7591:32;7588:2;;;-1:-1;;7626:12;7588:2;7684:17;7671:31;7722:18;;7714:6;7711:30;7708:2;;;-1:-1;;7744:12;7708:2;7863:6;7852:9;7848:22;464:3;457:4;449:6;445:17;441:27;431:2;;-1:-1;;472:12;431:2;519:6;506:20;492:34;;7722:18;76208:6;76205:30;76202:2;;;-1:-1;;76238:12;76202:2;541:108;7620:2;;76275:6;76271:17;76336:15;541:108;;;677:21;;;734:14;;;;709:17;;;-1:-1;814:261;839:6;836:1;833:13;814:261;;;922:3;909:17;713:6;897:30;2120:6;;76606:9;;897:30;2103:3;2099:19;;2095:32;2092:2;;;-1:-1;;2130:12;2092:2;2158:22;2120:6;2158:22;;;2268:64;2328:3;7620:2;897:30;;2268:64;;;2250:16;2243:90;2428:49;2473:3;2449:22;897:30;2449:22;2428:49;;;7620:2;2414:5;2410:16;2403:75;2602:22;2581:49;2626:3;2602:22;897:30;2602:22;2581:49;;;2449:22;2567:5;2563:16;2556:75;2726:49;2771:3;2747:22;897:30;2747:22;2726:49;;;2602:22;2712:5;2708:16;2701:75;;2895:22;897:30;2895:22;3552:20;2747:22;2860:5;2856:16;2849:75;3042:22;897:30;3042:22;3552:20;2895:22;3007:5;3003:16;2996:75;3188:22;897:30;3188:22;3552:20;3042:22;3153:5;3149:16;3142:75;2120:6;897:30;3291:19;3278:33;7722:18;3323:6;3320:30;3317:2;;;-1:-1;;3353:12;3317:2;3398:58;3452:3;7620:2;3443:6;897:30;3428:22;;3398:58;;;3188:22;3380:16;;3373:84;-1:-1;934:78;;-1:-1;;1026:14;;;;1054;;;;861:1;854:9;814:261;;;-1:-1;7764:116;;7582:314;-1:-1;;;;;;;;;7582:314;7903:235;;8004:2;7992:9;7983:7;7979:23;7975:32;7972:2;;;-1:-1;;8010:12;7972:2;1166:6;1153:20;1178:30;1202:5;1178:30;;8145:257;;8257:2;8245:9;8236:7;8232:23;8228:32;8225:2;;;-1:-1;;8263:12;8225:2;1301:6;1295:13;1313:30;1337:5;1313:30;;8409:529;;;;8555:2;8543:9;8534:7;8530:23;8526:32;8523:2;;;-1:-1;;8561:12;8523:2;1301:6;1295:13;1313:30;1337:5;1313:30;;;8721:2;8771:22;;3700:13;8840:2;8890:22;;;3700:13;8613:71;;3700:13;;-1:-1;3700:13;8517:421;-1:-1;;;8517:421;8945:263;;9060:2;9048:9;9039:7;9035:23;9031:32;9028:2;;;-1:-1;;9066:12;9028:2;-1:-1;3700:13;;9022:186;-1:-1;9022:186;9215:393;;;9344:2;9332:9;9323:7;9319:23;9315:32;9312:2;;;-1:-1;;9350:12;9312:2;3706:6;3700:13;9402:74;;9513:2;9564:9;9560:22;1295:13;1313:30;1337:5;1313:30;;10661:670;;10844:5;77115:12;77908:6;77903:3;77896:19;77945:4;;77940:3;77936:14;10856:83;;77945:4;11010:5;76811:14;-1:-1;11049:260;11074:6;11071:1;11068:13;11049:260;;;11135:13;;-1:-1;;;;;78842:54;10215:45;;9769:14;;;;77646;;;;76511:18;11089:9;11049:260;;;-1:-1;11315:10;;10775:556;-1:-1;;;;;10775:556;11370:670;;11553:5;77115:12;77908:6;77903:3;77896:19;77945:4;;77940:3;77936:14;11565:83;;77945:4;11719:5;76811:14;-1:-1;11758:260;11783:6;11780:1;11777:13;11758:260;;;11844:13;;36747:18;;9951:14;;;;77646;;;;11805:1;11798:9;11758:260;;12159:343;;12301:5;77115:12;77908:6;77903:3;77896:19;-1:-1;81357:101;81371:6;81368:1;81365:13;81357:101;;;77945:4;81438:11;;;;;81432:18;81419:11;;;;;81412:39;81386:10;81357:101;;;81473:6;81470:1;81467:13;81464:2;;;-1:-1;77945:4;81529:6;77940:3;81520:16;;81513:27;81464:2;-1:-1;76606:9;81629:14;-1:-1;;81625:28;12458:39;;;;77945:4;12458:39;;12249:253;-1:-1;;12249:253;34842:1796;;35067:16;35061:23;34987:4;35104:14;35097:38;35150:103;34987:4;34982:3;34978:14;35234:12;35150:103;;;35345:4;35338:5;35334:16;35328:23;35308:43;;35397:3;35391:4;35387:14;35345:4;35375:3;35371:14;35364:38;35417:103;35515:4;35501:12;35417:103;;;35617:4;35610:5;35606:16;35600:23;35580:43;;35669:3;35663:4;35659:14;35617:4;35647:3;35643:14;35636:38;35689:103;35787:4;35773:12;35689:103;;;35681:111;;;35885:4;35878:5;35874:16;35868:23;35848:43;;35937:3;35931:4;35927:14;35885:4;35915:3;35911:14;35904:38;35957:103;36055:4;36041:12;35957:103;;;36152:4;36145:5;36141:16;36135:23;36115:43;;36204:3;36198:4;36194:14;36152:4;36182:3;36178:14;36171:38;36224:103;36322:4;36308:12;36224:103;;;36216:111;;;36425:4;36418:5;36414:16;36408:23;36388:43;;36477:3;36471:4;36467:14;36425:4;36455:3;36451:14;36444:38;36497:103;36595:4;36581:12;36497:103;;37135:222;-1:-1;;;;;78842:54;;;;10215:45;;37262:2;37247:18;;37233:124;37364:449;-1:-1;;;;;78842:54;;10215:45;;37553:2;37687;37672:18;;37665:48;;;37364:449;;37727:76;;37538:18;;37789:6;37727:76;;;37719:84;37524:289;-1:-1;;;;37524:289;37820:349;-1:-1;;;;;78842:54;;;;10058:58;;38155:2;38140:18;;36747;37983:2;37968:18;;37954:215;38176:460;-1:-1;;;;;78842:54;;;10215:45;;78842:54;;;;38539:2;38524:18;;10058:58;38622:2;38607:18;;36747;;;;38367:2;38352:18;;38338:298;38643:556;-1:-1;;;;;78842:54;;;10215:45;;78842:54;;;39019:2;39004:18;;10215:45;78842:54;;;39102:2;39087:18;;10215:45;78842:54;;;39185:2;39170:18;;10215:45;38854:3;38839:19;;38825:374;39997:444;-1:-1;;;;;78842:54;;;;10215:45;;40344:2;40329:18;;36747;;;;40427:2;40412:18;;36747;40180:2;40165:18;;40151:290;40448:210;78754:13;;78747:21;12113:34;;40569:2;40554:18;;40540:118;40665:432;78754:13;;78747:21;12113:34;;41000:2;40985:18;;36747;;;;41083:2;41068:18;;36747;40842:2;40827:18;;40813:284;41104:306;;41249:2;41270:17;41263:47;41324:76;41249:2;41238:9;41234:18;41386:6;41324:76;;43163:416;43363:2;43377:47;;;14194:1;43348:18;;;77896:19;-1:-1;;;77936:14;;;14209:25;14253:12;;;43334:245;43586:416;43786:2;43800:47;;;14504:1;43771:18;;;77896:19;-1:-1;;;77936:14;;;14519:26;14564:12;;;43757:245;44009:416;44209:2;44223:47;;;14815:1;44194:18;;;77896:19;-1:-1;;;77936:14;;;14830:26;14875:12;;;44180:245;44432:416;44632:2;44646:47;;;15126:1;44617:18;;;77896:19;-1:-1;;;77936:14;;;15141:26;15186:12;;;44603:245;44855:416;45055:2;45069:47;;;15437:1;45040:18;;;77896:19;-1:-1;;;77936:14;;;15452:26;15497:12;;;45026:245;45278:416;45478:2;45492:47;;;15748:1;45463:18;;;77896:19;-1:-1;;;77936:14;;;15763:26;15808:12;;;45449:245;45701:416;45901:2;45915:47;;;16059:1;45886:18;;;77896:19;-1:-1;;;77936:14;;;16074:26;16119:12;;;45872:245;46124:416;46324:2;46338:47;;;16370:1;46309:18;;;77896:19;-1:-1;;;77936:14;;;16385:25;16429:12;;;46295:245;46547:416;46747:2;46761:47;;;16680:1;46732:18;;;77896:19;-1:-1;;;77936:14;;;16695:26;16740:12;;;46718:245;46970:416;47170:2;47184:47;;;16991:2;47155:18;;;77896:19;17027:34;77936:14;;;17007:55;-1:-1;;;17082:12;;;17075:30;17124:12;;;47141:245;47393:416;47593:2;47607:47;;;17375:1;47578:18;;;77896:19;-1:-1;;;77936:14;;;17390:25;17434:12;;;47564:245;47816:416;48016:2;48030:47;;;17685:1;48001:18;;;77896:19;-1:-1;;;77936:14;;;17700:26;17745:12;;;47987:245;48239:416;48439:2;48453:47;;;17996:2;48424:18;;;77896:19;18032:29;77936:14;;;18012:50;18081:12;;;48410:245;48662:416;48862:2;48876:47;;;18332:1;48847:18;;;77896:19;-1:-1;;;77936:14;;;18347:26;18392:12;;;48833:245;49085:416;49285:2;49299:47;;;18643:1;49270:18;;;77896:19;-1:-1;;;77936:14;;;18658:26;18703:12;;;49256:245;49508:416;49708:2;49722:47;;;18954:1;49693:18;;;77896:19;-1:-1;;;77936:14;;;18969:26;19014:12;;;49679:245;49931:416;50131:2;50145:47;;;19265:1;50116:18;;;77896:19;-1:-1;;;77936:14;;;19280:26;19325:12;;;50102:245;50354:416;50554:2;50568:47;;;19576:1;50539:18;;;77896:19;-1:-1;;;77936:14;;;19591:25;19635:12;;;50525:245;50777:416;50977:2;50991:47;;;19886:1;50962:18;;;77896:19;-1:-1;;;77936:14;;;19901:26;19946:12;;;50948:245;51200:416;51400:2;51414:47;;;20197:1;51385:18;;;77896:19;-1:-1;;;77936:14;;;20212:26;20257:12;;;51371:245;51623:416;51823:2;51837:47;;;20508:1;51808:18;;;77896:19;-1:-1;;;77936:14;;;20523:26;20568:12;;;51794:245;52046:416;52246:2;52260:47;;;20819:1;52231:18;;;77896:19;-1:-1;;;77936:14;;;20834:25;20878:12;;;52217:245;52469:416;52669:2;52683:47;;;21129:1;52654:18;;;77896:19;-1:-1;;;77936:14;;;21144:25;21188:12;;;52640:245;52892:416;53092:2;53106:47;;;21439:1;53077:18;;;77896:19;-1:-1;;;77936:14;;;21454:26;21499:12;;;53063:245;53315:416;53515:2;53529:47;;;21750:1;53500:18;;;77896:19;-1:-1;;;77936:14;;;21765:26;21810:12;;;53486:245;53738:416;53938:2;53952:47;;;22061:1;53923:18;;;77896:19;-1:-1;;;77936:14;;;22076:26;22121:12;;;53909:245;54161:416;54361:2;54375:47;;;22372:1;54346:18;;;77896:19;-1:-1;;;77936:14;;;22387:26;22432:12;;;54332:245;54584:416;54784:2;54798:47;;;22683:1;54769:18;;;77896:19;-1:-1;;;77936:14;;;22698:26;22743:12;;;54755:245;55007:416;55207:2;55221:47;;;22994:1;55192:18;;;77896:19;-1:-1;;;77936:14;;;23009:26;23054:12;;;55178:245;55430:416;55630:2;55644:47;;;23305:1;55615:18;;;77896:19;-1:-1;;;77936:14;;;23320:25;23364:12;;;55601:245;55853:416;56053:2;56067:47;;;23615:1;56038:18;;;77896:19;-1:-1;;;77936:14;;;23630:26;23675:12;;;56024:245;56276:416;56476:2;56490:47;;;23926:1;56461:18;;;77896:19;-1:-1;;;77936:14;;;23941:26;23986:12;;;56447:245;56699:416;56899:2;56913:47;;;24237:1;56884:18;;;77896:19;-1:-1;;;77936:14;;;24252:26;24297:12;;;56870:245;57122:416;57322:2;57336:47;;;24548:1;57307:18;;;77896:19;-1:-1;;;77936:14;;;24563:26;24608:12;;;57293:245;57545:416;57745:2;57759:47;;;24859:1;57730:18;;;77896:19;-1:-1;;;77936:14;;;24874:25;24918:12;;;57716:245;57968:416;58168:2;58182:47;;;25169:1;58153:18;;;77896:19;-1:-1;;;77936:14;;;25184:26;25229:12;;;58139:245;58391:416;58591:2;58605:47;;;25480:2;58576:18;;;77896:19;25516:34;77936:14;;;25496:55;-1:-1;;;25571:12;;;25564:25;25608:12;;;58562:245;58814:416;59014:2;59028:47;;;25859:1;58999:18;;;77896:19;-1:-1;;;77936:14;;;25874:26;25919:12;;;58985:245;59237:416;59437:2;59451:47;;;59422:18;;;77896:19;26206:34;77936:14;;;26186:55;26260:12;;;59408:245;59660:416;59860:2;59874:47;;;26511:1;59845:18;;;77896:19;-1:-1;;;77936:14;;;26526:26;26571:12;;;59831:245;60083:416;60283:2;60297:47;;;26822:2;60268:18;;;77896:19;26858:34;77936:14;;;26838:55;-1:-1;;;26913:12;;;26906:38;26963:12;;;60254:245;60506:416;60706:2;60720:47;;;27214:1;60691:18;;;77896:19;-1:-1;;;77936:14;;;27229:26;27274:12;;;60677:245;60929:416;61129:2;61143:47;;;27525:1;61114:18;;;77896:19;-1:-1;;;77936:14;;;27540:26;27585:12;;;61100:245;61352:416;61552:2;61566:47;;;27836:1;61537:18;;;77896:19;-1:-1;;;77936:14;;;27851:26;27896:12;;;61523:245;61775:416;61975:2;61989:47;;;28147:1;61960:18;;;77896:19;-1:-1;;;77936:14;;;28162:26;28207:12;;;61946:245;62198:416;62398:2;62412:47;;;28458:1;62383:18;;;77896:19;-1:-1;;;77936:14;;;28473:26;28518:12;;;62369:245;62621:416;62821:2;62835:47;;;28769:1;62806:18;;;77896:19;-1:-1;;;77936:14;;;28784:26;28829:12;;;62792:245;63044:416;63244:2;63258:47;;;29080:1;63229:18;;;77896:19;-1:-1;;;77936:14;;;29095:25;29139:12;;;63215:245;63467:416;63667:2;63681:47;;;29390:1;63652:18;;;77896:19;-1:-1;;;77936:14;;;29405:25;29449:12;;;63638:245;63890:416;64090:2;64104:47;;;29700:1;64075:18;;;77896:19;-1:-1;;;77936:14;;;29715:26;29760:12;;;64061:245;64313:416;64513:2;64527:47;;;30011:1;64498:18;;;77896:19;-1:-1;;;77936:14;;;30026:25;30070:12;;;64484:245;64736:416;64936:2;64950:47;;;30321:1;64921:18;;;77896:19;-1:-1;;;77936:14;;;30336:26;30381:12;;;64907:245;65159:416;65359:2;65373:47;;;30632:1;65344:18;;;77896:19;-1:-1;;;77936:14;;;30647:26;30692:12;;;65330:245;65582:416;65782:2;65796:47;;;30943:1;65767:18;;;77896:19;-1:-1;;;77936:14;;;30958:26;31003:12;;;65753:245;66005:416;66205:2;66219:47;;;31254:1;66190:18;;;77896:19;-1:-1;;;77936:14;;;31269:26;31314:12;;;66176:245;66428:416;66628:2;66642:47;;;31565:1;66613:18;;;77896:19;-1:-1;;;77936:14;;;31580:25;31624:12;;;66599:245;66851:416;67051:2;67065:47;;;31875:1;67036:18;;;77896:19;-1:-1;;;77936:14;;;31890:25;31934:12;;;67022:245;67274:416;67474:2;67488:47;;;32185:1;67459:18;;;77896:19;-1:-1;;;77936:14;;;32200:25;32244:12;;;67445:245;67697:416;67897:2;67911:47;;;32495:1;67882:18;;;77896:19;-1:-1;;;77936:14;;;32510:26;32555:12;;;67868:245;68120:416;68320:2;68334:47;;;32806:1;68305:18;;;77896:19;-1:-1;;;77936:14;;;32821:25;32865:12;;;68291:245;68543:416;68743:2;68757:47;;;33116:1;68728:18;;;77896:19;-1:-1;;;77936:14;;;33131:26;33176:12;;;68714:245;68966:416;69166:2;69180:47;;;33427:1;69151:18;;;77896:19;-1:-1;;;77936:14;;;33442:26;33487:12;;;69137:245;69389:416;69589:2;69603:47;;;33738:2;69574:18;;;77896:19;33774:33;77936:14;;;33754:54;33827:12;;;69560:245;69812:416;70012:2;70026:47;;;34078:1;69997:18;;;77896:19;-1:-1;;;77936:14;;;34093:25;34137:12;;;69983:245;70235:416;70435:2;70449:47;;;34388:1;70420:18;;;77896:19;-1:-1;;;77936:14;;;34403:25;34447:12;;;70406:245;70658:416;70858:2;70872:47;;;34698:1;70843:18;;;77896:19;-1:-1;;;77936:14;;;34713:25;34757:12;;;70829:245;71081:358;;71252:2;71273:17;71266:47;71327:102;71252:2;71241:9;71237:18;71415:6;71327:102;;71446:469;;71645:2;71666:17;71659:47;71720:102;71645:2;71634:9;71630:18;71808:6;71720:102;;;71712:110;;36759:5;71901:2;71890:9;71886:18;36747;71616:299;;;;;;71922:580;;72149:2;72170:17;72163:47;72224:102;72149:2;72138:9;72134:18;72312:6;72224:102;;;72405:2;72390:18;;36747;;;;-1:-1;72488:2;72473:18;36747;72216:110;72120:382;-1:-1;72120:382;72509:692;;72764:3;72786:17;72779:47;72840:102;72764:3;72753:9;72749:19;72928:6;72840:102;;;73021:2;73006:18;;36747;;;;-1:-1;73104:2;73089:18;;36747;;;;73187:2;73172:18;;;36747;72832:110;72735:466;-1:-1;72735:466;73208:658;36747:18;;;-1:-1;;;;;78842:54;;;;73662:2;73647:18;;10215:45;73753:2;73738:18;;36747;73852:2;73837:18;;13545:58;73458:3;73443:19;;73429:437;74522:222;36747:18;;;74649:2;74634:18;;74620:124;74751:333;36747:18;;;75070:2;75055:18;;36747;74906:2;74891:18;;74877:207;75091:668;36747:18;;;75495:2;75480:18;;36747;;;;75578:2;75563:18;;36747;;;;75661:2;75646:18;;36747;75744:3;75729:19;;36747:18;75330:3;75315:19;;75301:458;75766:256;75828:2;75822:9;75854:17;;;75929:18;75914:34;;75950:22;;;75911:62;75908:2;;;75986:1;;75976:12;75908:2;75828;75995:22;75806:216;;-1:-1;75806:216;81666:117;-1:-1;;;;;78842:54;;81725:35;;81715:2;;81774:1;;81764:12;81790:111;81871:5;78754:13;78747:21;81849:5;81846:32;81836:2;;81892:1;;81882:12
Swarm Source
ipfs://a7e19740a045ca277745868a9ac88b87f050c6954895e10f38c411c53312ad6f
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.