My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Contract Name:
Router
Compiler Version
v0.7.6+commit.7338295f
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; pragma abicoder v2; // imports import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "./Factory.sol"; import "./Pool.sol"; import "./Bridge.sol"; // interfaces import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./interfaces/IStargateRouter.sol"; import "./interfaces/IStargateReceiver.sol"; // libraries import "@openzeppelin/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts/utils/Address.sol"; contract Router is IStargateRouter, Ownable, ReentrancyGuard { using SafeMath for uint256; //--------------------------------------------------------------------------- // CONSTANTS uint8 internal constant TYPE_REDEEM_LOCAL_RESPONSE = 1; uint8 internal constant TYPE_REDEEM_LOCAL_CALLBACK_RETRY = 2; uint8 internal constant TYPE_SWAP_REMOTE_RETRY = 3; //--------------------------------------------------------------------------- // STRUCTS struct CachedSwap { address token; uint256 amountLD; address to; bytes payload; } //--------------------------------------------------------------------------- // VARIABLES Factory public factory; // used for creating pools address public protocolFeeOwner; // can call methods to pull Stargate fees collected in pools address public mintFeeOwner; // can call methods to pull mint fees collected in pools Bridge public bridge; mapping(uint16 => mapping(bytes => mapping(uint256 => bytes))) public revertLookup; //[chainId][srcAddress][nonce] mapping(uint16 => mapping(bytes => mapping(uint256 => CachedSwap))) public cachedSwapLookup; //[chainId][srcAddress][nonce] //--------------------------------------------------------------------------- // EVENTS event Revert(uint8 bridgeFunctionType, uint16 chainId, bytes srcAddress, uint256 nonce); event CachedSwapSaved( uint16 chainId, bytes srcAddress, uint256 nonce, address token, uint256 amountLD, address to, bytes payload, bytes reason ); event RevertRedeemLocal( uint16 srcChainId, uint256 _srcPoolId, uint256 _dstPoolId, bytes to, uint256 redeemAmountSD, uint256 mintAmountSD, uint256 indexed nonce, bytes indexed srcAddress ); event RedeemLocalCallback( uint16 srcChainId, bytes indexed srcAddress, uint256 indexed nonce, uint256 srcPoolId, uint256 dstPoolId, address to, uint256 amountSD, uint256 mintAmountSD ); //--------------------------------------------------------------------------- // MODIFIERS modifier onlyBridge() { require(msg.sender == address(bridge), "Bridge: caller must be Bridge."); _; } constructor() {} function setBridgeAndFactory(Bridge _bridge, Factory _factory) external onlyOwner { require(address(bridge) == address(0x0) && address(factory) == address(0x0), "Stargate: bridge and factory already initialized"); // 1 time only require(address(_bridge) != address(0x0), "Stargate: bridge cant be 0x0"); require(address(_factory) != address(0x0), "Stargate: factory cant be 0x0"); bridge = _bridge; factory = _factory; } //--------------------------------------------------------------------------- // VIEWS function _getPool(uint256 _poolId) internal view returns (Pool pool) { pool = factory.getPool(_poolId); require(address(pool) != address(0x0), "Stargate: Pool does not exist"); } //--------------------------------------------------------------------------- // INTERNAL function _safeTransferFrom( address token, address from, address to, uint256 value ) private { // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), "Stargate: TRANSFER_FROM_FAILED"); } //--------------------------------------------------------------------------- // LOCAL CHAIN FUNCTIONS function addLiquidity( uint256 _poolId, uint256 _amountLD, address _to ) external override nonReentrant { Pool pool = _getPool(_poolId); uint256 convertRate = pool.convertRate(); _amountLD = _amountLD.div(convertRate).mul(convertRate); _safeTransferFrom(pool.token(), msg.sender, address(pool), _amountLD); pool.mint(_to, _amountLD); } function swap( uint16 _dstChainId, uint256 _srcPoolId, uint256 _dstPoolId, address payable _refundAddress, uint256 _amountLD, uint256 _minAmountLD, lzTxObj memory _lzTxParams, bytes calldata _to, bytes calldata _payload ) external payable override nonReentrant { require(_amountLD > 0, "Stargate: cannot swap 0"); require(_refundAddress != address(0x0), "Stargate: _refundAddress cannot be 0x0"); Pool.SwapObj memory s; Pool.CreditObj memory c; { Pool pool = _getPool(_srcPoolId); { uint256 convertRate = pool.convertRate(); _amountLD = _amountLD.div(convertRate).mul(convertRate); } s = pool.swap(_dstChainId, _dstPoolId, msg.sender, _amountLD, _minAmountLD, true); _safeTransferFrom(pool.token(), msg.sender, address(pool), _amountLD); c = pool.sendCredits(_dstChainId, _dstPoolId); } bridge.swap{value: msg.value}(_dstChainId, _srcPoolId, _dstPoolId, _refundAddress, c, s, _lzTxParams, _to, _payload); } function redeemRemote( uint16 _dstChainId, uint256 _srcPoolId, uint256 _dstPoolId, address payable _refundAddress, uint256 _amountLP, uint256 _minAmountLD, bytes calldata _to, lzTxObj memory _lzTxParams ) external payable override nonReentrant { require(_refundAddress != address(0x0), "Stargate: _refundAddress cannot be 0x0"); require(_amountLP > 0, "Stargate: not enough lp to redeemRemote"); Pool.SwapObj memory s; Pool.CreditObj memory c; { Pool pool = _getPool(_srcPoolId); uint256 amountLD = pool.amountLPtoLD(_amountLP); // perform a swap with no liquidity s = pool.swap(_dstChainId, _dstPoolId, msg.sender, amountLD, _minAmountLD, false); pool.redeemRemote(_dstChainId, _dstPoolId, msg.sender, _amountLP); c = pool.sendCredits(_dstChainId, _dstPoolId); } // equal to a swap, with no payload ("0x") no dstGasForCall 0 bridge.swap{value: msg.value}(_dstChainId, _srcPoolId, _dstPoolId, _refundAddress, c, s, _lzTxParams, _to, ""); } function instantRedeemLocal( uint16 _srcPoolId, uint256 _amountLP, address _to ) external override nonReentrant returns (uint256 amountSD) { require(_amountLP > 0, "Stargate: not enough lp to redeem"); Pool pool = _getPool(_srcPoolId); amountSD = pool.instantRedeemLocal(msg.sender, _amountLP, _to); } function redeemLocal( uint16 _dstChainId, uint256 _srcPoolId, uint256 _dstPoolId, address payable _refundAddress, uint256 _amountLP, bytes calldata _to, lzTxObj memory _lzTxParams ) external payable override nonReentrant { require(_refundAddress != address(0x0), "Stargate: _refundAddress cannot be 0x0"); Pool pool = _getPool(_srcPoolId); require(_amountLP > 0, "Stargate: not enough lp to redeem"); uint256 amountSD = pool.redeemLocal(msg.sender, _amountLP, _dstChainId, _dstPoolId, _to); require(amountSD > 0, "Stargate: not enough lp to redeem with amountSD"); Pool.CreditObj memory c = pool.sendCredits(_dstChainId, _dstPoolId); bridge.redeemLocal{value: msg.value}(_dstChainId, _srcPoolId, _dstPoolId, _refundAddress, c, amountSD, _to, _lzTxParams); } function sendCredits( uint16 _dstChainId, uint256 _srcPoolId, uint256 _dstPoolId, address payable _refundAddress ) external payable override nonReentrant { require(_refundAddress != address(0x0), "Stargate: _refundAddress cannot be 0x0"); Pool pool = _getPool(_srcPoolId); Pool.CreditObj memory c = pool.sendCredits(_dstChainId, _dstPoolId); bridge.sendCredits{value: msg.value}(_dstChainId, _srcPoolId, _dstPoolId, _refundAddress, c); } function quoteLayerZeroFee( uint16 _dstChainId, uint8 _functionType, bytes calldata _toAddress, bytes calldata _transferAndCallPayload, Router.lzTxObj memory _lzTxParams ) external view override returns (uint256, uint256) { return bridge.quoteLayerZeroFee(_dstChainId, _functionType, _toAddress, _transferAndCallPayload, _lzTxParams); } function revertRedeemLocal( uint16 _dstChainId, bytes calldata _srcAddress, uint256 _nonce, address payable _refundAddress, lzTxObj memory _lzTxParams ) external payable { require(_refundAddress != address(0x0), "Stargate: _refundAddress cannot be 0x0"); bytes memory payload = revertLookup[_dstChainId][_srcAddress][_nonce]; require(payload.length > 0, "Stargate: no retry revert"); { uint8 functionType; assembly { functionType := mload(add(payload, 32)) } require(functionType == TYPE_REDEEM_LOCAL_RESPONSE, "Stargate: invalid function type"); } // empty it revertLookup[_dstChainId][_srcAddress][_nonce] = ""; uint256 srcPoolId; uint256 dstPoolId; assembly { srcPoolId := mload(add(payload, 64)) dstPoolId := mload(add(payload, 96)) } Pool.CreditObj memory c; { Pool pool = _getPool(dstPoolId); c = pool.sendCredits(_dstChainId, srcPoolId); } bridge.redeemLocalCallback{value: msg.value}(_dstChainId, _refundAddress, c, _lzTxParams, payload); } function retryRevert( uint16 _srcChainId, bytes calldata _srcAddress, uint256 _nonce ) external payable { bytes memory payload = revertLookup[_srcChainId][_srcAddress][_nonce]; require(payload.length > 0, "Stargate: no retry revert"); // empty it revertLookup[_srcChainId][_srcAddress][_nonce] = ""; uint8 functionType; assembly { functionType := mload(add(payload, 32)) } if (functionType == TYPE_REDEEM_LOCAL_CALLBACK_RETRY) { (, uint256 srcPoolId, uint256 dstPoolId, address to, uint256 amountSD, uint256 mintAmountSD) = abi.decode( payload, (uint8, uint256, uint256, address, uint256, uint256) ); _redeemLocalCallback(_srcChainId, _srcAddress, _nonce, srcPoolId, dstPoolId, to, amountSD, mintAmountSD); } // for retrying the swapRemote. if it fails again, retry else if (functionType == TYPE_SWAP_REMOTE_RETRY) { (, uint256 srcPoolId, uint256 dstPoolId, uint256 dstGasForCall, address to, Pool.SwapObj memory s, bytes memory p) = abi.decode( payload, (uint8, uint256, uint256, uint256, address, Pool.SwapObj, bytes) ); _swapRemote(_srcChainId, _srcAddress, _nonce, srcPoolId, dstPoolId, dstGasForCall, to, s, p); } else { revert("Stargate: invalid function type"); } } function clearCachedSwap( uint16 _srcChainId, bytes calldata _srcAddress, uint256 _nonce ) external { CachedSwap memory cs = cachedSwapLookup[_srcChainId][_srcAddress][_nonce]; require(cs.to != address(0x0), "Stargate: cache already cleared"); // clear the data cachedSwapLookup[_srcChainId][_srcAddress][_nonce] = CachedSwap(address(0x0), 0, address(0x0), ""); IStargateReceiver(cs.to).sgReceive(_srcChainId, _srcAddress, _nonce, cs.token, cs.amountLD, cs.payload); } function creditChainPath( uint16 _dstChainId, uint256 _dstPoolId, uint256 _srcPoolId, Pool.CreditObj memory _c ) external onlyBridge { Pool pool = _getPool(_srcPoolId); pool.creditChainPath(_dstChainId, _dstPoolId, _c); } //--------------------------------------------------------------------------- // REMOTE CHAIN FUNCTIONS function redeemLocalCheckOnRemote( uint16 _srcChainId, bytes memory _srcAddress, uint256 _nonce, uint256 _srcPoolId, uint256 _dstPoolId, uint256 _amountSD, bytes calldata _to ) external onlyBridge { Pool pool = _getPool(_dstPoolId); try pool.redeemLocalCheckOnRemote(_srcChainId, _srcPoolId, _amountSD) returns (uint256 redeemAmountSD, uint256 mintAmountSD) { revertLookup[_srcChainId][_srcAddress][_nonce] = abi.encode( TYPE_REDEEM_LOCAL_RESPONSE, _srcPoolId, _dstPoolId, redeemAmountSD, mintAmountSD, _to ); emit RevertRedeemLocal(_srcChainId, _srcPoolId, _dstPoolId, _to, redeemAmountSD, mintAmountSD, _nonce, _srcAddress); } catch { // if the func fail, return [swapAmount: 0, mintAMount: _amountSD] // swapAmount represents the amount of chainPath balance deducted on the remote side, which because the above tx failed, should be 0 // mintAmount is the full amount of tokens the user attempted to redeem on the src side, which gets converted back into the lp amount revertLookup[_srcChainId][_srcAddress][_nonce] = abi.encode(TYPE_REDEEM_LOCAL_RESPONSE, _srcPoolId, _dstPoolId, 0, _amountSD, _to); emit Revert(TYPE_REDEEM_LOCAL_RESPONSE, _srcChainId, _srcAddress, _nonce); } } function redeemLocalCallback( uint16 _srcChainId, bytes memory _srcAddress, uint256 _nonce, uint256 _srcPoolId, uint256 _dstPoolId, address _to, uint256 _amountSD, uint256 _mintAmountSD ) external onlyBridge { _redeemLocalCallback(_srcChainId, _srcAddress, _nonce, _srcPoolId, _dstPoolId, _to, _amountSD, _mintAmountSD); } function _redeemLocalCallback( uint16 _srcChainId, bytes memory _srcAddress, uint256 _nonce, uint256 _srcPoolId, uint256 _dstPoolId, address _to, uint256 _amountSD, uint256 _mintAmountSD ) internal { Pool pool = _getPool(_dstPoolId); try pool.redeemLocalCallback(_srcChainId, _srcPoolId, _to, _amountSD, _mintAmountSD) {} catch { revertLookup[_srcChainId][_srcAddress][_nonce] = abi.encode( TYPE_REDEEM_LOCAL_CALLBACK_RETRY, _srcPoolId, _dstPoolId, _to, _amountSD, _mintAmountSD ); emit Revert(TYPE_REDEEM_LOCAL_CALLBACK_RETRY, _srcChainId, _srcAddress, _nonce); } emit RedeemLocalCallback(_srcChainId, _srcAddress, _nonce, _srcPoolId, _dstPoolId, _to, _amountSD, _mintAmountSD); } function swapRemote( uint16 _srcChainId, bytes memory _srcAddress, uint256 _nonce, uint256 _srcPoolId, uint256 _dstPoolId, uint256 _dstGasForCall, address _to, Pool.SwapObj memory _s, bytes memory _payload ) external onlyBridge { _swapRemote(_srcChainId, _srcAddress, _nonce, _srcPoolId, _dstPoolId, _dstGasForCall, _to, _s, _payload); } function _swapRemote( uint16 _srcChainId, bytes memory _srcAddress, uint256 _nonce, uint256 _srcPoolId, uint256 _dstPoolId, uint256 _dstGasForCall, address _to, Pool.SwapObj memory _s, bytes memory _payload ) internal { Pool pool = _getPool(_dstPoolId); // first try catch the swap remote try pool.swapRemote(_srcChainId, _srcPoolId, _to, _s) returns (uint256 amountLD) { if (Address.isContract(_to) && _payload.length > 0) { // then try catch the external contract call try IStargateReceiver(_to).sgReceive{gas: _dstGasForCall}(_srcChainId, _srcAddress, _nonce, pool.token(), amountLD, _payload) { // do nothing } catch (bytes memory reason) { cachedSwapLookup[_srcChainId][_srcAddress][_nonce] = CachedSwap(pool.token(), amountLD, _to, _payload); emit CachedSwapSaved(_srcChainId, _srcAddress, _nonce, pool.token(), amountLD, _to, _payload, reason); } } } catch { revertLookup[_srcChainId][_srcAddress][_nonce] = abi.encode( TYPE_SWAP_REMOTE_RETRY, _srcPoolId, _dstPoolId, _dstGasForCall, _to, _s, _payload ); emit Revert(TYPE_SWAP_REMOTE_RETRY, _srcChainId, _srcAddress, _nonce); } } //--------------------------------------------------------------------------- // DAO Calls function createPool( uint256 _poolId, address _token, uint8 _sharedDecimals, uint8 _localDecimals, string memory _name, string memory _symbol ) external onlyOwner returns (address) { require(_token != address(0x0), "Stargate: _token cannot be 0x0"); return factory.createPool(_poolId, _token, _sharedDecimals, _localDecimals, _name, _symbol); } function createChainPath( uint256 _poolId, uint16 _dstChainId, uint256 _dstPoolId, uint256 _weight ) external onlyOwner { Pool pool = _getPool(_poolId); pool.createChainPath(_dstChainId, _dstPoolId, _weight); } function activateChainPath( uint256 _poolId, uint16 _dstChainId, uint256 _dstPoolId ) external onlyOwner { Pool pool = _getPool(_poolId); pool.activateChainPath(_dstChainId, _dstPoolId); } function setWeightForChainPath( uint256 _poolId, uint16 _dstChainId, uint256 _dstPoolId, uint16 _weight ) external onlyOwner { Pool pool = _getPool(_poolId); pool.setWeightForChainPath(_dstChainId, _dstPoolId, _weight); } function setProtocolFeeOwner(address _owner) external onlyOwner { require(_owner != address(0x0), "Stargate: _owner cannot be 0x0"); protocolFeeOwner = _owner; } function setMintFeeOwner(address _owner) external onlyOwner { require(_owner != address(0x0), "Stargate: _owner cannot be 0x0"); mintFeeOwner = _owner; } function setFees(uint256 _poolId, uint256 _mintFeeBP) external onlyOwner { Pool pool = _getPool(_poolId); pool.setFee(_mintFeeBP); } function setFeeLibrary(uint256 _poolId, address _feeLibraryAddr) external onlyOwner { Pool pool = _getPool(_poolId); pool.setFeeLibrary(_feeLibraryAddr); } function setSwapStop(uint256 _poolId, bool _swapStop) external onlyOwner { Pool pool = _getPool(_poolId); pool.setSwapStop(_swapStop); } function setDeltaParam( uint256 _poolId, bool _batched, uint256 _swapDeltaBP, uint256 _lpDeltaBP, bool _defaultSwapMode, bool _defaultLPMode ) external onlyOwner { Pool pool = _getPool(_poolId); pool.setDeltaParam(_batched, _swapDeltaBP, _lpDeltaBP, _defaultSwapMode, _defaultLPMode); } function callDelta(uint256 _poolId, bool _fullMode) external { Pool pool = _getPool(_poolId); pool.callDelta(_fullMode); } function withdrawMintFee(uint256 _poolId, address _to) external { require(mintFeeOwner == msg.sender, "Stargate: only mintFeeOwner"); Pool pool = _getPool(_poolId); pool.withdrawMintFeeBalance(_to); } function withdrawProtocolFee(uint256 _poolId, address _to) external { require(protocolFeeOwner == msg.sender, "Stargate: only protocolFeeOwner"); Pool pool = _getPool(_poolId); pool.withdrawProtocolFeeBalance(_to); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.5.0; interface ILayerZeroReceiver { // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.5.0; import "./ILayerZeroUserApplicationConfig.sol"; interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig { // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function send(uint16 _dstChainId, bytes calldata _destination, bytes calldata _payload, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable; // @notice used by the messaging library to publish verified payload // @param _srcChainId - the source chain identifier // @param _srcAddress - the source contract (as bytes) at the source chain // @param _dstAddress - the address on destination chain // @param _nonce - the unbound message ordering nonce // @param _gasLimit - the gas limit for external contract execution // @param _payload - verified payload to send to the destination contract function receivePayload(uint16 _srcChainId, bytes calldata _srcAddress, address _dstAddress, uint64 _nonce, uint _gasLimit, bytes calldata _payload) external; // @notice get the inboundNonce of a receiver from a source chain which could be EVM or non-EVM chain // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64); // @notice get the outboundNonce from this source chain which, consequently, is always an EVM // @param _srcAddress - the source chain contract address function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64); // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery // @param _dstChainId - the destination chain identifier // @param _userApplication - the user app address on this EVM chain // @param _payload - the custom message to send over LayerZero // @param _payInZRO - if false, user app pays the protocol fee in native token // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain function estimateFees(uint16 _dstChainId, address _userApplication, bytes calldata _payload, bool _payInZRO, bytes calldata _adapterParam) external view returns (uint nativeFee, uint zroFee); // @notice get this Endpoint's immutable source identifier function getChainId() external view returns (uint16); // @notice the interface to retry failed message on this Endpoint destination // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _payload - the payload to be retried function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external; // @notice query if any STORED payload (message blocking) at the endpoint. // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool); // @notice query if the _libraryAddress is valid for sending msgs. // @param _userApplication - the user app address on this EVM chain function getSendLibraryAddress(address _userApplication) external view returns (address); // @notice query if the _libraryAddress is valid for receiving msgs. // @param _userApplication - the user app address on this EVM chain function getReceiveLibraryAddress(address _userApplication) external view returns (address); // @notice query if the non-reentrancy guard for send() is on // @return true if the guard is on. false otherwise function isSendingPayload() external view returns (bool); // @notice query if the non-reentrancy guard for receive() is on // @return true if the guard is on. false otherwise function isReceivingPayload() external view returns (bool); // @notice get the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _userApplication - the contract address of the user application // @param _configType - type of configuration. every messaging library has its own convention. function getConfig(uint16 _version, uint16 _chainId, address _userApplication, uint _configType) external view returns (bytes memory); // @notice get the send() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getSendVersion(address _userApplication) external view returns (uint16); // @notice get the lzReceive() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getReceiveVersion(address _userApplication) external view returns (uint16); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.5.0; interface ILayerZeroUserApplicationConfig { // @notice set the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _configType - type of configuration. every messaging library has its own convention. // @param _config - configuration in the bytes. can encode arbitrary content. function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external; // @notice set the send() LayerZero messaging library version to _version // @param _version - new messaging library version function setSendVersion(uint16 _version) external; // @notice set the lzReceive() LayerZero messaging library version to _version // @param _version - new messaging library version function setReceiveVersion(uint16 _version) external; // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload // @param _srcChainId - the chainId of the source chain // @param _srcAddress - the contract address of the source contract at the source chain function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; // libraries import "@openzeppelin/contracts/math/SafeMath.sol"; contract LPTokenERC20 { using SafeMath for uint256; //--------------------------------------------------------------------------- // CONSTANTS string public name; string public symbol; bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; // set in constructor bytes32 public DOMAIN_SEPARATOR; //--------------------------------------------------------------------------- // VARIABLES uint256 public decimals; uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; mapping(address => uint256) public nonces; //--------------------------------------------------------------------------- // EVENTS event Approval(address indexed owner, address indexed spender, uint256 value); event Transfer(address indexed from, address indexed to, uint256 value); constructor(string memory _name, string memory _symbol) { name = _name; symbol = _symbol; uint256 chainId; assembly { chainId := chainid() } DOMAIN_SEPARATOR = keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256(bytes("1")), chainId, address(this) ) ); } function _mint(address to, uint256 value) internal { totalSupply = totalSupply.add(value); balanceOf[to] = balanceOf[to].add(value); emit Transfer(address(0), to, value); } function _burn(address from, uint256 value) internal { balanceOf[from] = balanceOf[from].sub(value); totalSupply = totalSupply.sub(value); emit Transfer(from, address(0), value); } function _approve( address owner, address spender, uint256 value ) private { allowance[owner][spender] = value; emit Approval(owner, spender, value); } function _transfer( address from, address to, uint256 value ) private { balanceOf[from] = balanceOf[from].sub(value); balanceOf[to] = balanceOf[to].add(value); emit Transfer(from, to, value); } function approve(address spender, uint256 value) external returns (bool) { _approve(msg.sender, spender, value); return true; } function transfer(address to, uint256 value) external returns (bool) { _transfer(msg.sender, to, value); return true; } function transferFrom( address from, address to, uint256 value ) external returns (bool) { if (allowance[from][msg.sender] != uint256(-1)) { allowance[from][msg.sender] = allowance[from][msg.sender].sub(value); } _transfer(from, to, value); return true; } function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(msg.sender, spender, allowance[msg.sender][spender].add(addedValue)); return true; } function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve(msg.sender, spender, allowance[msg.sender][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external { require(deadline >= block.timestamp, "Bridge: EXPIRED"); bytes32 digest = keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR, keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) ) ); address recoveredAddress = ecrecover(digest, v, r, s); require(recoveredAddress != address(0) && recoveredAddress == owner, "Bridge: INVALID_SIGNATURE"); _approve(owner, spender, value); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.7.6; pragma abicoder v2; import "../Pool.sol"; interface IStargateFeeLibrary { function getFees( uint256 _srcPoolId, uint256 _dstPoolId, uint16 _dstChainId, address _from, uint256 _amountSD ) external returns (Pool.SwapObj memory s); function getVersion() external view returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with 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 Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "../utils/Context.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. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { 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; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor () { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; pragma abicoder v2; import "@openzeppelin/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "./Pool.sol"; contract Factory is Ownable { using SafeMath for uint256; //--------------------------------------------------------------------------- // VARIABLES mapping(uint256 => Pool) public getPool; // poolId -> PoolInfo address[] public allPools; address public immutable router; address public defaultFeeLibrary; // address for retrieving fee params for swaps //--------------------------------------------------------------------------- // MODIFIERS modifier onlyRouter() { require(msg.sender == router, "Stargate: caller must be Router."); _; } constructor(address _router) { require(_router != address(0x0), "Stargate: _router cant be 0x0"); // 1 time only router = _router; } function setDefaultFeeLibrary(address _defaultFeeLibrary) external onlyOwner { require(_defaultFeeLibrary != address(0x0), "Stargate: fee library cant be 0x0"); defaultFeeLibrary = _defaultFeeLibrary; } function allPoolsLength() external view returns (uint256) { return allPools.length; } function createPool( uint256 _poolId, address _token, uint8 _sharedDecimals, uint8 _localDecimals, string memory _name, string memory _symbol ) public onlyRouter returns (address poolAddress) { require(address(getPool[_poolId]) == address(0x0), "Stargate: Pool already created"); Pool pool = new Pool(_poolId, router, _token, _sharedDecimals, _localDecimals, defaultFeeLibrary, _name, _symbol); getPool[_poolId] = pool; poolAddress = address(pool); allPools.push(poolAddress); } function renounceOwnership() public override onlyOwner {} }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; pragma abicoder v2; // imports import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "./LPTokenERC20.sol"; import "./interfaces/IStargateFeeLibrary.sol"; // libraries import "@openzeppelin/contracts/math/SafeMath.sol"; /// Pool contracts on other chains and managed by the Stargate protocol. contract Pool is LPTokenERC20, ReentrancyGuard { using SafeMath for uint256; //--------------------------------------------------------------------------- // CONSTANTS bytes4 private constant SELECTOR = bytes4(keccak256(bytes("transfer(address,uint256)"))); uint256 public constant BP_DENOMINATOR = 10000; //--------------------------------------------------------------------------- // STRUCTS struct ChainPath { bool ready; // indicate if the counter chainPath has been created. uint16 dstChainId; uint256 dstPoolId; uint256 weight; uint256 balance; uint256 lkb; uint256 credits; uint256 idealBalance; } struct SwapObj { uint256 amount; uint256 eqFee; uint256 eqReward; uint256 lpFee; uint256 protocolFee; uint256 lkbRemove; } struct CreditObj { uint256 credits; uint256 idealBalance; } //--------------------------------------------------------------------------- // VARIABLES // chainPath ChainPath[] public chainPaths; // list of connected chains with shared pools mapping(uint16 => mapping(uint256 => uint256)) public chainPathIndexLookup; // lookup for chainPath by chainId => poolId =>index // metadata uint256 public immutable poolId; // shared id between chains to represent same pool uint256 public sharedDecimals; // the shared decimals (lowest common decimals between chains) uint256 public localDecimals; // the decimals for the token uint256 public immutable convertRate; // the decimals for the token address public immutable token; // the token for the pool address public immutable router; // the token for the pool bool public stopSwap; // flag to stop swapping in extreme cases // Fee and Liquidity uint256 public totalLiquidity; // the total amount of tokens added on this side of the chain (fees + deposits - withdrawals) uint256 public totalWeight; // total weight for pool percentages uint256 public mintFeeBP; // fee basis points for the mint/deposit uint256 public protocolFeeBalance; // fee balance created from dao fee uint256 public mintFeeBalance; // fee balance created from mint fee uint256 public eqFeePool; // pool rewards in Shared Decimal format. indicate the total budget for reverse swap incentive address public feeLibrary; // address for retrieving fee params for swaps // Delta related uint256 public deltaCredit; // credits accumulated from txn bool public batched; // flag to indicate if we want batch processing. bool public defaultSwapMode; // flag for the default mode for swap bool public defaultLPMode; // flag for the default mode for lp uint256 public swapDeltaBP; // basis points of poolCredits to activate Delta in swap uint256 public lpDeltaBP; // basis points of poolCredits to activate Delta in liquidity events //--------------------------------------------------------------------------- // EVENTS event Mint(address to, uint256 amountLP, uint256 amountSD, uint256 mintFeeAmountSD); event Burn(address from, uint256 amountLP, uint256 amountSD); event RedeemLocalCallback(address _to, uint256 _amountSD, uint256 _amountToMintSD); event Swap( uint16 chainId, uint256 dstPoolId, address from, uint256 amountSD, uint256 eqReward, uint256 eqFee, uint256 protocolFee, uint256 lpFee ); event SendCredits(uint16 dstChainId, uint256 dstPoolId, uint256 credits, uint256 idealBalance); event RedeemRemote(uint16 chainId, uint256 dstPoolId, address from, uint256 amountLP, uint256 amountSD); event RedeemLocal(address from, uint256 amountLP, uint256 amountSD, uint16 chainId, uint256 dstPoolId, bytes to); event InstantRedeemLocal(address from, uint256 amountLP, uint256 amountSD, address to); event CreditChainPath(uint16 chainId, uint256 srcPoolId, uint256 amountSD, uint256 idealBalance); event SwapRemote(address to, uint256 amountSD, uint256 protocolFee, uint256 dstFee); event WithdrawRemote(uint16 srcChainId, uint256 srcPoolId, uint256 swapAmount, uint256 mintAmount); event ChainPathUpdate(uint16 dstChainId, uint256 dstPoolId, uint256 weight); event FeesUpdated(uint256 mintFeeBP); event FeeLibraryUpdated(address feeLibraryAddr); event StopSwapUpdated(bool swapStop); event WithdrawProtocolFeeBalance(address to, uint256 amountSD); event WithdrawMintFeeBalance(address to, uint256 amountSD); event DeltaParamUpdated(bool batched, uint256 swapDeltaBP, uint256 lpDeltaBP, bool defaultSwapMode, bool defaultLPMode); //--------------------------------------------------------------------------- // MODIFIERS modifier onlyRouter() { require(msg.sender == router, "Stargate: only the router can call this method"); _; } constructor( uint256 _poolId, address _router, address _token, uint256 _sharedDecimals, uint256 _localDecimals, address _feeLibrary, string memory _name, string memory _symbol ) LPTokenERC20(_name, _symbol) { require(_token != address(0x0), "Stargate: _token cannot be 0x0"); require(_router != address(0x0), "Stargate: _router cannot be 0x0"); poolId = _poolId; router = _router; token = _token; sharedDecimals = _sharedDecimals; decimals = uint8(_sharedDecimals); localDecimals = _localDecimals; convertRate = 10**(uint256(localDecimals).sub(sharedDecimals)); totalWeight = 0; feeLibrary = _feeLibrary; //delta algo related batched = false; defaultSwapMode = true; defaultLPMode = true; } function getChainPathsLength() public view returns (uint256) { return chainPaths.length; } //--------------------------------------------------------------------------- // LOCAL CHAIN FUNCTIONS function mint(address _to, uint256 _amountLD) external nonReentrant onlyRouter returns (uint256) { return _mintLocal(_to, _amountLD, true, true); } // Local Remote // ------- --------- // swap -> swapRemote function swap( uint16 _dstChainId, uint256 _dstPoolId, address _from, uint256 _amountLD, uint256 _minAmountLD, bool newLiquidity ) external nonReentrant onlyRouter returns (SwapObj memory) { require(!stopSwap, "Stargate: swap func stopped"); ChainPath storage cp = getAndCheckCP(_dstChainId, _dstPoolId); require(cp.ready == true, "Stargate: counter chainPath is not ready"); uint256 amountSD = amountLDtoSD(_amountLD); uint256 minAmountSD = amountLDtoSD(_minAmountLD); // request fee params from library SwapObj memory s = IStargateFeeLibrary(feeLibrary).getFees(poolId, _dstPoolId, _dstChainId, _from, amountSD); // equilibrium fee and reward. note eqFee/eqReward are separated from swap liquidity eqFeePool = eqFeePool.sub(s.eqReward); // update the new amount the user gets minus the fees s.amount = amountSD.sub(s.eqFee).sub(s.protocolFee).sub(s.lpFee); // users will also get the eqReward require(s.amount.add(s.eqReward) >= minAmountSD, "Stargate: slippage too high"); // behaviours // - protocolFee: booked, stayed and withdrawn at remote. // - eqFee: booked, stayed and withdrawn at remote. // - lpFee: booked and stayed at remote, can be withdrawn anywhere s.lkbRemove = amountSD.sub(s.lpFee).add(s.eqReward); // check for transfer solvency. require(cp.balance >= s.lkbRemove, "Stargate: dst balance too low"); cp.balance = cp.balance.sub(s.lkbRemove); if (newLiquidity) { deltaCredit = deltaCredit.add(amountSD).add(s.eqReward); } else if (s.eqReward > 0) { deltaCredit = deltaCredit.add(s.eqReward); } // distribute credits on condition. if (!batched || deltaCredit >= totalLiquidity.mul(swapDeltaBP).div(BP_DENOMINATOR)) { _delta(defaultSwapMode); } emit Swap(_dstChainId, _dstPoolId, _from, s.amount, s.eqReward, s.eqFee, s.protocolFee, s.lpFee); return s; } // Local Remote // ------- --------- // sendCredits -> creditChainPath function sendCredits(uint16 _dstChainId, uint256 _dstPoolId) external nonReentrant onlyRouter returns (CreditObj memory c) { ChainPath storage cp = getAndCheckCP(_dstChainId, _dstPoolId); require(cp.ready == true, "Stargate: counter chainPath is not ready"); cp.lkb = cp.lkb.add(cp.credits); c.idealBalance = totalLiquidity.mul(cp.weight).div(totalWeight); c.credits = cp.credits; cp.credits = 0; emit SendCredits(_dstChainId, _dstPoolId, c.credits, c.idealBalance); } // Local Remote // ------- --------- // redeemRemote -> swapRemote function redeemRemote( uint16 _dstChainId, uint256 _dstPoolId, address _from, uint256 _amountLP ) external nonReentrant onlyRouter { require(_from != address(0x0), "Stargate: _from cannot be 0x0"); uint256 amountSD = _burnLocal(_from, _amountLP); //run Delta if (!batched || deltaCredit > totalLiquidity.mul(lpDeltaBP).div(BP_DENOMINATOR)) { _delta(defaultLPMode); } uint256 amountLD = amountSDtoLD(amountSD); emit RedeemRemote(_dstChainId, _dstPoolId, _from, _amountLP, amountLD); } function instantRedeemLocal( address _from, uint256 _amountLP, address _to ) external nonReentrant onlyRouter returns (uint256 amountSD) { require(_from != address(0x0), "Stargate: _from cannot be 0x0"); uint256 _deltaCredit = deltaCredit; // sload optimization. uint256 _capAmountLP = _amountSDtoLP(_deltaCredit); if (_amountLP > _capAmountLP) _amountLP = _capAmountLP; amountSD = _burnLocal(_from, _amountLP); deltaCredit = _deltaCredit.sub(amountSD); uint256 amountLD = amountSDtoLD(amountSD); _safeTransfer(token, _to, amountLD); emit InstantRedeemLocal(_from, _amountLP, amountSD, _to); } // Local Remote // ------- --------- // redeemLocal -> redeemLocalCheckOnRemote // redeemLocalCallback <- function redeemLocal( address _from, uint256 _amountLP, uint16 _dstChainId, uint256 _dstPoolId, bytes calldata _to ) external nonReentrant onlyRouter returns (uint256 amountSD) { require(_from != address(0x0), "Stargate: _from cannot be 0x0"); // safeguard. require(chainPaths[chainPathIndexLookup[_dstChainId][_dstPoolId]].ready == true, "Stargate: counter chainPath is not ready"); amountSD = _burnLocal(_from, _amountLP); // run Delta if (!batched || deltaCredit > totalLiquidity.mul(lpDeltaBP).div(BP_DENOMINATOR)) { _delta(false); } emit RedeemLocal(_from, _amountLP, amountSD, _dstChainId, _dstPoolId, _to); } //--------------------------------------------------------------------------- // REMOTE CHAIN FUNCTIONS // Local Remote // ------- --------- // sendCredits -> creditChainPath function creditChainPath( uint16 _dstChainId, uint256 _dstPoolId, CreditObj memory _c ) external nonReentrant onlyRouter { ChainPath storage cp = chainPaths[chainPathIndexLookup[_dstChainId][_dstPoolId]]; cp.balance = cp.balance.add(_c.credits); if (cp.idealBalance != _c.idealBalance) { cp.idealBalance = _c.idealBalance; } emit CreditChainPath(_dstChainId, _dstPoolId, _c.credits, _c.idealBalance); } // Local Remote // ------- --------- // swap -> swapRemote function swapRemote( uint16 _srcChainId, uint256 _srcPoolId, address _to, SwapObj memory _s ) external nonReentrant onlyRouter returns (uint256 amountLD) { // booking lpFee totalLiquidity = totalLiquidity.add(_s.lpFee); // booking eqFee eqFeePool = eqFeePool.add(_s.eqFee); // booking stargateFee protocolFeeBalance = protocolFeeBalance.add(_s.protocolFee); // update LKB uint256 chainPathIndex = chainPathIndexLookup[_srcChainId][_srcPoolId]; chainPaths[chainPathIndex].lkb = chainPaths[chainPathIndex].lkb.sub(_s.lkbRemove); // user receives the amount + the srcReward amountLD = amountSDtoLD(_s.amount.add(_s.eqReward)); _safeTransfer(token, _to, amountLD); emit SwapRemote(_to, _s.amount.add(_s.eqReward), _s.protocolFee, _s.eqFee); } // Local Remote // ------- --------- // redeemLocal -> redeemLocalCheckOnRemote // redeemLocalCallback <- function redeemLocalCallback( uint16 _srcChainId, uint256 _srcPoolId, address _to, uint256 _amountSD, uint256 _amountToMintSD ) external nonReentrant onlyRouter { if (_amountToMintSD > 0) { _mintLocal(_to, amountSDtoLD(_amountToMintSD), false, false); } ChainPath storage cp = getAndCheckCP(_srcChainId, _srcPoolId); cp.lkb = cp.lkb.sub(_amountSD); uint256 amountLD = amountSDtoLD(_amountSD); _safeTransfer(token, _to, amountLD); emit RedeemLocalCallback(_to, _amountSD, _amountToMintSD); } // Local Remote // ------- --------- // redeemLocal(amount) -> redeemLocalCheckOnRemote // redeemLocalCallback <- function redeemLocalCheckOnRemote( uint16 _srcChainId, uint256 _srcPoolId, uint256 _amountSD ) external nonReentrant onlyRouter returns (uint256 swapAmount, uint256 mintAmount) { ChainPath storage cp = getAndCheckCP(_srcChainId, _srcPoolId); if (_amountSD > cp.balance) { mintAmount = _amountSD - cp.balance; swapAmount = cp.balance; cp.balance = 0; } else { cp.balance = cp.balance.sub(_amountSD); swapAmount = _amountSD; mintAmount = 0; } emit WithdrawRemote(_srcChainId, _srcPoolId, swapAmount, mintAmount); } //--------------------------------------------------------------------------- // DAO Calls function createChainPath( uint16 _dstChainId, uint256 _dstPoolId, uint256 _weight ) external onlyRouter { for (uint256 i = 0; i < chainPaths.length; ++i) { ChainPath memory cp = chainPaths[i]; bool exists = cp.dstChainId == _dstChainId && cp.dstPoolId == _dstPoolId; require(!exists, "Stargate: cant createChainPath of existing dstChainId and _dstPoolId"); } totalWeight = totalWeight.add(_weight); chainPathIndexLookup[_dstChainId][_dstPoolId] = chainPaths.length; chainPaths.push(ChainPath(false, _dstChainId, _dstPoolId, _weight, 0, 0, 0, 0)); emit ChainPathUpdate(_dstChainId, _dstPoolId, _weight); } function setWeightForChainPath( uint16 _dstChainId, uint256 _dstPoolId, uint16 _weight ) external onlyRouter { ChainPath storage cp = getAndCheckCP(_dstChainId, _dstPoolId); totalWeight = totalWeight.sub(cp.weight).add(_weight); cp.weight = _weight; emit ChainPathUpdate(_dstChainId, _dstPoolId, _weight); } function setFee(uint256 _mintFeeBP) external onlyRouter { require(_mintFeeBP <= BP_DENOMINATOR, "Bridge: cum fees > 100%"); mintFeeBP = _mintFeeBP; emit FeesUpdated(mintFeeBP); } function setFeeLibrary(address _feeLibraryAddr) external onlyRouter { require(_feeLibraryAddr != address(0x0), "Stargate: fee library cant be 0x0"); feeLibrary = _feeLibraryAddr; emit FeeLibraryUpdated(_feeLibraryAddr); } function setSwapStop(bool _swapStop) external onlyRouter { stopSwap = _swapStop; emit StopSwapUpdated(_swapStop); } function setDeltaParam( bool _batched, uint256 _swapDeltaBP, uint256 _lpDeltaBP, bool _defaultSwapMode, bool _defaultLPMode ) external onlyRouter { require(_swapDeltaBP <= BP_DENOMINATOR && _lpDeltaBP <= BP_DENOMINATOR, "Stargate: wrong Delta param"); batched = _batched; swapDeltaBP = _swapDeltaBP; lpDeltaBP = _lpDeltaBP; defaultSwapMode = _defaultSwapMode; defaultLPMode = _defaultLPMode; emit DeltaParamUpdated(_batched, _swapDeltaBP, _lpDeltaBP, _defaultSwapMode, _defaultLPMode); } function callDelta(bool _fullMode) external onlyRouter { _delta(_fullMode); } function activateChainPath(uint16 _dstChainId, uint256 _dstPoolId) external onlyRouter { ChainPath storage cp = getAndCheckCP(_dstChainId, _dstPoolId); require(cp.ready == false, "Stargate: chainPath is already active"); // this func will only be called once cp.ready = true; } function withdrawProtocolFeeBalance(address _to) external onlyRouter { if (protocolFeeBalance > 0) { uint256 amountOfLD = amountSDtoLD(protocolFeeBalance); protocolFeeBalance = 0; _safeTransfer(token, _to, amountOfLD); emit WithdrawProtocolFeeBalance(_to, amountOfLD); } } function withdrawMintFeeBalance(address _to) external onlyRouter { if (mintFeeBalance > 0) { uint256 amountOfLD = amountSDtoLD(mintFeeBalance); mintFeeBalance = 0; _safeTransfer(token, _to, amountOfLD); emit WithdrawMintFeeBalance(_to, amountOfLD); } } //--------------------------------------------------------------------------- // INTERNAL // Conversion Helpers //--------------------------------------------------------------------------- function amountLPtoLD(uint256 _amountLP) external view returns (uint256) { return amountSDtoLD(_amountLPtoSD(_amountLP)); } function _amountLPtoSD(uint256 _amountLP) internal view returns (uint256) { require(totalSupply > 0, "Stargate: cant convert LPtoSD when totalSupply == 0"); return _amountLP.mul(totalLiquidity).div(totalSupply); } function _amountSDtoLP(uint256 _amountSD) internal view returns (uint256) { require(totalLiquidity > 0, "Stargate: cant convert SDtoLP when totalLiq == 0"); return _amountSD.mul(totalSupply).div(totalLiquidity); } function amountSDtoLD(uint256 _amount) internal view returns (uint256) { return _amount.mul(convertRate); } function amountLDtoSD(uint256 _amount) internal view returns (uint256) { return _amount.div(convertRate); } function getAndCheckCP(uint16 _dstChainId, uint256 _dstPoolId) internal view returns (ChainPath storage) { require(chainPaths.length > 0, "Stargate: no chainpaths exist"); ChainPath storage cp = chainPaths[chainPathIndexLookup[_dstChainId][_dstPoolId]]; require(cp.dstChainId == _dstChainId && cp.dstPoolId == _dstPoolId, "Stargate: local chainPath does not exist"); return cp; } function getChainPath(uint16 _dstChainId, uint256 _dstPoolId) external view returns (ChainPath memory) { ChainPath memory cp = chainPaths[chainPathIndexLookup[_dstChainId][_dstPoolId]]; require(cp.dstChainId == _dstChainId && cp.dstPoolId == _dstPoolId, "Stargate: local chainPath does not exist"); return cp; } function _burnLocal(address _from, uint256 _amountLP) internal returns (uint256) { require(totalSupply > 0, "Stargate: cant burn when totalSupply == 0"); uint256 amountOfLPTokens = balanceOf[_from]; require(amountOfLPTokens >= _amountLP, "Stargate: not enough LP tokens to burn"); uint256 amountSD = _amountLP.mul(totalLiquidity).div(totalSupply); //subtract totalLiquidity accordingly totalLiquidity = totalLiquidity.sub(amountSD); _burn(_from, _amountLP); emit Burn(_from, _amountLP, amountSD); return amountSD; } function _delta(bool fullMode) internal { if (deltaCredit > 0 && totalWeight > 0) { uint256 cpLength = chainPaths.length; uint256[] memory deficit = new uint256[](cpLength); uint256 totalDeficit = 0; // algorithm steps 6-9: calculate the total and the amounts required to get to balance state for (uint256 i = 0; i < cpLength; ++i) { ChainPath storage cp = chainPaths[i]; // (liquidity * (weight/totalWeight)) - (lkb+credits) uint256 balLiq = totalLiquidity.mul(cp.weight).div(totalWeight); uint256 currLiq = cp.lkb.add(cp.credits); if (balLiq > currLiq) { // save gas since we know balLiq > currLiq and we know deficit[i] > 0 deficit[i] = balLiq - currLiq; totalDeficit = totalDeficit.add(deficit[i]); } } // indicates how much delta credit is distributed uint256 spent; // handle credits with 2 tranches. the [ < totalDeficit] [excessCredit] // run full Delta, allocate all credits if (totalDeficit == 0) { // only fullMode delta will allocate excess credits if (fullMode && deltaCredit > 0) { // credit ChainPath by weights for (uint256 i = 0; i < cpLength; ++i) { ChainPath storage cp = chainPaths[i]; // credits = credits + toBalanceChange + remaining allocation based on weight uint256 amtToCredit = deltaCredit.mul(cp.weight).div(totalWeight); spent = spent.add(amtToCredit); cp.credits = cp.credits.add(amtToCredit); } } // else do nth } else if (totalDeficit <= deltaCredit) { if (fullMode) { // algorithm step 13: calculate amount to disperse to bring to balance state or as close as possible uint256 excessCredit = deltaCredit - totalDeficit; // algorithm steps 14-16: calculate credits for (uint256 i = 0; i < cpLength; ++i) { if (deficit[i] > 0) { ChainPath storage cp = chainPaths[i]; // credits = credits + deficit + remaining allocation based on weight uint256 amtToCredit = deficit[i].add(excessCredit.mul(cp.weight).div(totalWeight)); spent = spent.add(amtToCredit); cp.credits = cp.credits.add(amtToCredit); } } } else { // totalDeficit <= deltaCredit but not running fullMode // credit chainPaths as is if any deficit, not using all deltaCredit for (uint256 i = 0; i < cpLength; ++i) { if (deficit[i] > 0) { ChainPath storage cp = chainPaths[i]; uint256 amtToCredit = deficit[i]; spent = spent.add(amtToCredit); cp.credits = cp.credits.add(amtToCredit); } } } } else { // totalDeficit > deltaCredit, fullMode or not, normalize the deficit by deltaCredit for (uint256 i = 0; i < cpLength; ++i) { if (deficit[i] > 0) { ChainPath storage cp = chainPaths[i]; uint256 proportionalDeficit = deficit[i].mul(deltaCredit).div(totalDeficit); spent = spent.add(proportionalDeficit); cp.credits = cp.credits.add(proportionalDeficit); } } } // deduct the amount of credit sent deltaCredit = deltaCredit.sub(spent); } } function _mintLocal( address _to, uint256 _amountLD, bool _feesEnabled, bool _creditDelta ) internal returns (uint256 amountSD) { require(totalWeight > 0, "Stargate: No ChainPaths exist"); amountSD = amountLDtoSD(_amountLD); uint256 mintFeeSD = 0; if (_feesEnabled) { mintFeeSD = amountSD.mul(mintFeeBP).div(BP_DENOMINATOR); amountSD = amountSD.sub(mintFeeSD); mintFeeBalance = mintFeeBalance.add(mintFeeSD); } if (_creditDelta) { deltaCredit = deltaCredit.add(amountSD); } uint256 amountLPTokens = amountSD; if (totalSupply != 0) { amountLPTokens = amountSD.mul(totalSupply).div(totalLiquidity); } totalLiquidity = totalLiquidity.add(amountSD); _mint(_to, amountLPTokens); emit Mint(_to, amountLPTokens, amountSD, mintFeeSD); // add to credits and call delta. short circuit to save gas if (!batched || deltaCredit > totalLiquidity.mul(lpDeltaBP).div(BP_DENOMINATOR)) { _delta(defaultLPMode); } } function _safeTransfer( address _token, address _to, uint256 _value ) private { (bool success, bytes memory data) = _token.call(abi.encodeWithSelector(SELECTOR, _to, _value)); require(success && (data.length == 0 || abi.decode(data, (bool))), "Stargate: TRANSFER_FAILED"); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; pragma abicoder v2; // imports import "@openzeppelin/contracts/access/Ownable.sol"; import "./Pool.sol"; import "./Router.sol"; // interfaces import "@layerzerolabs/layerzero-core/contracts/interfaces/ILayerZeroReceiver.sol"; import "@layerzerolabs/layerzero-core/contracts/interfaces/ILayerZeroEndpoint.sol"; import "@layerzerolabs/layerzero-core/contracts/interfaces/ILayerZeroUserApplicationConfig.sol"; // libraries import "@openzeppelin/contracts/math/SafeMath.sol"; contract Bridge is Ownable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig { using SafeMath for uint256; //--------------------------------------------------------------------------- // CONSTANTS uint8 internal constant TYPE_SWAP_REMOTE = 1; uint8 internal constant TYPE_ADD_LIQUIDITY = 2; uint8 internal constant TYPE_REDEEM_LOCAL_CALL_BACK = 3; uint8 internal constant TYPE_WITHDRAW_REMOTE = 4; //--------------------------------------------------------------------------- // VARIABLES ILayerZeroEndpoint public immutable layerZeroEndpoint; mapping(uint16 => bytes) public bridgeLookup; mapping(uint16 => mapping(uint8 => uint256)) public gasLookup; Router public immutable router; bool public useLayerZeroToken; //--------------------------------------------------------------------------- // EVENTS event SendMsg(uint8 msgType, uint64 nonce); //--------------------------------------------------------------------------- // MODIFIERS modifier onlyRouter() { require(msg.sender == address(router), "Stargate: caller must be Router."); _; } constructor(address _layerZeroEndpoint, address _router) { require(_layerZeroEndpoint != address(0x0), "Stargate: _layerZeroEndpoint cannot be 0x0"); require(_router != address(0x0), "Stargate: _router cannot be 0x0"); layerZeroEndpoint = ILayerZeroEndpoint(_layerZeroEndpoint); router = Router(_router); } //--------------------------------------------------------------------------- // EXTERNAL functions function lzReceive( uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload ) external override { require(msg.sender == address(layerZeroEndpoint), "Stargate: only LayerZero endpoint can call lzReceive"); require( _srcAddress.length == bridgeLookup[_srcChainId].length && keccak256(_srcAddress) == keccak256(bridgeLookup[_srcChainId]), "Stargate: bridge does not match" ); uint8 functionType; assembly { functionType := mload(add(_payload, 32)) } if (functionType == TYPE_SWAP_REMOTE) { ( , uint256 srcPoolId, uint256 dstPoolId, uint256 dstGasForCall, Pool.CreditObj memory c, Pool.SwapObj memory s, bytes memory to, bytes memory payload ) = abi.decode(_payload, (uint8, uint256, uint256, uint256, Pool.CreditObj, Pool.SwapObj, bytes, bytes)); address toAddress; assembly { toAddress := mload(add(to, 20)) } router.creditChainPath(_srcChainId, srcPoolId, dstPoolId, c); router.swapRemote(_srcChainId, _srcAddress, _nonce, srcPoolId, dstPoolId, dstGasForCall, toAddress, s, payload); } else if (functionType == TYPE_ADD_LIQUIDITY) { (, uint256 srcPoolId, uint256 dstPoolId, Pool.CreditObj memory c) = abi.decode(_payload, (uint8, uint256, uint256, Pool.CreditObj)); router.creditChainPath(_srcChainId, srcPoolId, dstPoolId, c); } else if (functionType == TYPE_REDEEM_LOCAL_CALL_BACK) { (, uint256 srcPoolId, uint256 dstPoolId, Pool.CreditObj memory c, uint256 amountSD, uint256 mintAmountSD, bytes memory to) = abi .decode(_payload, (uint8, uint256, uint256, Pool.CreditObj, uint256, uint256, bytes)); address toAddress; assembly { toAddress := mload(add(to, 20)) } router.creditChainPath(_srcChainId, srcPoolId, dstPoolId, c); router.redeemLocalCallback(_srcChainId, _srcAddress, _nonce, srcPoolId, dstPoolId, toAddress, amountSD, mintAmountSD); } else if (functionType == TYPE_WITHDRAW_REMOTE) { (, uint256 srcPoolId, uint256 dstPoolId, Pool.CreditObj memory c, uint256 amountSD, bytes memory to) = abi.decode( _payload, (uint8, uint256, uint256, Pool.CreditObj, uint256, bytes) ); router.creditChainPath(_srcChainId, srcPoolId, dstPoolId, c); router.redeemLocalCheckOnRemote(_srcChainId, _srcAddress, _nonce, srcPoolId, dstPoolId, amountSD, to); } } //--------------------------------------------------------------------------- // LOCAL CHAIN FUNCTIONS function swap( uint16 _chainId, uint256 _srcPoolId, uint256 _dstPoolId, address payable _refundAddress, Pool.CreditObj memory _c, Pool.SwapObj memory _s, IStargateRouter.lzTxObj memory _lzTxParams, bytes calldata _to, bytes calldata _payload ) external payable onlyRouter { bytes memory payload = abi.encode(TYPE_SWAP_REMOTE, _srcPoolId, _dstPoolId, _lzTxParams.dstGasForCall, _c, _s, _to, _payload); _call(_chainId, TYPE_SWAP_REMOTE, _refundAddress, _lzTxParams, payload); } function redeemLocalCallback( uint16 _chainId, address payable _refundAddress, Pool.CreditObj memory _c, IStargateRouter.lzTxObj memory _lzTxParams, bytes memory _payload ) external payable onlyRouter { bytes memory payload; { (, uint256 srcPoolId, uint256 dstPoolId, uint256 amountSD, uint256 mintAmountSD, bytes memory to) = abi.decode( _payload, (uint8, uint256, uint256, uint256, uint256, bytes) ); // swap dst and src because we are headed back payload = abi.encode(TYPE_REDEEM_LOCAL_CALL_BACK, dstPoolId, srcPoolId, _c, amountSD, mintAmountSD, to); } _call(_chainId, TYPE_REDEEM_LOCAL_CALL_BACK, _refundAddress, _lzTxParams, payload); } function redeemLocal( uint16 _chainId, uint256 _srcPoolId, uint256 _dstPoolId, address payable _refundAddress, Pool.CreditObj memory _c, uint256 _amountSD, bytes calldata _to, IStargateRouter.lzTxObj memory _lzTxParams ) external payable onlyRouter { bytes memory payload = abi.encode(TYPE_WITHDRAW_REMOTE, _srcPoolId, _dstPoolId, _c, _amountSD, _to); _call(_chainId, TYPE_WITHDRAW_REMOTE, _refundAddress, _lzTxParams, payload); } function sendCredits( uint16 _chainId, uint256 _srcPoolId, uint256 _dstPoolId, address payable _refundAddress, Pool.CreditObj memory _c ) external payable onlyRouter { bytes memory payload = abi.encode(TYPE_ADD_LIQUIDITY, _srcPoolId, _dstPoolId, _c); IStargateRouter.lzTxObj memory lzTxObj = IStargateRouter.lzTxObj(0, 0, "0x"); _call(_chainId, TYPE_ADD_LIQUIDITY, _refundAddress, lzTxObj, payload); } function quoteLayerZeroFee( uint16 _chainId, uint8 _functionType, bytes calldata _toAddress, bytes calldata _transferAndCallPayload, IStargateRouter.lzTxObj memory _lzTxParams ) external view returns (uint256, uint256) { bytes memory payload = ""; Pool.CreditObj memory c = Pool.CreditObj(1, 1); if (_functionType == TYPE_SWAP_REMOTE) { Pool.SwapObj memory s = Pool.SwapObj(1, 1, 1, 1, 1, 1); payload = abi.encode(TYPE_SWAP_REMOTE, 0, 0, 0, c, s, _toAddress, _transferAndCallPayload); } else if (_functionType == TYPE_ADD_LIQUIDITY) { payload = abi.encode(TYPE_ADD_LIQUIDITY, 0, 0, c); } else if (_functionType == TYPE_REDEEM_LOCAL_CALL_BACK) { payload = abi.encode(TYPE_REDEEM_LOCAL_CALL_BACK, 0, 0, c, 0, 0, _toAddress); } else if (_functionType == TYPE_WITHDRAW_REMOTE) { payload = abi.encode(TYPE_WITHDRAW_REMOTE, 0, 0, c, 0, _toAddress); } else { revert("Stargate: unsupported function type"); } bytes memory lzTxParamBuilt = _txParamBuilder(_chainId, _functionType, _lzTxParams); return layerZeroEndpoint.estimateFees(_chainId, address(this), payload, useLayerZeroToken, lzTxParamBuilt); } //--------------------------------------------------------------------------- // dao functions function setBridge(uint16 _chainId, bytes calldata _bridgeAddress) external onlyOwner { require(bridgeLookup[_chainId].length == 0, "Stargate: Bridge already set!"); bridgeLookup[_chainId] = _bridgeAddress; } function setGasAmount( uint16 _chainId, uint8 _functionType, uint256 _gasAmount ) external onlyOwner { require(_functionType >= 1 && _functionType <= 4, "Stargate: invalid _functionType"); gasLookup[_chainId][_functionType] = _gasAmount; } function approveTokenSpender( address token, address spender, uint256 amount ) external onlyOwner { IERC20(token).approve(spender, amount); } function setUseLayerZeroToken(bool enable) external onlyOwner { useLayerZeroToken = enable; } function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external override onlyOwner { layerZeroEndpoint.forceResumeReceive(_srcChainId, _srcAddress); } //--------------------------------------------------------------------------- // generic config for user Application function setConfig( uint16 _version, uint16 _chainId, uint256 _configType, bytes calldata _config ) external override onlyOwner { layerZeroEndpoint.setConfig(_version, _chainId, _configType, _config); } function setSendVersion(uint16 version) external override onlyOwner { layerZeroEndpoint.setSendVersion(version); } function setReceiveVersion(uint16 version) external override onlyOwner { layerZeroEndpoint.setReceiveVersion(version); } //--------------------------------------------------------------------------- // INTERNAL functions function txParamBuilderType1(uint256 _gasAmount) internal pure returns (bytes memory) { uint16 txType = 1; return abi.encodePacked(txType, _gasAmount); } function txParamBuilderType2( uint256 _gasAmount, uint256 _dstNativeAmount, bytes memory _dstNativeAddr ) internal pure returns (bytes memory) { uint16 txType = 2; return abi.encodePacked(txType, _gasAmount, _dstNativeAmount, _dstNativeAddr); } function _txParamBuilder( uint16 _chainId, uint8 _type, IStargateRouter.lzTxObj memory _lzTxParams ) internal view returns (bytes memory) { bytes memory lzTxParam; address dstNativeAddr; { bytes memory dstNativeAddrBytes = _lzTxParams.dstNativeAddr; assembly { dstNativeAddr := mload(add(dstNativeAddrBytes, 20)) } } uint256 totalGas = gasLookup[_chainId][_type].add(_lzTxParams.dstGasForCall); if (_lzTxParams.dstNativeAmount > 0 && dstNativeAddr != address(0x0)) { lzTxParam = txParamBuilderType2(totalGas, _lzTxParams.dstNativeAmount, _lzTxParams.dstNativeAddr); } else { lzTxParam = txParamBuilderType1(totalGas); } return lzTxParam; } function _call( uint16 _chainId, uint8 _type, address payable _refundAddress, IStargateRouter.lzTxObj memory _lzTxParams, bytes memory _payload ) internal { bytes memory lzTxParamBuilt = _txParamBuilder(_chainId, _type, _lzTxParams); uint64 nextNonce = layerZeroEndpoint.getOutboundNonce(_chainId, address(this)) + 1; layerZeroEndpoint.send{value: msg.value}(_chainId, bridgeLookup[_chainId], _payload, _refundAddress, address(this), lzTxParamBuilt); emit SendMsg(_type, nextNonce); } function renounceOwnership() public override onlyOwner {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; pragma abicoder v2; interface IStargateRouter { struct lzTxObj { uint256 dstGasForCall; uint256 dstNativeAmount; bytes dstNativeAddr; } function addLiquidity( uint256 _poolId, uint256 _amountLD, address _to ) external; function swap( uint16 _dstChainId, uint256 _srcPoolId, uint256 _dstPoolId, address payable _refundAddress, uint256 _amountLD, uint256 _minAmountLD, lzTxObj memory _lzTxParams, bytes calldata _to, bytes calldata _payload ) external payable; function redeemRemote( uint16 _dstChainId, uint256 _srcPoolId, uint256 _dstPoolId, address payable _refundAddress, uint256 _amountLP, uint256 _minAmountLD, bytes calldata _to, lzTxObj memory _lzTxParams ) external payable; function instantRedeemLocal( uint16 _srcPoolId, uint256 _amountLP, address _to ) external returns (uint256); function redeemLocal( uint16 _dstChainId, uint256 _srcPoolId, uint256 _dstPoolId, address payable _refundAddress, uint256 _amountLP, bytes calldata _to, lzTxObj memory _lzTxParams ) external payable; function sendCredits( uint16 _dstChainId, uint256 _srcPoolId, uint256 _dstPoolId, address payable _refundAddress ) external payable; function quoteLayerZeroFee( uint16 _dstChainId, uint8 _functionType, bytes calldata _toAddress, bytes calldata _transferAndCallPayload, lzTxObj memory _lzTxParams ) external view returns (uint256, uint256); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; interface IStargateReceiver { function sgReceive( uint16 _chainId, bytes memory _srcAddress, uint256 _nonce, address _token, uint256 amountLD, bytes memory payload ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @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, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, 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 (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @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) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @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) { 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, reverting 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) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting 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) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * 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); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * 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) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * 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; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "metadata": { "useLiteralContent": true } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountLD","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"bytes","name":"payload","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"reason","type":"bytes"}],"name":"CachedSwapSaved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"srcChainId","type":"uint16"},{"indexed":true,"internalType":"bytes","name":"srcAddress","type":"bytes"},{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"srcPoolId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"dstPoolId","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountSD","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mintAmountSD","type":"uint256"}],"name":"RedeemLocalCallback","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"bridgeFunctionType","type":"uint8"},{"indexed":false,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"Revert","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"srcChainId","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"to","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"redeemAmountSD","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mintAmountSD","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":true,"internalType":"bytes","name":"srcAddress","type":"bytes"}],"name":"RevertRedeemLocal","type":"event"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"}],"name":"activateChainPath","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"uint256","name":"_amountLD","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"addLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bridge","outputs":[{"internalType":"contract Bridge","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"cachedSwapLookup","outputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"payload","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"bool","name":"_fullMode","type":"bool"}],"name":"callDelta","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"}],"name":"clearCachedSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"uint256","name":"_weight","type":"uint256"}],"name":"createChainPath","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint8","name":"_sharedDecimals","type":"uint8"},{"internalType":"uint8","name":"_localDecimals","type":"uint8"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"name":"createPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"components":[{"internalType":"uint256","name":"credits","type":"uint256"},{"internalType":"uint256","name":"idealBalance","type":"uint256"}],"internalType":"struct Pool.CreditObj","name":"_c","type":"tuple"}],"name":"creditChainPath","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"contract Factory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcPoolId","type":"uint16"},{"internalType":"uint256","name":"_amountLP","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"instantRedeemLocal","outputs":[{"internalType":"uint256","name":"amountSD","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintFeeOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFeeOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint8","name":"_functionType","type":"uint8"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"bytes","name":"_transferAndCallPayload","type":"bytes"},{"components":[{"internalType":"uint256","name":"dstGasForCall","type":"uint256"},{"internalType":"uint256","name":"dstNativeAmount","type":"uint256"},{"internalType":"bytes","name":"dstNativeAddr","type":"bytes"}],"internalType":"struct IStargateRouter.lzTxObj","name":"_lzTxParams","type":"tuple"}],"name":"quoteLayerZeroFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"uint256","name":"_amountLP","type":"uint256"},{"internalType":"bytes","name":"_to","type":"bytes"},{"components":[{"internalType":"uint256","name":"dstGasForCall","type":"uint256"},{"internalType":"uint256","name":"dstNativeAmount","type":"uint256"},{"internalType":"bytes","name":"dstNativeAddr","type":"bytes"}],"internalType":"struct IStargateRouter.lzTxObj","name":"_lzTxParams","type":"tuple"}],"name":"redeemLocal","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amountSD","type":"uint256"},{"internalType":"uint256","name":"_mintAmountSD","type":"uint256"}],"name":"redeemLocalCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"uint256","name":"_amountSD","type":"uint256"},{"internalType":"bytes","name":"_to","type":"bytes"}],"name":"redeemLocalCheckOnRemote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"uint256","name":"_amountLP","type":"uint256"},{"internalType":"uint256","name":"_minAmountLD","type":"uint256"},{"internalType":"bytes","name":"_to","type":"bytes"},{"components":[{"internalType":"uint256","name":"dstGasForCall","type":"uint256"},{"internalType":"uint256","name":"dstNativeAmount","type":"uint256"},{"internalType":"bytes","name":"dstNativeAddr","type":"bytes"}],"internalType":"struct IStargateRouter.lzTxObj","name":"_lzTxParams","type":"tuple"}],"name":"redeemRemote","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"}],"name":"retryRevert","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"revertLookup","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"components":[{"internalType":"uint256","name":"dstGasForCall","type":"uint256"},{"internalType":"uint256","name":"dstNativeAmount","type":"uint256"},{"internalType":"bytes","name":"dstNativeAddr","type":"bytes"}],"internalType":"struct IStargateRouter.lzTxObj","name":"_lzTxParams","type":"tuple"}],"name":"revertRedeemLocal","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"}],"name":"sendCredits","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract Bridge","name":"_bridge","type":"address"},{"internalType":"contract Factory","name":"_factory","type":"address"}],"name":"setBridgeAndFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"bool","name":"_batched","type":"bool"},{"internalType":"uint256","name":"_swapDeltaBP","type":"uint256"},{"internalType":"uint256","name":"_lpDeltaBP","type":"uint256"},{"internalType":"bool","name":"_defaultSwapMode","type":"bool"},{"internalType":"bool","name":"_defaultLPMode","type":"bool"}],"name":"setDeltaParam","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"address","name":"_feeLibraryAddr","type":"address"}],"name":"setFeeLibrary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"uint256","name":"_mintFeeBP","type":"uint256"}],"name":"setFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setMintFeeOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setProtocolFeeOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"bool","name":"_swapStop","type":"bool"}],"name":"setSwapStop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"uint16","name":"_weight","type":"uint16"}],"name":"setWeightForChainPath","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"uint256","name":"_amountLD","type":"uint256"},{"internalType":"uint256","name":"_minAmountLD","type":"uint256"},{"components":[{"internalType":"uint256","name":"dstGasForCall","type":"uint256"},{"internalType":"uint256","name":"dstNativeAmount","type":"uint256"},{"internalType":"bytes","name":"dstNativeAddr","type":"bytes"}],"internalType":"struct IStargateRouter.lzTxObj","name":"_lzTxParams","type":"tuple"},{"internalType":"bytes","name":"_to","type":"bytes"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"swap","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstGasForCall","type":"uint256"},{"internalType":"address","name":"_to","type":"address"},{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"eqFee","type":"uint256"},{"internalType":"uint256","name":"eqReward","type":"uint256"},{"internalType":"uint256","name":"lpFee","type":"uint256"},{"internalType":"uint256","name":"protocolFee","type":"uint256"},{"internalType":"uint256","name":"lkbRemove","type":"uint256"}],"internalType":"struct Pool.SwapObj","name":"_s","type":"tuple"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"swapRemote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"withdrawMintFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"withdrawProtocolFee","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060006200001e62000072565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506001805562000076565b3390565b6151c980620000866000396000f3fe60806040526004361061021a5760003560e01c806387b21efc11610123578063c45a0155116100ab578063cefbdde21161006f578063cefbdde2146105dd578063da133a06146105fd578063e78cea921461062a578063f2fde38b1461063f578063fba6e2801461065f5761021a565b8063c45a01551461053b578063c4de93a514610550578063c6a276241461057d578063c7d968e31461059d578063c8adf12d146105bd5761021a565b80639ba3aa74116100f25780639ba3aa74146104cb5780639fbf10fc146104de578063a18fa804146104f1578063a96fbed414610511578063af640d82146105265761021a565b806387b21efc146104635780638da5cb5b146104835780638f2e1d181461049857806398e391a1146104ab5761021a565b806343a30630116101a6578063715018a611610175578063715018a6146103ce5780637af935a1146103e35780637b84d287146104105780637f7212981461043057806384d0dba3146104505761021a565b806343a30630146103685780635500585c1461038857806360a3b95c146103a85780636a7982da146103bb5761021a565b806323fd4647116101ed57806323fd4647146102b85780632f925555146102e857806334aba41014610308578063403a9f7a14610328578063424c9119146103485761021a565b80630403bce51461021f5780630a512369146102415780630b78f9c01461027857806316fb60f514610298575b600080fd5b34801561022b57600080fd5b5061023f61023a366004613b12565b61067f565b005b34801561024d57600080fd5b5061026161025c366004613ed5565b6108eb565b60405161026f929190614f2c565b60405180910390f35b34801561028457600080fd5b5061023f610293366004614193565b61098b565b3480156102a457600080fd5b5061023f6102b3366004614159565b610a5e565b3480156102c457600080fd5b506102d86102d336600461390f565b610b2c565b60405161026f94939291906144e3565b3480156102f457600080fd5b5061023f6103033660046139f1565b610c0b565b34801561031457600080fd5b5061023f610323366004613737565b610c46565b34801561033457600080fd5b5061023f610343366004613825565b610cf0565b34801561035457600080fd5b5061023f61036336600461378b565b610f23565b34801561037457600080fd5b5061023f61038336600461407a565b61103d565b34801561039457600080fd5b5061023f6103a3366004613f9f565b61111c565b61023f6103b6366004613825565b611180565b61023f6103c936600461387c565b6113fd565b3480156103da57600080fd5b5061023f6116ae565b3480156103ef57600080fd5b506104036103fe366004613fc3565b61175a565b60405161026f919061442b565b34801561041c57600080fd5b5061023f61042b366004614114565b61187d565b34801561043c57600080fd5b5061023f61044b366004613963565b61191d565b61023f61045e366004613cda565b611961565b34801561046f57600080fd5b5061023f61047e3660046141d7565b611c96565b34801561048f57600080fd5b50610403611e81565b61023f6104a6366004613c35565b611e90565b3480156104b757600080fd5b5061023f6104c6366004614056565b6120b1565b61023f6104d9366004613bee565b61214d565b61023f6104ec366004613d79565b6122c5565b3480156104fd57600080fd5b5061023f61050c366004613e59565b61261a565b34801561051d57600080fd5b50610403612682565b34801561053257600080fd5b50610403612691565b34801561054757600080fd5b506104036126a0565b34801561055c57600080fd5b5061057061056b366004613baf565b6126af565b60405161026f9190614ed6565b34801561058957600080fd5b5061023f610598366004613f9f565b6127ba565b3480156105a957600080fd5b5061023f6105b83660046140e0565b612856565b3480156105c957600080fd5b5061023f6105d8366004613f9f565b612922565b3480156105e957600080fd5b5061023f6105f8366004613737565b612986565b34801561060957600080fd5b5061061d61061836600461390f565b612a30565b60405161026f919061454a565b34801561063657600080fd5b50610403612aed565b34801561064b57600080fd5b5061023f61065a366004613737565b612afc565b34801561066b57600080fd5b5061023f61067a366004614056565b612bfe565b6005546001600160a01b031633146106b25760405162461bcd60e51b81526004016106a99061462b565b60405180910390fd5b60006106bd85612c38565b604051637544f15560e11b81529091506001600160a01b0382169063ea89e2aa906106f0908c908a908990600401614c2c565b6040805180830381600087803b15801561070957600080fd5b505af1925050508015610739575060408051601f3d908101601f19168201909252610736918101906141b4565b60015b6108025760018686600087878760405160200161075c9796959493929190614fa7565b60408051601f1981840301815282825261ffff8c166000908152600660205291909120909161078c908b9061440f565b9081526020016040518091039020600089815260200190815260200160002090805190602001906107be9291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60018a8a8a6040516107f59493929190614f3a565b60405180910390a16108e0565b6001888884848989604051602001610820979695949392919061502e565b60408051601f1981840301815282825261ffff8e1660009081526006602052919091209091610850908d9061440f565b908152602001604051809103902060008b815260200190815260200160002090805190602001906108829291906134af565b5089604051610891919061440f565b6040518091039020897f6ace246fa15cf1d5decabf654b1e8581a4422e0fcf4c1ed4bf83f41687caec198d8b8b8a8a89896040516108d59796959493929190614e48565b60405180910390a350505b505050505050505050565b600554604051630a51236960e01b815260009182916001600160a01b0390911690630a5123699061092c908c908c908c908c908c908c908c90600401614e88565b604080518083038186803b15801561094357600080fd5b505afa158015610957573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097b91906141b4565b9150915097509795505050505050565b610993612ce6565b6001600160a01b03166109a4611e81565b6001600160a01b0316146109ed576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006109f883612c38565b6040516369fe0e2d60e01b81529091506001600160a01b038216906369fe0e2d90610a27908590600401614ed6565b600060405180830381600087803b158015610a4157600080fd5b505af1158015610a55573d6000803e3d6000fd5b50505050505050565b610a66612ce6565b6001600160a01b0316610a77611e81565b6001600160a01b031614610ac0576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6000610acb85612c38565b6040516320d6bc7560e01b81529091506001600160a01b038216906320d6bc7590610afe90879087908790600401614c2c565b600060405180830381600087803b158015610b1857600080fd5b505af11580156108e0573d6000803e3d6000fd5b600760209081526000938452604080852084518086018401805192815290840195840195909520945292815290835291819020805460018083015460028085015460038601805488516101009682161596909602600019011692909204601f81018990048902850189019097528684526001600160a01b03948516979296941694939091830182828015610c015780601f10610bd657610100808354040283529160200191610c01565b820191906000526020600020905b815481529060010190602001808311610be457829003601f168201915b5050505050905084565b6005546001600160a01b03163314610c355760405162461bcd60e51b81526004016106a99061462b565b6108e0898989898989898989612cea565b610c4e612ce6565b6001600160a01b0316610c5f611e81565b6001600160a01b031614610ca8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116610cce5760405162461bcd60e51b81526004016106a99061483c565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b61ffff84166000908152600760205260408082209051610d1390869086906143ff565b9081526040805160209281900383018120600086815290845282902060808201835280546001600160a01b039081168352600180830154868501526002808401549092168486015260038301805486516101009382161593909302600019011692909204601f810187900487028201870190955284815292949193606086019392830182828015610de55780601f10610dba57610100808354040283529160200191610de5565b820191906000526020600020905b815481529060010190602001808311610dc857829003601f168201915b5050509190925250505060408101519091506001600160a01b0316610e1c5760405162461bcd60e51b81526004016106a990614873565b604080516080810182526000808252602080830182905282840182905283518082018552828152606084015261ffff89168252600790528290209151909190610e6890879087906143ff565b90815260408051602092819003830190206000868152908352819020835181546001600160a01b03199081166001600160a01b0392831617835585850151600184015592850151600283018054909416911617909155606083015180519192610ed9926003850192909101906134af565b505050604080820151825160208401516060850151935163ab8236f360e01b81526001600160a01b039093169363ab8236f393610afe938b938b938b938b939291906004016149e0565b610f2b612ce6565b6001600160a01b0316610f3c611e81565b6001600160a01b031614610f85576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6005546001600160a01b0316158015610fa757506002546001600160a01b0316155b610fc35760405162461bcd60e51b81526004016106a99061455d565b6001600160a01b038216610fe95760405162461bcd60e51b81526004016106a990614775565b6001600160a01b03811661100f5760405162461bcd60e51b81526004016106a990614707565b600580546001600160a01b039384166001600160a01b03199182161790915560028054929093169116179055565b611045612ce6565b6001600160a01b0316611056611e81565b6001600160a01b03161461109f576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006110aa87612c38565b60405163e065608b60e01b81529091506001600160a01b0382169063e065608b906110e19089908990899089908990600401614521565b600060405180830381600087803b1580156110fb57600080fd5b505af115801561110f573d6000803e3d6000fd5b5050505050505050505050565b6004546001600160a01b031633146111465760405162461bcd60e51b81526004016106a990614662565b600061115183612c38565b60405163011dbbf960e61b81529091506001600160a01b0382169063476efe4090610a2790859060040161442b565b61ffff841660009081526006602052604080822090516111a390869086906143ff565b90815260408051602092819003830181206000868152908452829020805460026001821615610100026000190190911604601f8101859004850283018501909352828252909290919083018282801561123d5780601f106112125761010080835404028352916020019161123d565b820191906000526020600020905b81548152906001019060200180831161122057829003601f168201915b5050505050905060008151116112655760405162461bcd60e51b81526004016106a990614699565b6040805160208082018352600080835261ffff891681526006909152829020915190919061129690879087906143ff565b9081526020016040518091039020600084815260200190815260200160002090805190602001906112c89291906134af565b50602081015160ff811660021415611353576000806000806000868060200190518101906112f69190614204565b95509550955095509550506113498b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508d92508a9150899050888888613166565b50505050506113f5565b60ff8116600314156113dd576000806000806000808780602001905181019061137c9190614263565b965096509650965096509650506113d28c8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92508b91508a905089898989612cea565b5050505050506113f5565b60405162461bcd60e51b81526004016106a9906148e1565b505050505050565b6001600160a01b0382166114235760405162461bcd60e51b81526004016106a99061494f565b61ffff8616600090815260066020526040808220905161144690889088906143ff565b90815260408051602092819003830181206000888152908452829020805460026001821615610100026000190190911604601f810185900485028301850190935282825290929091908301828280156114e05780601f106114b5576101008083540402835291602001916114e0565b820191906000526020600020905b8154815290600101906020018083116114c357829003601f168201915b5050505050905060008151116115085760405162461bcd60e51b81526004016106a990614699565b602081015160ff81166001146115305760405162461bcd60e51b81526004016106a9906148e1565b506040805160208082018352600080835261ffff8b1681526006909152829020915190919061156290899089906143ff565b9081526020016040518091039020600086815260200190815260200160002090805190602001906115949291906134af565b50604081015160608201516115a761353b565b60006115b283612c38565b604051630474ec6160e11b81529091506001600160a01b038216906308e9d8c2906115e3908e908890600401614b0e565b6040805180830381600087803b1580156115fc57600080fd5b505af1158015611610573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163491906137c3565b6005546040516396aae4af60e01b81529193506001600160a01b031691506396aae4af903490611670908e908b9087908c908c90600401614995565b6000604051808303818588803b15801561168957600080fd5b505af115801561169d573d6000803e3d6000fd5b505050505050505050505050505050565b6116b6612ce6565b6001600160a01b03166116c7611e81565b6001600160a01b031614611710576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000611764612ce6565b6001600160a01b0316611775611e81565b6001600160a01b0316146117be576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b0386166117e45760405162461bcd60e51b81526004016106a9906145ad565b600254604051637af935a160e01b81526001600160a01b0390911690637af935a19061181e908a908a908a908a908a908a90600401614edf565b602060405180830381600087803b15801561183857600080fd5b505af115801561184c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118709190613753565b90505b9695505050505050565b611885612ce6565b6001600160a01b0316611896611e81565b6001600160a01b0316146118df576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006118ea85612c38565b60405163a985565f60e01b81529091506001600160a01b0382169063a985565f90610afe90879087908790600401614c0e565b6005546001600160a01b031633146119475760405162461bcd60e51b81526004016106a99061462b565b6119578888888888888888613166565b5050505050505050565b600260015414156119a7576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b0386166119d25760405162461bcd60e51b81526004016106a99061494f565b600085116119f25760405162461bcd60e51b81526004016106a9906145e4565b6119fa613555565b611a0261353b565b6000611a0d8b612c38565b90506000816001600160a01b031663f6cd35ee8a6040518263ffffffff1660e01b8152600401611a3d9190614ed6565b60206040518083038186803b158015611a5557600080fd5b505afa158015611a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8d9190613f87565b9050816001600160a01b0316631b7319b68e8d33858d60006040518763ffffffff1660e01b8152600401611ac696959493929190614b4c565b60c060405180830381600087803b158015611ae057600080fd5b505af1158015611af4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b18919061380a565b9350816001600160a01b0316637298a5dc8e8d338d6040518563ffffffff1660e01b8152600401611b4c9493929190614b22565b600060405180830381600087803b158015611b6657600080fd5b505af1158015611b7a573d6000803e3d6000fd5b50505050816001600160a01b03166308e9d8c28e8d6040518363ffffffff1660e01b8152600401611bac929190614b0e565b6040805180830381600087803b158015611bc557600080fd5b505af1158015611bd9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bfd91906137c3565b92505050600560009054906101000a90046001600160a01b03166001600160a01b03166351156e73348d8d8d8d87898b8e8e6040518b63ffffffff1660e01b8152600401611c5399989796959493929190614d11565b6000604051808303818588803b158015611c6c57600080fd5b505af1158015611c80573d6000803e3d6000fd5b5050600180555050505050505050505050505050565b60026001541415611cdc576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556000611cec84612c38565b90506000816001600160a01b031663feb56b156040518163ffffffff1660e01b815260040160206040518083038186803b158015611d2957600080fd5b505afa158015611d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d619190613f87565b9050611d7781611d7186826132f8565b90613361565b9350611df5826001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015611db557600080fd5b505afa158015611dc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ded9190613753565b3384876133c1565b6040516340c10f1960e01b81526001600160a01b038316906340c10f1990611e2390869088906004016144ca565b602060405180830381600087803b158015611e3d57600080fd5b505af1158015611e51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e759190613f87565b50506001805550505050565b6000546001600160a01b031690565b60026001541415611ed6576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b038516611f015760405162461bcd60e51b81526004016106a99061494f565b6000611f0c88612c38565b905060008511611f2e5760405162461bcd60e51b81526004016106a9906147ac565b604051632c3eac2f60e21b81526000906001600160a01b0383169063b0fab0bc90611f679033908a908f908e908c908c90600401614462565b602060405180830381600087803b158015611f8157600080fd5b505af1158015611f95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb99190613f87565b905060008111611fdb5760405162461bcd60e51b81526004016106a9906147ed565b604051630474ec6160e11b81526000906001600160a01b038416906308e9d8c29061200c908e908d90600401614b0e565b6040805180830381600087803b15801561202557600080fd5b505af1158015612039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205d91906137c3565b9050600560009054906101000a90046001600160a01b03166001600160a01b0316633cef94b9348d8d8d8d87898e8e8e6040518b63ffffffff1660e01b8152600401611c5399989796959493929190614d9d565b6120b9612ce6565b6001600160a01b03166120ca611e81565b6001600160a01b031614612113576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600061211e83612c38565b60405163ac2cc36b60e01b81529091506001600160a01b0382169063ac2cc36b90610a27908590600401614516565b60026001541415612193576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b0381166121be5760405162461bcd60e51b81526004016106a99061494f565b60006121c984612c38565b90506000816001600160a01b03166308e9d8c287866040518363ffffffff1660e01b81526004016121fb929190614b0e565b6040805180830381600087803b15801561221457600080fd5b505af1158015612228573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224c91906137c3565b600554604051632fa7502b60e21b81529192506001600160a01b03169063be9d40ac903490612287908a908a908a908a908990600401614c48565b6000604051808303818588803b1580156122a057600080fd5b505af11580156122b4573d6000803e3d6000fd5b505060018055505050505050505050565b6002600154141561230b576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001558661232d5760405162461bcd60e51b81526004016106a9906148aa565b6001600160a01b0388166123535760405162461bcd60e51b81526004016106a99061494f565b61235b613555565b61236361353b565b600061236e8d612c38565b90506000816001600160a01b031663feb56b156040518163ffffffff1660e01b815260040160206040518083038186803b1580156123ab57600080fd5b505afa1580156123bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e39190613f87565b90506123f381611d718d826132f8565b9a5050806001600160a01b0316631b7319b68f8e338e8e60016040518763ffffffff1660e01b815260040161242d96959493929190614b4c565b60c060405180830381600087803b15801561244757600080fd5b505af115801561245b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247f919061380a565b92506124fd816001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156124bd57600080fd5b505afa1580156124d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f59190613753565b33838d6133c1565b806001600160a01b03166308e9d8c28f8e6040518363ffffffff1660e01b815260040161252b929190614b0e565b6040805180830381600087803b15801561254457600080fd5b505af1158015612558573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257c91906137c3565b915050600560009054906101000a90046001600160a01b03166001600160a01b03166351156e73348f8f8f8f87898f8f8f8f8f6040518d63ffffffff1660e01b81526004016125d59b9a99989796959493929190614c7d565b6000604051808303818588803b1580156125ee57600080fd5b505af1158015612602573d6000803e3d6000fd5b50506001805550505050505050505050505050505050565b6005546001600160a01b031633146126445760405162461bcd60e51b81526004016106a99061462b565b600061264f83612c38565b60405163b6addec760e01b81529091506001600160a01b0382169063b6addec790610afe90889088908790600401614bef565b6003546001600160a01b031681565b6004546001600160a01b031681565b6002546001600160a01b031681565b6000600260015414156126f7576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b6002600155826127195760405162461bcd60e51b81526004016106a9906147ac565b60006127288561ffff16612c38565b6040516304c35b0d60e11b81529091506001600160a01b03821690630986b61a9061275b9033908890889060040161443f565b602060405180830381600087803b15801561277557600080fd5b505af1158015612789573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ad9190613f87565b6001805595945050505050565b6127c2612ce6565b6001600160a01b03166127d3611e81565b6001600160a01b03161461281c576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600061282783612c38565b6040516312d72b2f60e21b81529091506001600160a01b03821690634b5cacbc90610a2790859060040161442b565b61285e612ce6565b6001600160a01b031661286f611e81565b6001600160a01b0316146128b8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006128c384612c38565b6040516345ec368560e11b81529091506001600160a01b03821690638bd86d0a906128f49086908690600401614b0e565b600060405180830381600087803b15801561290e57600080fd5b505af1158015611957573d6000803e3d6000fd5b6003546001600160a01b0316331461294c5760405162461bcd60e51b81526004016106a99061473e565b600061295783612c38565b604051632f8c40a560e21b81529091506001600160a01b0382169063be31029490610a2790859060040161442b565b61298e612ce6565b6001600160a01b031661299f611e81565b6001600160a01b0316146129e8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116612a0e5760405162461bcd60e51b81526004016106a99061483c565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6006602090815260009384526040808520845180860184018051928152908401958401959095209452928152908352918190208054825160026001831615610100026000190190921691909104601f810185900485028201850190935282815292909190830182828015612ae55780601f10612aba57610100808354040283529160200191612ae5565b820191906000526020600020905b815481529060010190602001808311612ac857829003601f168201915b505050505081565b6005546001600160a01b031681565b612b04612ce6565b6001600160a01b0316612b15611e81565b6001600160a01b031614612b5e576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116612ba35760405162461bcd60e51b815260040180806020018281038252602681526020018061512d6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000612c0983612c38565b604051637fb6526560e01b81529091506001600160a01b03821690637fb6526590610a27908590600401614516565b60025460405163068bcd8d60e01b81526000916001600160a01b03169063068bcd8d90612c69908590600401614ed6565b60206040518083038186803b158015612c8157600080fd5b505afa158015612c95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb99190613753565b90506001600160a01b038116612ce15760405162461bcd60e51b81526004016106a990614918565b919050565b3390565b6000612cf586612c38565b60405163902b8ab760e01b81529091506001600160a01b0382169063902b8ab790612d2a908d908b9089908990600401614b85565b602060405180830381600087803b158015612d4457600080fd5b505af1925050508015612d74575060408051601f3d908101601f19168201909252612d7191810190613f87565b60015b612e3c576003878787878787604051602001612d969796959493929190614fdf565b60408051601f1981840301815282825261ffff8d1660009081526006602052919091209091612dc6908c9061440f565b908152602001604051809103902060008a81526020019081526020016000209080519060200190612df89291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60038b8b8b604051612e2f9493929190614f3a565b60405180910390a161315a565b612e45856134a9565b8015612e52575060008351115b1561110f57846001600160a01b031663ab8236f3878d8d8d876001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612ea357600080fd5b505afa158015612eb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612edb9190613753565b878a6040518863ffffffff1660e01b8152600401612efe96959493929190614ab5565b600060405180830381600088803b158015612f1857600080fd5b5087f193505050508015612f2a575060015b61110f573d808015612f58576040519150601f19603f3d011682016040523d82523d6000602084013e612f5d565b606091505b506040518060800160405280846001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612fa257600080fd5b505afa158015612fb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fda9190613753565b6001600160a01b03168152602001838152602001876001600160a01b0316815260200185815250600760008e61ffff1661ffff1681526020019081526020016000208c60405161302a919061440f565b908152604080516020928190038301902060008e8152908352819020835181546001600160a01b03199081166001600160a01b039283161783558585015160018401559285015160028301805490941691161790915560608301518051919261309b926003850192909101906134af565b509050507f8186389e97ff190cd5e17304ed8188a4a98a6c8add46e6df94462ac7f7e8dd348c8c8c866001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156130fc57600080fd5b505afa158015613110573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131349190613753565b868b8a8860405161314c989796959493929190614a3b565b60405180910390a15061110f565b50505050505050505050565b600061317185612c38565b604051632cc36bab60e21b81529091506001600160a01b0382169063b30daeac906131a8908c908a90899089908990600401614bbd565b600060405180830381600087803b1580156131c257600080fd5b505af19250505080156131d3575060015b61329557600286868686866040516020016131f396959493929190614f71565b60408051601f1981840301815282825261ffff8c1660009081526006602052919091209091613223908b9061440f565b9081526020016040518091039020600089815260200190815260200160002090805190602001906132559291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60028a8a8a60405161328c9493929190614f3a565b60405180910390a15b86886040516132a4919061440f565b60405180910390207fc7379a02e530fbd0a46ea1ce6fd91987e96535798231a796bdc0e1a688a508738b89898989896040516132e596959493929190614e11565b60405180910390a3505050505050505050565b600080821161334e576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161335757fe5b0490505b92915050565b6000826133705750600061335b565b8282028284828161337d57fe5b04146133ba5760405162461bcd60e51b81526004018080602001828103825260218152602001806151536021913960400191505060405180910390fd5b9392505050565b600080856001600160a01b03166323b872dd8686866040516024016133e8939291906144a6565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051613421919061440f565b6000604051808303816000865af19150503d806000811461345e576040519150601f19603f3d011682016040523d82523d6000602084013e613463565b606091505b509150915081801561348d57508051158061348d57508080602001905181019061348d919061376f565b6113f55760405162461bcd60e51b81526004016106a9906146d0565b3b151590565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826134e5576000855561352b565b82601f106134fe57805160ff191683800117855561352b565b8280016001018555821561352b579182015b8281111561352b578251825591602001919060010190613510565b5061353792915061358b565b5090565b604051806040016040528060008152602001600081525090565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5b80821115613537576000815560010161358c565b8035612ce1816150d7565b60008083601f8401126135bc578182fd5b5081356001600160401b038111156135d2578182fd5b6020830191508360208285010111156135ea57600080fd5b9250929050565b600082601f830112613601578081fd5b813561361461360f82615086565b615063565b818152846020838601011115613628578283fd5b816020850160208301379081016020019190915292915050565b600060c08284031215613653578081fd5b60405160c081018181106001600160401b038211171561366f57fe5b8060405250809150825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a08201525092915050565b6000606082840312156136c5578081fd5b604051606081016001600160401b0382821081831117156136e257fe5b816040528293508435835260208501356020840152604085013591508082111561370b57600080fd5b50613718858286016135f1565b6040830152505092915050565b803561ffff81168114612ce157600080fd5b600060208284031215613748578081fd5b81356133ba816150d7565b600060208284031215613764578081fd5b81516133ba816150d7565b600060208284031215613780578081fd5b81516133ba816150ef565b6000806040838503121561379d578081fd5b82356137a8816150d7565b915060208301356137b8816150d7565b809150509250929050565b6000604082840312156137d4578081fd5b604051604081018181106001600160401b03821117156137f057fe5b604052825181526020928301519281019290925250919050565b600060c0828403121561381b578081fd5b6133ba8383613642565b6000806000806060858703121561383a578182fd5b61384385613725565b935060208501356001600160401b0381111561385d578283fd5b613869878288016135ab565b9598909750949560400135949350505050565b60008060008060008060a08789031215613894578384fd5b61389d87613725565b955060208701356001600160401b03808211156138b8578586fd5b6138c48a838b016135ab565b909750955060408901359450606089013591506138e0826150d7565b909250608088013590808211156138f5578283fd5b5061390289828a016136b4565b9150509295509295509295565b600080600060608486031215613923578081fd5b61392c84613725565b925060208401356001600160401b03811115613946578182fd5b613952868287016135f1565b925050604084013590509250925092565b600080600080600080600080610100898b03121561397f578586fd5b61398889613725565b975060208901356001600160401b038111156139a2578687fd5b6139ae8b828c016135f1565b97505060408901359550606089013594506080890135935060a08901356139d4816150d7565b979a969950949793969295929450505060c08201359160e0013590565b6000806000806000806000806000898b036101c0811215613a10578384fd5b613a198b613725565b995060208b01356001600160401b0380821115613a34578586fd5b613a408e838f016135f1565b9a5060408d0135995060608d0135985060808d0135975060a08d0135965060c08d01359150613a6e826150d7565b81955060c060df1984011215613a82578384fd5b604051925060c0830191508282108183111715613a9b57fe5b8160405260e08d013583526101008d013560208401526101208d013560408401526101408d013560608401526101608d013560808401526101808d013560a08401528294506101a08d0135925080831115613af4578384fd5b5050613b028c828d016135f1565b9150509295985092959850929598565b60008060008060008060008060e0898b031215613b2d578182fd5b613b3689613725565b975060208901356001600160401b0380821115613b51578384fd5b613b5d8c838d016135f1565b985060408b0135975060608b0135965060808b0135955060a08b0135945060c08b0135915080821115613b8e578384fd5b50613b9b8b828c016135ab565b999c989b5096995094979396929594505050565b600080600060608486031215613bc3578081fd5b613bcc84613725565b9250602084013591506040840135613be3816150d7565b809150509250925092565b60008060008060808587031215613c03578182fd5b613c0c85613725565b935060208501359250604085013591506060850135613c2a816150d7565b939692955090935050565b60008060008060008060008060e0898b031215613c50578182fd5b613c5989613725565b975060208901359650604089013595506060890135613c77816150d7565b94506080890135935060a08901356001600160401b0380821115613c99578384fd5b613ca58c838d016135ab565b909550935060c08b0135915080821115613cbd578283fd5b50613cca8b828c016136b4565b9150509295985092959890939650565b60008060008060008060008060006101008a8c031215613cf8578283fd5b613d018a613725565b985060208a0135975060408a0135965060608a0135613d1f816150d7565b955060808a0135945060a08a0135935060c08a01356001600160401b0380821115613d48578485fd5b613d548d838e016135ab565b909550935060e08c0135915080821115613d6c578283fd5b50613b028c828d016136b4565b60008060008060008060008060008060006101208c8e031215613d9a578485fd5b613da38c613725565b9a5060208c0135995060408c01359850613dbf60608d016135a0565b975060808c0135965060a08c013595506001600160401b038060c08e01351115613de7578586fd5b613df78e60c08f01358f016136b4565b95508060e08e01351115613e09578283fd5b613e198e60e08f01358f016135ab565b90955093506101008d0135811015613e2f578283fd5b50613e418d6101008e01358e016135ab565b81935080925050509295989b509295989b9093969950565b60008060008084860360a0811215613e6f578283fd5b613e7886613725565b9450602086013593506040808701359350605f1982011215613e98578182fd5b50604051604081018181106001600160401b0382111715613eb557fe5b604052606086013581526080909501356020860152509194909350909190565b600080600080600080600060a0888a031215613eef578081fd5b613ef888613725565b96506020880135613f08816150fd565b955060408801356001600160401b0380821115613f23578283fd5b613f2f8b838c016135ab565b909750955060608a0135915080821115613f47578283fd5b613f538b838c016135ab565b909550935060808a0135915080821115613f6b578283fd5b50613f788a828b016136b4565b91505092959891949750929550565b600060208284031215613f98578081fd5b5051919050565b60008060408385031215613fb1578182fd5b8235915060208301356137b8816150d7565b60008060008060008060c08789031215613fdb578384fd5b863595506020870135613fed816150d7565b94506040870135613ffd816150fd565b9350606087013561400d816150fd565b925060808701356001600160401b0380821115614028578384fd5b6140348a838b016135f1565b935060a0890135915080821115614049578283fd5b5061390289828a016135f1565b60008060408385031215614068578182fd5b8235915060208301356137b8816150ef565b60008060008060008060c08789031215614092578384fd5b8635955060208701356140a4816150ef565b9450604087013593506060870135925060808701356140c2816150ef565b915060a08701356140d2816150ef565b809150509295509295509295565b6000806000606084860312156140f4578081fd5b8335925061410460208501613725565b9150604084013590509250925092565b60008060008060808587031215614129578182fd5b8435935061413960208601613725565b92506040850135915061414e60608601613725565b905092959194509250565b6000806000806080858703121561416e578182fd5b8435935061417e60208601613725565b93969395505050506040820135916060013590565b600080604083850312156141a5578182fd5b50508035926020909101359150565b600080604083850312156141c6578182fd5b505080516020909101519092909150565b6000806000606084860312156141eb578081fd5b83359250602084013591506040840135613be3816150d7565b60008060008060008060c0878903121561421c578384fd5b8651614227816150fd565b8096505060208701519450604087015193506060870151614247816150d7565b809350506080870151915060a087015190509295509295509295565b6000806000806000806000610180888a03121561427e578081fd5b8751614289816150fd565b8097505060208801519550604088015194506060880151935060808801516142b0816150d7565b92506142bf8960a08a01613642565b91506101608801516001600160401b038111156142da578182fd5b8801601f81018a136142ea578182fd5b80516142f861360f82615086565b8181528b602083850101111561430c578384fd5b61431d8260208301602086016150a7565b80935050505092959891949750929550565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526143718160208601602086016150a7565b601f01601f19169290920160200192915050565b80518252602090810151910152565b805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a08301525050565b600081518352602082015160208401526040820151606060408501526143f76060850182614359565b949350505050565b6000828483379101908152919050565b600082516144218184602087016150a7565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b600060018060a01b038816825286602083015261ffff8616604083015284606083015260a0608083015261449a60a08301848661432f565b98975050505050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b038581168252602082018590528316604082015260806060820181905260009061187390830184614359565b901515815260200190565b941515855260208501939093526040840191909152151560608301521515608082015260a00190565b6000602082526133ba6020830184614359565b60208082526030908201527f53746172676174653a2062726964676520616e6420666163746f727920616c7260408201526f1958591e481a5b9a5d1a585b1a5e995960821b606082015260800190565b6020808252601e908201527f53746172676174653a205f746f6b656e2063616e6e6f74206265203078300000604082015260600190565b60208082526027908201527f53746172676174653a206e6f7420656e6f756768206c7020746f2072656465656040820152666d52656d6f746560c81b606082015260800190565b6020808252601e908201527f4272696467653a2063616c6c6572206d757374206265204272696467652e0000604082015260600190565b6020808252601b908201527f53746172676174653a206f6e6c79206d696e744665654f776e65720000000000604082015260600190565b60208082526019908201527f53746172676174653a206e6f2072657472792072657665727400000000000000604082015260600190565b6020808252601e908201527f53746172676174653a205452414e534645525f46524f4d5f4641494c45440000604082015260600190565b6020808252601d908201527f53746172676174653a20666163746f72792063616e7420626520307830000000604082015260600190565b6020808252601f908201527f53746172676174653a206f6e6c792070726f746f636f6c4665654f776e657200604082015260600190565b6020808252601c908201527f53746172676174653a206272696467652063616e742062652030783000000000604082015260600190565b60208082526021908201527f53746172676174653a206e6f7420656e6f756768206c7020746f2072656465656040820152606d60f81b606082015260800190565b6020808252602f908201527f53746172676174653a206e6f7420656e6f756768206c7020746f20726564656560408201526e1b481dda5d1a08185b5bdd5b9d14d1608a1b606082015260800190565b6020808252601e908201527f53746172676174653a205f6f776e65722063616e6e6f74206265203078300000604082015260600190565b6020808252601f908201527f53746172676174653a20636163686520616c726561647920636c656172656400604082015260600190565b60208082526017908201527f53746172676174653a2063616e6e6f7420737761702030000000000000000000604082015260600190565b6020808252601f908201527f53746172676174653a20696e76616c69642066756e6374696f6e207479706500604082015260600190565b6020808252601d908201527f53746172676174653a20506f6f6c20646f6573206e6f74206578697374000000604082015260600190565b60208082526026908201527f53746172676174653a205f726566756e64416464726573732063616e6e6f742060408201526506265203078360d41b606082015260800190565b61ffff861681526001600160a01b038516602082015260006149ba6040830186614385565b60c060808301526149ce60c08301856143ce565b82810360a084015261449a8185614359565b600061ffff8916825260c060208301526149fe60c08301888a61432f565b604083018790526001600160a01b03861660608401526080830185905282810360a0840152614a2d8185614359565b9a9950505050505050505050565b600061010061ffff8b168352806020840152614a598184018b614359565b604084018a90526001600160a01b03898116606086015260808501899052871660a085015283810360c08501529050614a928186614359565b905082810360e0840152614aa68185614359565b9b9a5050505050505050505050565b600061ffff8816825260c06020830152614ad260c0830188614359565b604083018790526001600160a01b03861660608401526080830185905282810360a0840152614b018185614359565b9998505050505050505050565b61ffff929092168252602082015260400190565b61ffff94909416845260208401929092526001600160a01b03166040830152606082015260800190565b61ffff96909616865260208601949094526001600160a01b0392909216604085015260608401526080830152151560a082015260c00190565b61ffff85168152602081018490526001600160a01b03831660408201526101208101614bb46060830184614394565b95945050505050565b61ffff95909516855260208501939093526001600160a01b039190911660408401526060830152608082015260a00190565b61ffff8416815260208101839052608081016143f76040830184614385565b61ffff93841681526020810192909252909116604082015260600190565b61ffff9390931683526020830191909152604082015260600190565b61ffff8616815260208101859052604081018490526001600160a01b038316606082015260c081016118736080830184614385565b61ffff8c168152602081018b9052604081018a90526001600160a01b038916606082015260006101e0614cb3608084018b614385565b614cc060c084018a614394565b80610180840152614cd3818401896143ce565b90508281036101a0840152614ce981878961432f565b90508281036101c0840152614cff81858761432f565b9e9d5050505050505050505050505050565b61ffff8a16815260208101899052604081018890526001600160a01b038716606082015260006101e0614d476080840189614385565b614d5460c0840188614394565b80610180840152614d67818401876143ce565b90508281036101a0840152614d7d81858761432f565b8381036101c0909401939093525081526020019998505050505050505050565b61ffff8a16815260208101899052604081018890526001600160a01b03871660608201526000610120614dd36080840189614385565b8660c08401528060e0840152614dec818401868861432f565b9050828103610100840152614e0181856143ce565b9c9b505050505050505050505050565b61ffff969096168652602086019490945260408501929092526001600160a01b03166060840152608083015260a082015260c00190565b600061ffff8916825287602083015286604083015260c06060830152614e7260c08301868861432f565b60808301949094525060a0015295945050505050565b600061ffff8916825260ff8816602083015260a06040830152614eaf60a08301878961432f565b8281036060840152614ec281868861432f565b90508281036080840152614a2d81856143ce565b90815260200190565b8681526001600160a01b038616602082015260ff85811660408301528416606082015260c060808201819052600090614f1a90830185614359565b82810360a0840152614b018185614359565b918252602082015260400190565b600060ff8616825261ffff8516602083015260806040830152614f606080830185614359565b905082606083015295945050505050565b60ff969096168652602086019490945260408501929092526001600160a01b03166060840152608083015260a082015260c00190565b600060ff8916825287602083015286604083015260ff8616606083015284608083015260c060a0830152614b0160c08301848661432f565b60ff881681526020810187905260408101869052606081018590526001600160a01b0384166080820152600061018061501b60a0840186614394565b80610160840152614a2d81840185614359565b600060ff8916825287602083015286604083015285606083015284608083015260c060a0830152614b0160c08301848661432f565b6040518181016001600160401b038111828210171561507e57fe5b604052919050565b60006001600160401b0382111561509957fe5b50601f01601f191660200190565b60005b838110156150c25781810151838201526020016150aa565b838111156150d1576000848401525b50505050565b6001600160a01b03811681146150ec57600080fd5b50565b80151581146150ec57600080fd5b60ff811681146150ec57600080fdfe5265656e7472616e637947756172643a207265656e7472616e742063616c6c004f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a2646970667358221220d86582ffb411c85869be51806318cb203c2835996c58fcb8521dd7b53c5baece64736f6c63430007060033
Deployed Bytecode
0x60806040526004361061021a5760003560e01c806387b21efc11610123578063c45a0155116100ab578063cefbdde21161006f578063cefbdde2146105dd578063da133a06146105fd578063e78cea921461062a578063f2fde38b1461063f578063fba6e2801461065f5761021a565b8063c45a01551461053b578063c4de93a514610550578063c6a276241461057d578063c7d968e31461059d578063c8adf12d146105bd5761021a565b80639ba3aa74116100f25780639ba3aa74146104cb5780639fbf10fc146104de578063a18fa804146104f1578063a96fbed414610511578063af640d82146105265761021a565b806387b21efc146104635780638da5cb5b146104835780638f2e1d181461049857806398e391a1146104ab5761021a565b806343a30630116101a6578063715018a611610175578063715018a6146103ce5780637af935a1146103e35780637b84d287146104105780637f7212981461043057806384d0dba3146104505761021a565b806343a30630146103685780635500585c1461038857806360a3b95c146103a85780636a7982da146103bb5761021a565b806323fd4647116101ed57806323fd4647146102b85780632f925555146102e857806334aba41014610308578063403a9f7a14610328578063424c9119146103485761021a565b80630403bce51461021f5780630a512369146102415780630b78f9c01461027857806316fb60f514610298575b600080fd5b34801561022b57600080fd5b5061023f61023a366004613b12565b61067f565b005b34801561024d57600080fd5b5061026161025c366004613ed5565b6108eb565b60405161026f929190614f2c565b60405180910390f35b34801561028457600080fd5b5061023f610293366004614193565b61098b565b3480156102a457600080fd5b5061023f6102b3366004614159565b610a5e565b3480156102c457600080fd5b506102d86102d336600461390f565b610b2c565b60405161026f94939291906144e3565b3480156102f457600080fd5b5061023f6103033660046139f1565b610c0b565b34801561031457600080fd5b5061023f610323366004613737565b610c46565b34801561033457600080fd5b5061023f610343366004613825565b610cf0565b34801561035457600080fd5b5061023f61036336600461378b565b610f23565b34801561037457600080fd5b5061023f61038336600461407a565b61103d565b34801561039457600080fd5b5061023f6103a3366004613f9f565b61111c565b61023f6103b6366004613825565b611180565b61023f6103c936600461387c565b6113fd565b3480156103da57600080fd5b5061023f6116ae565b3480156103ef57600080fd5b506104036103fe366004613fc3565b61175a565b60405161026f919061442b565b34801561041c57600080fd5b5061023f61042b366004614114565b61187d565b34801561043c57600080fd5b5061023f61044b366004613963565b61191d565b61023f61045e366004613cda565b611961565b34801561046f57600080fd5b5061023f61047e3660046141d7565b611c96565b34801561048f57600080fd5b50610403611e81565b61023f6104a6366004613c35565b611e90565b3480156104b757600080fd5b5061023f6104c6366004614056565b6120b1565b61023f6104d9366004613bee565b61214d565b61023f6104ec366004613d79565b6122c5565b3480156104fd57600080fd5b5061023f61050c366004613e59565b61261a565b34801561051d57600080fd5b50610403612682565b34801561053257600080fd5b50610403612691565b34801561054757600080fd5b506104036126a0565b34801561055c57600080fd5b5061057061056b366004613baf565b6126af565b60405161026f9190614ed6565b34801561058957600080fd5b5061023f610598366004613f9f565b6127ba565b3480156105a957600080fd5b5061023f6105b83660046140e0565b612856565b3480156105c957600080fd5b5061023f6105d8366004613f9f565b612922565b3480156105e957600080fd5b5061023f6105f8366004613737565b612986565b34801561060957600080fd5b5061061d61061836600461390f565b612a30565b60405161026f919061454a565b34801561063657600080fd5b50610403612aed565b34801561064b57600080fd5b5061023f61065a366004613737565b612afc565b34801561066b57600080fd5b5061023f61067a366004614056565b612bfe565b6005546001600160a01b031633146106b25760405162461bcd60e51b81526004016106a99061462b565b60405180910390fd5b60006106bd85612c38565b604051637544f15560e11b81529091506001600160a01b0382169063ea89e2aa906106f0908c908a908990600401614c2c565b6040805180830381600087803b15801561070957600080fd5b505af1925050508015610739575060408051601f3d908101601f19168201909252610736918101906141b4565b60015b6108025760018686600087878760405160200161075c9796959493929190614fa7565b60408051601f1981840301815282825261ffff8c166000908152600660205291909120909161078c908b9061440f565b9081526020016040518091039020600089815260200190815260200160002090805190602001906107be9291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60018a8a8a6040516107f59493929190614f3a565b60405180910390a16108e0565b6001888884848989604051602001610820979695949392919061502e565b60408051601f1981840301815282825261ffff8e1660009081526006602052919091209091610850908d9061440f565b908152602001604051809103902060008b815260200190815260200160002090805190602001906108829291906134af565b5089604051610891919061440f565b6040518091039020897f6ace246fa15cf1d5decabf654b1e8581a4422e0fcf4c1ed4bf83f41687caec198d8b8b8a8a89896040516108d59796959493929190614e48565b60405180910390a350505b505050505050505050565b600554604051630a51236960e01b815260009182916001600160a01b0390911690630a5123699061092c908c908c908c908c908c908c908c90600401614e88565b604080518083038186803b15801561094357600080fd5b505afa158015610957573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097b91906141b4565b9150915097509795505050505050565b610993612ce6565b6001600160a01b03166109a4611e81565b6001600160a01b0316146109ed576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006109f883612c38565b6040516369fe0e2d60e01b81529091506001600160a01b038216906369fe0e2d90610a27908590600401614ed6565b600060405180830381600087803b158015610a4157600080fd5b505af1158015610a55573d6000803e3d6000fd5b50505050505050565b610a66612ce6565b6001600160a01b0316610a77611e81565b6001600160a01b031614610ac0576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6000610acb85612c38565b6040516320d6bc7560e01b81529091506001600160a01b038216906320d6bc7590610afe90879087908790600401614c2c565b600060405180830381600087803b158015610b1857600080fd5b505af11580156108e0573d6000803e3d6000fd5b600760209081526000938452604080852084518086018401805192815290840195840195909520945292815290835291819020805460018083015460028085015460038601805488516101009682161596909602600019011692909204601f81018990048902850189019097528684526001600160a01b03948516979296941694939091830182828015610c015780601f10610bd657610100808354040283529160200191610c01565b820191906000526020600020905b815481529060010190602001808311610be457829003601f168201915b5050505050905084565b6005546001600160a01b03163314610c355760405162461bcd60e51b81526004016106a99061462b565b6108e0898989898989898989612cea565b610c4e612ce6565b6001600160a01b0316610c5f611e81565b6001600160a01b031614610ca8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116610cce5760405162461bcd60e51b81526004016106a99061483c565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b61ffff84166000908152600760205260408082209051610d1390869086906143ff565b9081526040805160209281900383018120600086815290845282902060808201835280546001600160a01b039081168352600180830154868501526002808401549092168486015260038301805486516101009382161593909302600019011692909204601f810187900487028201870190955284815292949193606086019392830182828015610de55780601f10610dba57610100808354040283529160200191610de5565b820191906000526020600020905b815481529060010190602001808311610dc857829003601f168201915b5050509190925250505060408101519091506001600160a01b0316610e1c5760405162461bcd60e51b81526004016106a990614873565b604080516080810182526000808252602080830182905282840182905283518082018552828152606084015261ffff89168252600790528290209151909190610e6890879087906143ff565b90815260408051602092819003830190206000868152908352819020835181546001600160a01b03199081166001600160a01b0392831617835585850151600184015592850151600283018054909416911617909155606083015180519192610ed9926003850192909101906134af565b505050604080820151825160208401516060850151935163ab8236f360e01b81526001600160a01b039093169363ab8236f393610afe938b938b938b938b939291906004016149e0565b610f2b612ce6565b6001600160a01b0316610f3c611e81565b6001600160a01b031614610f85576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6005546001600160a01b0316158015610fa757506002546001600160a01b0316155b610fc35760405162461bcd60e51b81526004016106a99061455d565b6001600160a01b038216610fe95760405162461bcd60e51b81526004016106a990614775565b6001600160a01b03811661100f5760405162461bcd60e51b81526004016106a990614707565b600580546001600160a01b039384166001600160a01b03199182161790915560028054929093169116179055565b611045612ce6565b6001600160a01b0316611056611e81565b6001600160a01b03161461109f576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006110aa87612c38565b60405163e065608b60e01b81529091506001600160a01b0382169063e065608b906110e19089908990899089908990600401614521565b600060405180830381600087803b1580156110fb57600080fd5b505af115801561110f573d6000803e3d6000fd5b5050505050505050505050565b6004546001600160a01b031633146111465760405162461bcd60e51b81526004016106a990614662565b600061115183612c38565b60405163011dbbf960e61b81529091506001600160a01b0382169063476efe4090610a2790859060040161442b565b61ffff841660009081526006602052604080822090516111a390869086906143ff565b90815260408051602092819003830181206000868152908452829020805460026001821615610100026000190190911604601f8101859004850283018501909352828252909290919083018282801561123d5780601f106112125761010080835404028352916020019161123d565b820191906000526020600020905b81548152906001019060200180831161122057829003601f168201915b5050505050905060008151116112655760405162461bcd60e51b81526004016106a990614699565b6040805160208082018352600080835261ffff891681526006909152829020915190919061129690879087906143ff565b9081526020016040518091039020600084815260200190815260200160002090805190602001906112c89291906134af565b50602081015160ff811660021415611353576000806000806000868060200190518101906112f69190614204565b95509550955095509550506113498b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508d92508a9150899050888888613166565b50505050506113f5565b60ff8116600314156113dd576000806000806000808780602001905181019061137c9190614263565b965096509650965096509650506113d28c8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92508b91508a905089898989612cea565b5050505050506113f5565b60405162461bcd60e51b81526004016106a9906148e1565b505050505050565b6001600160a01b0382166114235760405162461bcd60e51b81526004016106a99061494f565b61ffff8616600090815260066020526040808220905161144690889088906143ff565b90815260408051602092819003830181206000888152908452829020805460026001821615610100026000190190911604601f810185900485028301850190935282825290929091908301828280156114e05780601f106114b5576101008083540402835291602001916114e0565b820191906000526020600020905b8154815290600101906020018083116114c357829003601f168201915b5050505050905060008151116115085760405162461bcd60e51b81526004016106a990614699565b602081015160ff81166001146115305760405162461bcd60e51b81526004016106a9906148e1565b506040805160208082018352600080835261ffff8b1681526006909152829020915190919061156290899089906143ff565b9081526020016040518091039020600086815260200190815260200160002090805190602001906115949291906134af565b50604081015160608201516115a761353b565b60006115b283612c38565b604051630474ec6160e11b81529091506001600160a01b038216906308e9d8c2906115e3908e908890600401614b0e565b6040805180830381600087803b1580156115fc57600080fd5b505af1158015611610573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163491906137c3565b6005546040516396aae4af60e01b81529193506001600160a01b031691506396aae4af903490611670908e908b9087908c908c90600401614995565b6000604051808303818588803b15801561168957600080fd5b505af115801561169d573d6000803e3d6000fd5b505050505050505050505050505050565b6116b6612ce6565b6001600160a01b03166116c7611e81565b6001600160a01b031614611710576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000611764612ce6565b6001600160a01b0316611775611e81565b6001600160a01b0316146117be576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b0386166117e45760405162461bcd60e51b81526004016106a9906145ad565b600254604051637af935a160e01b81526001600160a01b0390911690637af935a19061181e908a908a908a908a908a908a90600401614edf565b602060405180830381600087803b15801561183857600080fd5b505af115801561184c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118709190613753565b90505b9695505050505050565b611885612ce6565b6001600160a01b0316611896611e81565b6001600160a01b0316146118df576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006118ea85612c38565b60405163a985565f60e01b81529091506001600160a01b0382169063a985565f90610afe90879087908790600401614c0e565b6005546001600160a01b031633146119475760405162461bcd60e51b81526004016106a99061462b565b6119578888888888888888613166565b5050505050505050565b600260015414156119a7576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b0386166119d25760405162461bcd60e51b81526004016106a99061494f565b600085116119f25760405162461bcd60e51b81526004016106a9906145e4565b6119fa613555565b611a0261353b565b6000611a0d8b612c38565b90506000816001600160a01b031663f6cd35ee8a6040518263ffffffff1660e01b8152600401611a3d9190614ed6565b60206040518083038186803b158015611a5557600080fd5b505afa158015611a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8d9190613f87565b9050816001600160a01b0316631b7319b68e8d33858d60006040518763ffffffff1660e01b8152600401611ac696959493929190614b4c565b60c060405180830381600087803b158015611ae057600080fd5b505af1158015611af4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b18919061380a565b9350816001600160a01b0316637298a5dc8e8d338d6040518563ffffffff1660e01b8152600401611b4c9493929190614b22565b600060405180830381600087803b158015611b6657600080fd5b505af1158015611b7a573d6000803e3d6000fd5b50505050816001600160a01b03166308e9d8c28e8d6040518363ffffffff1660e01b8152600401611bac929190614b0e565b6040805180830381600087803b158015611bc557600080fd5b505af1158015611bd9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bfd91906137c3565b92505050600560009054906101000a90046001600160a01b03166001600160a01b03166351156e73348d8d8d8d87898b8e8e6040518b63ffffffff1660e01b8152600401611c5399989796959493929190614d11565b6000604051808303818588803b158015611c6c57600080fd5b505af1158015611c80573d6000803e3d6000fd5b5050600180555050505050505050505050505050565b60026001541415611cdc576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556000611cec84612c38565b90506000816001600160a01b031663feb56b156040518163ffffffff1660e01b815260040160206040518083038186803b158015611d2957600080fd5b505afa158015611d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d619190613f87565b9050611d7781611d7186826132f8565b90613361565b9350611df5826001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015611db557600080fd5b505afa158015611dc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ded9190613753565b3384876133c1565b6040516340c10f1960e01b81526001600160a01b038316906340c10f1990611e2390869088906004016144ca565b602060405180830381600087803b158015611e3d57600080fd5b505af1158015611e51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e759190613f87565b50506001805550505050565b6000546001600160a01b031690565b60026001541415611ed6576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b038516611f015760405162461bcd60e51b81526004016106a99061494f565b6000611f0c88612c38565b905060008511611f2e5760405162461bcd60e51b81526004016106a9906147ac565b604051632c3eac2f60e21b81526000906001600160a01b0383169063b0fab0bc90611f679033908a908f908e908c908c90600401614462565b602060405180830381600087803b158015611f8157600080fd5b505af1158015611f95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb99190613f87565b905060008111611fdb5760405162461bcd60e51b81526004016106a9906147ed565b604051630474ec6160e11b81526000906001600160a01b038416906308e9d8c29061200c908e908d90600401614b0e565b6040805180830381600087803b15801561202557600080fd5b505af1158015612039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205d91906137c3565b9050600560009054906101000a90046001600160a01b03166001600160a01b0316633cef94b9348d8d8d8d87898e8e8e6040518b63ffffffff1660e01b8152600401611c5399989796959493929190614d9d565b6120b9612ce6565b6001600160a01b03166120ca611e81565b6001600160a01b031614612113576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600061211e83612c38565b60405163ac2cc36b60e01b81529091506001600160a01b0382169063ac2cc36b90610a27908590600401614516565b60026001541415612193576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b0381166121be5760405162461bcd60e51b81526004016106a99061494f565b60006121c984612c38565b90506000816001600160a01b03166308e9d8c287866040518363ffffffff1660e01b81526004016121fb929190614b0e565b6040805180830381600087803b15801561221457600080fd5b505af1158015612228573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224c91906137c3565b600554604051632fa7502b60e21b81529192506001600160a01b03169063be9d40ac903490612287908a908a908a908a908990600401614c48565b6000604051808303818588803b1580156122a057600080fd5b505af11580156122b4573d6000803e3d6000fd5b505060018055505050505050505050565b6002600154141561230b576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001558661232d5760405162461bcd60e51b81526004016106a9906148aa565b6001600160a01b0388166123535760405162461bcd60e51b81526004016106a99061494f565b61235b613555565b61236361353b565b600061236e8d612c38565b90506000816001600160a01b031663feb56b156040518163ffffffff1660e01b815260040160206040518083038186803b1580156123ab57600080fd5b505afa1580156123bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e39190613f87565b90506123f381611d718d826132f8565b9a5050806001600160a01b0316631b7319b68f8e338e8e60016040518763ffffffff1660e01b815260040161242d96959493929190614b4c565b60c060405180830381600087803b15801561244757600080fd5b505af115801561245b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247f919061380a565b92506124fd816001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156124bd57600080fd5b505afa1580156124d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f59190613753565b33838d6133c1565b806001600160a01b03166308e9d8c28f8e6040518363ffffffff1660e01b815260040161252b929190614b0e565b6040805180830381600087803b15801561254457600080fd5b505af1158015612558573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257c91906137c3565b915050600560009054906101000a90046001600160a01b03166001600160a01b03166351156e73348f8f8f8f87898f8f8f8f8f6040518d63ffffffff1660e01b81526004016125d59b9a99989796959493929190614c7d565b6000604051808303818588803b1580156125ee57600080fd5b505af1158015612602573d6000803e3d6000fd5b50506001805550505050505050505050505050505050565b6005546001600160a01b031633146126445760405162461bcd60e51b81526004016106a99061462b565b600061264f83612c38565b60405163b6addec760e01b81529091506001600160a01b0382169063b6addec790610afe90889088908790600401614bef565b6003546001600160a01b031681565b6004546001600160a01b031681565b6002546001600160a01b031681565b6000600260015414156126f7576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b6002600155826127195760405162461bcd60e51b81526004016106a9906147ac565b60006127288561ffff16612c38565b6040516304c35b0d60e11b81529091506001600160a01b03821690630986b61a9061275b9033908890889060040161443f565b602060405180830381600087803b15801561277557600080fd5b505af1158015612789573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ad9190613f87565b6001805595945050505050565b6127c2612ce6565b6001600160a01b03166127d3611e81565b6001600160a01b03161461281c576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600061282783612c38565b6040516312d72b2f60e21b81529091506001600160a01b03821690634b5cacbc90610a2790859060040161442b565b61285e612ce6565b6001600160a01b031661286f611e81565b6001600160a01b0316146128b8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006128c384612c38565b6040516345ec368560e11b81529091506001600160a01b03821690638bd86d0a906128f49086908690600401614b0e565b600060405180830381600087803b15801561290e57600080fd5b505af1158015611957573d6000803e3d6000fd5b6003546001600160a01b0316331461294c5760405162461bcd60e51b81526004016106a99061473e565b600061295783612c38565b604051632f8c40a560e21b81529091506001600160a01b0382169063be31029490610a2790859060040161442b565b61298e612ce6565b6001600160a01b031661299f611e81565b6001600160a01b0316146129e8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116612a0e5760405162461bcd60e51b81526004016106a99061483c565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6006602090815260009384526040808520845180860184018051928152908401958401959095209452928152908352918190208054825160026001831615610100026000190190921691909104601f810185900485028201850190935282815292909190830182828015612ae55780601f10612aba57610100808354040283529160200191612ae5565b820191906000526020600020905b815481529060010190602001808311612ac857829003601f168201915b505050505081565b6005546001600160a01b031681565b612b04612ce6565b6001600160a01b0316612b15611e81565b6001600160a01b031614612b5e576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116612ba35760405162461bcd60e51b815260040180806020018281038252602681526020018061512d6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000612c0983612c38565b604051637fb6526560e01b81529091506001600160a01b03821690637fb6526590610a27908590600401614516565b60025460405163068bcd8d60e01b81526000916001600160a01b03169063068bcd8d90612c69908590600401614ed6565b60206040518083038186803b158015612c8157600080fd5b505afa158015612c95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb99190613753565b90506001600160a01b038116612ce15760405162461bcd60e51b81526004016106a990614918565b919050565b3390565b6000612cf586612c38565b60405163902b8ab760e01b81529091506001600160a01b0382169063902b8ab790612d2a908d908b9089908990600401614b85565b602060405180830381600087803b158015612d4457600080fd5b505af1925050508015612d74575060408051601f3d908101601f19168201909252612d7191810190613f87565b60015b612e3c576003878787878787604051602001612d969796959493929190614fdf565b60408051601f1981840301815282825261ffff8d1660009081526006602052919091209091612dc6908c9061440f565b908152602001604051809103902060008a81526020019081526020016000209080519060200190612df89291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60038b8b8b604051612e2f9493929190614f3a565b60405180910390a161315a565b612e45856134a9565b8015612e52575060008351115b1561110f57846001600160a01b031663ab8236f3878d8d8d876001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612ea357600080fd5b505afa158015612eb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612edb9190613753565b878a6040518863ffffffff1660e01b8152600401612efe96959493929190614ab5565b600060405180830381600088803b158015612f1857600080fd5b5087f193505050508015612f2a575060015b61110f573d808015612f58576040519150601f19603f3d011682016040523d82523d6000602084013e612f5d565b606091505b506040518060800160405280846001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612fa257600080fd5b505afa158015612fb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fda9190613753565b6001600160a01b03168152602001838152602001876001600160a01b0316815260200185815250600760008e61ffff1661ffff1681526020019081526020016000208c60405161302a919061440f565b908152604080516020928190038301902060008e8152908352819020835181546001600160a01b03199081166001600160a01b039283161783558585015160018401559285015160028301805490941691161790915560608301518051919261309b926003850192909101906134af565b509050507f8186389e97ff190cd5e17304ed8188a4a98a6c8add46e6df94462ac7f7e8dd348c8c8c866001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156130fc57600080fd5b505afa158015613110573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131349190613753565b868b8a8860405161314c989796959493929190614a3b565b60405180910390a15061110f565b50505050505050505050565b600061317185612c38565b604051632cc36bab60e21b81529091506001600160a01b0382169063b30daeac906131a8908c908a90899089908990600401614bbd565b600060405180830381600087803b1580156131c257600080fd5b505af19250505080156131d3575060015b61329557600286868686866040516020016131f396959493929190614f71565b60408051601f1981840301815282825261ffff8c1660009081526006602052919091209091613223908b9061440f565b9081526020016040518091039020600089815260200190815260200160002090805190602001906132559291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60028a8a8a60405161328c9493929190614f3a565b60405180910390a15b86886040516132a4919061440f565b60405180910390207fc7379a02e530fbd0a46ea1ce6fd91987e96535798231a796bdc0e1a688a508738b89898989896040516132e596959493929190614e11565b60405180910390a3505050505050505050565b600080821161334e576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161335757fe5b0490505b92915050565b6000826133705750600061335b565b8282028284828161337d57fe5b04146133ba5760405162461bcd60e51b81526004018080602001828103825260218152602001806151536021913960400191505060405180910390fd5b9392505050565b600080856001600160a01b03166323b872dd8686866040516024016133e8939291906144a6565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051613421919061440f565b6000604051808303816000865af19150503d806000811461345e576040519150601f19603f3d011682016040523d82523d6000602084013e613463565b606091505b509150915081801561348d57508051158061348d57508080602001905181019061348d919061376f565b6113f55760405162461bcd60e51b81526004016106a9906146d0565b3b151590565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826134e5576000855561352b565b82601f106134fe57805160ff191683800117855561352b565b8280016001018555821561352b579182015b8281111561352b578251825591602001919060010190613510565b5061353792915061358b565b5090565b604051806040016040528060008152602001600081525090565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5b80821115613537576000815560010161358c565b8035612ce1816150d7565b60008083601f8401126135bc578182fd5b5081356001600160401b038111156135d2578182fd5b6020830191508360208285010111156135ea57600080fd5b9250929050565b600082601f830112613601578081fd5b813561361461360f82615086565b615063565b818152846020838601011115613628578283fd5b816020850160208301379081016020019190915292915050565b600060c08284031215613653578081fd5b60405160c081018181106001600160401b038211171561366f57fe5b8060405250809150825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a08201525092915050565b6000606082840312156136c5578081fd5b604051606081016001600160401b0382821081831117156136e257fe5b816040528293508435835260208501356020840152604085013591508082111561370b57600080fd5b50613718858286016135f1565b6040830152505092915050565b803561ffff81168114612ce157600080fd5b600060208284031215613748578081fd5b81356133ba816150d7565b600060208284031215613764578081fd5b81516133ba816150d7565b600060208284031215613780578081fd5b81516133ba816150ef565b6000806040838503121561379d578081fd5b82356137a8816150d7565b915060208301356137b8816150d7565b809150509250929050565b6000604082840312156137d4578081fd5b604051604081018181106001600160401b03821117156137f057fe5b604052825181526020928301519281019290925250919050565b600060c0828403121561381b578081fd5b6133ba8383613642565b6000806000806060858703121561383a578182fd5b61384385613725565b935060208501356001600160401b0381111561385d578283fd5b613869878288016135ab565b9598909750949560400135949350505050565b60008060008060008060a08789031215613894578384fd5b61389d87613725565b955060208701356001600160401b03808211156138b8578586fd5b6138c48a838b016135ab565b909750955060408901359450606089013591506138e0826150d7565b909250608088013590808211156138f5578283fd5b5061390289828a016136b4565b9150509295509295509295565b600080600060608486031215613923578081fd5b61392c84613725565b925060208401356001600160401b03811115613946578182fd5b613952868287016135f1565b925050604084013590509250925092565b600080600080600080600080610100898b03121561397f578586fd5b61398889613725565b975060208901356001600160401b038111156139a2578687fd5b6139ae8b828c016135f1565b97505060408901359550606089013594506080890135935060a08901356139d4816150d7565b979a969950949793969295929450505060c08201359160e0013590565b6000806000806000806000806000898b036101c0811215613a10578384fd5b613a198b613725565b995060208b01356001600160401b0380821115613a34578586fd5b613a408e838f016135f1565b9a5060408d0135995060608d0135985060808d0135975060a08d0135965060c08d01359150613a6e826150d7565b81955060c060df1984011215613a82578384fd5b604051925060c0830191508282108183111715613a9b57fe5b8160405260e08d013583526101008d013560208401526101208d013560408401526101408d013560608401526101608d013560808401526101808d013560a08401528294506101a08d0135925080831115613af4578384fd5b5050613b028c828d016135f1565b9150509295985092959850929598565b60008060008060008060008060e0898b031215613b2d578182fd5b613b3689613725565b975060208901356001600160401b0380821115613b51578384fd5b613b5d8c838d016135f1565b985060408b0135975060608b0135965060808b0135955060a08b0135945060c08b0135915080821115613b8e578384fd5b50613b9b8b828c016135ab565b999c989b5096995094979396929594505050565b600080600060608486031215613bc3578081fd5b613bcc84613725565b9250602084013591506040840135613be3816150d7565b809150509250925092565b60008060008060808587031215613c03578182fd5b613c0c85613725565b935060208501359250604085013591506060850135613c2a816150d7565b939692955090935050565b60008060008060008060008060e0898b031215613c50578182fd5b613c5989613725565b975060208901359650604089013595506060890135613c77816150d7565b94506080890135935060a08901356001600160401b0380821115613c99578384fd5b613ca58c838d016135ab565b909550935060c08b0135915080821115613cbd578283fd5b50613cca8b828c016136b4565b9150509295985092959890939650565b60008060008060008060008060006101008a8c031215613cf8578283fd5b613d018a613725565b985060208a0135975060408a0135965060608a0135613d1f816150d7565b955060808a0135945060a08a0135935060c08a01356001600160401b0380821115613d48578485fd5b613d548d838e016135ab565b909550935060e08c0135915080821115613d6c578283fd5b50613b028c828d016136b4565b60008060008060008060008060008060006101208c8e031215613d9a578485fd5b613da38c613725565b9a5060208c0135995060408c01359850613dbf60608d016135a0565b975060808c0135965060a08c013595506001600160401b038060c08e01351115613de7578586fd5b613df78e60c08f01358f016136b4565b95508060e08e01351115613e09578283fd5b613e198e60e08f01358f016135ab565b90955093506101008d0135811015613e2f578283fd5b50613e418d6101008e01358e016135ab565b81935080925050509295989b509295989b9093969950565b60008060008084860360a0811215613e6f578283fd5b613e7886613725565b9450602086013593506040808701359350605f1982011215613e98578182fd5b50604051604081018181106001600160401b0382111715613eb557fe5b604052606086013581526080909501356020860152509194909350909190565b600080600080600080600060a0888a031215613eef578081fd5b613ef888613725565b96506020880135613f08816150fd565b955060408801356001600160401b0380821115613f23578283fd5b613f2f8b838c016135ab565b909750955060608a0135915080821115613f47578283fd5b613f538b838c016135ab565b909550935060808a0135915080821115613f6b578283fd5b50613f788a828b016136b4565b91505092959891949750929550565b600060208284031215613f98578081fd5b5051919050565b60008060408385031215613fb1578182fd5b8235915060208301356137b8816150d7565b60008060008060008060c08789031215613fdb578384fd5b863595506020870135613fed816150d7565b94506040870135613ffd816150fd565b9350606087013561400d816150fd565b925060808701356001600160401b0380821115614028578384fd5b6140348a838b016135f1565b935060a0890135915080821115614049578283fd5b5061390289828a016135f1565b60008060408385031215614068578182fd5b8235915060208301356137b8816150ef565b60008060008060008060c08789031215614092578384fd5b8635955060208701356140a4816150ef565b9450604087013593506060870135925060808701356140c2816150ef565b915060a08701356140d2816150ef565b809150509295509295509295565b6000806000606084860312156140f4578081fd5b8335925061410460208501613725565b9150604084013590509250925092565b60008060008060808587031215614129578182fd5b8435935061413960208601613725565b92506040850135915061414e60608601613725565b905092959194509250565b6000806000806080858703121561416e578182fd5b8435935061417e60208601613725565b93969395505050506040820135916060013590565b600080604083850312156141a5578182fd5b50508035926020909101359150565b600080604083850312156141c6578182fd5b505080516020909101519092909150565b6000806000606084860312156141eb578081fd5b83359250602084013591506040840135613be3816150d7565b60008060008060008060c0878903121561421c578384fd5b8651614227816150fd565b8096505060208701519450604087015193506060870151614247816150d7565b809350506080870151915060a087015190509295509295509295565b6000806000806000806000610180888a03121561427e578081fd5b8751614289816150fd565b8097505060208801519550604088015194506060880151935060808801516142b0816150d7565b92506142bf8960a08a01613642565b91506101608801516001600160401b038111156142da578182fd5b8801601f81018a136142ea578182fd5b80516142f861360f82615086565b8181528b602083850101111561430c578384fd5b61431d8260208301602086016150a7565b80935050505092959891949750929550565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526143718160208601602086016150a7565b601f01601f19169290920160200192915050565b80518252602090810151910152565b805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a08301525050565b600081518352602082015160208401526040820151606060408501526143f76060850182614359565b949350505050565b6000828483379101908152919050565b600082516144218184602087016150a7565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b600060018060a01b038816825286602083015261ffff8616604083015284606083015260a0608083015261449a60a08301848661432f565b98975050505050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b038581168252602082018590528316604082015260806060820181905260009061187390830184614359565b901515815260200190565b941515855260208501939093526040840191909152151560608301521515608082015260a00190565b6000602082526133ba6020830184614359565b60208082526030908201527f53746172676174653a2062726964676520616e6420666163746f727920616c7260408201526f1958591e481a5b9a5d1a585b1a5e995960821b606082015260800190565b6020808252601e908201527f53746172676174653a205f746f6b656e2063616e6e6f74206265203078300000604082015260600190565b60208082526027908201527f53746172676174653a206e6f7420656e6f756768206c7020746f2072656465656040820152666d52656d6f746560c81b606082015260800190565b6020808252601e908201527f4272696467653a2063616c6c6572206d757374206265204272696467652e0000604082015260600190565b6020808252601b908201527f53746172676174653a206f6e6c79206d696e744665654f776e65720000000000604082015260600190565b60208082526019908201527f53746172676174653a206e6f2072657472792072657665727400000000000000604082015260600190565b6020808252601e908201527f53746172676174653a205452414e534645525f46524f4d5f4641494c45440000604082015260600190565b6020808252601d908201527f53746172676174653a20666163746f72792063616e7420626520307830000000604082015260600190565b6020808252601f908201527f53746172676174653a206f6e6c792070726f746f636f6c4665654f776e657200604082015260600190565b6020808252601c908201527f53746172676174653a206272696467652063616e742062652030783000000000604082015260600190565b60208082526021908201527f53746172676174653a206e6f7420656e6f756768206c7020746f2072656465656040820152606d60f81b606082015260800190565b6020808252602f908201527f53746172676174653a206e6f7420656e6f756768206c7020746f20726564656560408201526e1b481dda5d1a08185b5bdd5b9d14d1608a1b606082015260800190565b6020808252601e908201527f53746172676174653a205f6f776e65722063616e6e6f74206265203078300000604082015260600190565b6020808252601f908201527f53746172676174653a20636163686520616c726561647920636c656172656400604082015260600190565b60208082526017908201527f53746172676174653a2063616e6e6f7420737761702030000000000000000000604082015260600190565b6020808252601f908201527f53746172676174653a20696e76616c69642066756e6374696f6e207479706500604082015260600190565b6020808252601d908201527f53746172676174653a20506f6f6c20646f6573206e6f74206578697374000000604082015260600190565b60208082526026908201527f53746172676174653a205f726566756e64416464726573732063616e6e6f742060408201526506265203078360d41b606082015260800190565b61ffff861681526001600160a01b038516602082015260006149ba6040830186614385565b60c060808301526149ce60c08301856143ce565b82810360a084015261449a8185614359565b600061ffff8916825260c060208301526149fe60c08301888a61432f565b604083018790526001600160a01b03861660608401526080830185905282810360a0840152614a2d8185614359565b9a9950505050505050505050565b600061010061ffff8b168352806020840152614a598184018b614359565b604084018a90526001600160a01b03898116606086015260808501899052871660a085015283810360c08501529050614a928186614359565b905082810360e0840152614aa68185614359565b9b9a5050505050505050505050565b600061ffff8816825260c06020830152614ad260c0830188614359565b604083018790526001600160a01b03861660608401526080830185905282810360a0840152614b018185614359565b9998505050505050505050565b61ffff929092168252602082015260400190565b61ffff94909416845260208401929092526001600160a01b03166040830152606082015260800190565b61ffff96909616865260208601949094526001600160a01b0392909216604085015260608401526080830152151560a082015260c00190565b61ffff85168152602081018490526001600160a01b03831660408201526101208101614bb46060830184614394565b95945050505050565b61ffff95909516855260208501939093526001600160a01b039190911660408401526060830152608082015260a00190565b61ffff8416815260208101839052608081016143f76040830184614385565b61ffff93841681526020810192909252909116604082015260600190565b61ffff9390931683526020830191909152604082015260600190565b61ffff8616815260208101859052604081018490526001600160a01b038316606082015260c081016118736080830184614385565b61ffff8c168152602081018b9052604081018a90526001600160a01b038916606082015260006101e0614cb3608084018b614385565b614cc060c084018a614394565b80610180840152614cd3818401896143ce565b90508281036101a0840152614ce981878961432f565b90508281036101c0840152614cff81858761432f565b9e9d5050505050505050505050505050565b61ffff8a16815260208101899052604081018890526001600160a01b038716606082015260006101e0614d476080840189614385565b614d5460c0840188614394565b80610180840152614d67818401876143ce565b90508281036101a0840152614d7d81858761432f565b8381036101c0909401939093525081526020019998505050505050505050565b61ffff8a16815260208101899052604081018890526001600160a01b03871660608201526000610120614dd36080840189614385565b8660c08401528060e0840152614dec818401868861432f565b9050828103610100840152614e0181856143ce565b9c9b505050505050505050505050565b61ffff969096168652602086019490945260408501929092526001600160a01b03166060840152608083015260a082015260c00190565b600061ffff8916825287602083015286604083015260c06060830152614e7260c08301868861432f565b60808301949094525060a0015295945050505050565b600061ffff8916825260ff8816602083015260a06040830152614eaf60a08301878961432f565b8281036060840152614ec281868861432f565b90508281036080840152614a2d81856143ce565b90815260200190565b8681526001600160a01b038616602082015260ff85811660408301528416606082015260c060808201819052600090614f1a90830185614359565b82810360a0840152614b018185614359565b918252602082015260400190565b600060ff8616825261ffff8516602083015260806040830152614f606080830185614359565b905082606083015295945050505050565b60ff969096168652602086019490945260408501929092526001600160a01b03166060840152608083015260a082015260c00190565b600060ff8916825287602083015286604083015260ff8616606083015284608083015260c060a0830152614b0160c08301848661432f565b60ff881681526020810187905260408101869052606081018590526001600160a01b0384166080820152600061018061501b60a0840186614394565b80610160840152614a2d81840185614359565b600060ff8916825287602083015286604083015285606083015284608083015260c060a0830152614b0160c08301848661432f565b6040518181016001600160401b038111828210171561507e57fe5b604052919050565b60006001600160401b0382111561509957fe5b50601f01601f191660200190565b60005b838110156150c25781810151838201526020016150aa565b838111156150d1576000848401525b50505050565b6001600160a01b03811681146150ec57600080fd5b50565b80151581146150ec57600080fd5b60ff811681146150ec57600080fdfe5265656e7472616e637947756172643a207265656e7472616e742063616c6c004f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a2646970667358221220d86582ffb411c85869be51806318cb203c2835996c58fcb8521dd7b53c5baece64736f6c63430007060033
Deployed ByteCode Sourcemap
553:20274:13:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12905:1469;;;;;;;;;;-1:-1:-1;12905:1469:13;;;;;:::i;:::-;;:::i;:::-;;8851:392;;;;;;;;;;-1:-1:-1;8851:392:13;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;19334:152;;;;;;;;;;-1:-1:-1;19334:152:13;;;;;:::i;:::-;;:::i;18171:266::-;;;;;;;;;;-1:-1:-1;18171:266:13;;;;;:::i;:::-;;:::i;1642:91::-;;;;;;;;;;-1:-1:-1;1642:91:13;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;15711:425::-;;;;;;;;;;-1:-1:-1;15711:425:13;;;;;:::i;:::-;;:::i;18968:181::-;;;;;;;;;;-1:-1:-1;18968:181:13;;;;;:::i;:::-;;:::i;11964:540::-;;;;;;;;;;-1:-1:-1;11964:540:13;;;;;:::i;:::-;;:::i;2952:465::-;;;;;;;;;;-1:-1:-1;2952:465:13;;;;;:::i;:::-;;:::i;19835:358::-;;;;;;;;;;-1:-1:-1;19835:358:13;;;;;:::i;:::-;;:::i;20347:228::-;;;;;;;;;;-1:-1:-1;20347:228:13;;;;;:::i;:::-;;:::i;10487:1471::-;;;;;;:::i;:::-;;:::i;9249:1232::-;;;;;;:::i;:::-;;:::i;1700:145:3:-;;;;;;;;;;;;;:::i;17749:416:13:-;;;;;;;;;;-1:-1:-1;17749:416:13;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;18685:277::-;;;;;;;;;;-1:-1:-1;18685:277:13;;;;;:::i;:::-;;:::i;14380:402::-;;;;;;;;;;-1:-1:-1;14380:402:13;;;;;:::i;:::-;;:::i;5936:1147::-;;;;;;:::i;:::-;;:::i;4370:407::-;;;;;;;;;;-1:-1:-1;4370:407:13;;;;;:::i;:::-;;:::i;1068:85:3:-;;;;;;;;;;;;;:::i;7452:878:13:-;;;;;;:::i;:::-;;:::i;19673:156::-;;;;;;;;;;-1:-1:-1;19673:156:13;;;;;:::i;:::-;;:::i;8336:509::-;;;;;;:::i;:::-;;:::i;4783:1147::-;;;;;;:::i;:::-;;:::i;12510:277::-;;;;;;;;;;-1:-1:-1;12510:277:13;;;;;:::i;:::-;;:::i;1309:31::-;;;;;;;;;;;;;:::i;1407:27::-;;;;;;;;;;;;;:::i;1254:22::-;;;;;;;;;;;;;:::i;7089:357::-;;;;;;;;;;-1:-1:-1;7089:357:13;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;19492:175::-;;;;;;;;;;-1:-1:-1;19492:175:13;;;;;:::i;:::-;;:::i;18443:236::-;;;;;;;;;;-1:-1:-1;18443:236:13;;;;;:::i;:::-;;:::i;20581:244::-;;;;;;;;;;-1:-1:-1;20581:244:13;;;;;:::i;:::-;;:::i;19155:173::-;;;;;;;;;;-1:-1:-1;19155:173:13;;;;;:::i;:::-;;:::i;1523:82::-;;;;;;;;;;-1:-1:-1;1523:82:13;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1497:20::-;;;;;;;;;;;;;:::i;1994:240:3:-;;;;;;;;;;-1:-1:-1;1994:240:3;;;;;:::i;:::-;;:::i;20199:142:13:-;;;;;;;;;;-1:-1:-1;20199:142:13;;;;;:::i;:::-;;:::i;12905:1469::-;2864:6;;-1:-1:-1;;;;;2864:6:13;2842:10;:29;2834:72;;;;-1:-1:-1;;;2834:72:13;;;;;;;:::i;:::-;;;;;;;;;13172:9:::1;13184:20;13193:10;13184:8;:20::i;:::-;13218:65;::::0;-1:-1:-1;;;13218:65:13;;13172:32;;-1:-1:-1;;;;;;13218:29:13;::::1;::::0;::::1;::::0;:65:::1;::::0;13248:11;;13261:10;;13273:9;;13218:65:::1;;;:::i;:::-;;::::0;::::1;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;-1:-1:-1::0;13218:65:13::1;::::0;;::::1;;::::0;;::::1;-1:-1:-1::0;;13218:65:13::1;::::0;::::1;::::0;;;::::1;::::0;;::::1;::::0;::::1;:::i;:::-;;;13214:1154;;805:1;14228:10;14240;14252:1;14255:9;14266:3;;14189:81;;;;;;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;14189:81:13;;::::1;::::0;;;;;;14140:25:::1;::::0;::::1;;::::0;;;:12:::1;14189:81;14140:25:::0;;;;;14189:81;;14140:38:::1;::::0;14166:11;;14140:38:::1;:::i;:::-;;;;;;;;;;;;;:46;14179:6;14140:46;;;;;;;;;;;:130;;;;;;;;;;;;:::i;:::-;;14289:68;805:1;14324:11;14337;14350:6;14289:68;;;;;;;;;:::i;:::-;;;;;;;;13214:1154;;;805:1;13474:10;13502;13530:14;13562:12;13592:3;;13402:207;;;;;;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;13402:207:13;;::::1;::::0;;;;;;13353:25:::1;::::0;::::1;;::::0;;;:12:::1;13402:207;13353:25:::0;;;;;13402:207;;13353:38:::1;::::0;13379:11;;13353:38:::1;:::i;:::-;;;;;;;;;;;;;:46;13392:6;13353:46;;;;;;;;;;;:256;;;;;;;;;;;;:::i;:::-;;13726:11;13628:110;;;;;;:::i;:::-;;;;;;;;13718:6;13628:110;13646:11;13659:10;13671;13683:3;;13688:14;13704:12;13628:110;;;;;;;;;;;;:::i;:::-;;;;;;;;13284:465;;13214:1154;2916:1;12905:1469:::0;;;;;;;;:::o;8851:392::-;9134:6;;:102;;-1:-1:-1;;;9134:102:13;;9099:7;;;;-1:-1:-1;;;;;9134:6:13;;;;:24;;:102;;9159:11;;9172:13;;9187:10;;;;9199:23;;;;9224:11;;9134:102;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9127:109;;;;8851:392;;;;;;;;;;:::o;19334:152::-;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;19417:9:13::1;19429:17;19438:7;19429:8;:17::i;:::-;19456:23;::::0;-1:-1:-1;;;19456:23:13;;19417:29;;-1:-1:-1;;;;;;19456:11:13;::::1;::::0;::::1;::::0;:23:::1;::::0;19468:10;;19456:23:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;1350:1:3;19334:152:13::0;;:::o;18171:266::-;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;18337:9:13::1;18349:17;18358:7;18349:8;:17::i;:::-;18376:54;::::0;-1:-1:-1;;;18376:54:13;;18337:29;;-1:-1:-1;;;;;;18376:20:13;::::1;::::0;::::1;::::0;:54:::1;::::0;18397:11;;18410:10;;18422:7;;18376:54:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;1642:91:::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1642:91:13;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1642:91:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;15711:425::-;2864:6;;-1:-1:-1;;;;;2864:6:13;2842:10;:29;2834:72;;;;-1:-1:-1;;;2834:72:13;;;;;;;:::i;:::-;16025:104:::1;16037:11;16050;16063:6;16071:10;16083;16095:14;16111:3;16116:2;16120:8;16025:11;:104::i;18968:181::-:0;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;-1:-1:-1;;;;;19050:22:13;::::1;19042:65;;;;-1:-1:-1::0;;;19042:65:13::1;;;;;;;:::i;:::-;19117:16;:25:::0;;-1:-1:-1;;;;;;19117:25:13::1;-1:-1:-1::0;;;;;19117:25:13;;;::::1;::::0;;;::::1;::::0;;18968:181::o;11964:540::-;12125:29;;;12102:20;12125:29;;;:16;:29;;;;;;:42;;;;12155:11;;;;12125:42;:::i;:::-;;;;;;;;;;;;;;;;:50;;;;;;;;;;12102:73;;;;;;;-1:-1:-1;;;;;12102:73:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;12102:73:13;;;;;;;;;;;;;;;;;;;;;;;;12125:42;;:50;;12102:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;12102:73:13;;;;-1:-1:-1;;;12193:5:13;;;;12102:73;;-1:-1:-1;;;;;;12193:21:13;12185:65;;;;-1:-1:-1;;;12185:65:13;;;;;;;:::i;:::-;12339:45;;;;;;;;-1:-1:-1;12339:45:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12286:29;;;;;:16;:29;;;;;:42;;12339:45;;12286:29;:42;;12316:11;;;;12286:42;:::i;:::-;;;;;;;;;;;;;;;;:50;;;;;;;;;;:98;;;;-1:-1:-1;;;;;;12286:98:13;;;-1:-1:-1;;;;;12286:98:13;;;;;;;;;;-1:-1:-1;12286:98:13;;;;;;;;;;;;;;;;;;;;;;;;;;;:50;;:98;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;12412:5:13;;;;;12463:8;;12473:11;;;;12486:10;;;;12394:103;;-1:-1:-1;;;12394:103:13;;-1:-1:-1;;;;;12394:34:13;;;;;;:103;;12429:11;;12442;;;;12455:6;;12463:8;12473:11;12486:10;12394:103;;;:::i;2952:465::-;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;3060:6:13::1;::::0;-1:-1:-1;;;;;3060:6:13::1;3052:31:::0;:67;::::1;;;-1:-1:-1::0;3095:7:13::1;::::0;-1:-1:-1;;;;;3095:7:13::1;3087:32:::0;3052:67:::1;3044:128;;;;-1:-1:-1::0;;;3044:128:13::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;3205:32:13;::::1;3197:73;;;;-1:-1:-1::0;;;3197:73:13::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;3288:33:13;::::1;3280:75;;;;-1:-1:-1::0;;;3280:75:13::1;;;;;;;:::i;:::-;3366:6;:16:::0;;-1:-1:-1;;;;;3366:16:13;;::::1;-1:-1:-1::0;;;;;;3366:16:13;;::::1;;::::0;;;3392:7:::1;:18:::0;;;;;::::1;::::0;::::1;;::::0;;2952:465::o;19835:358::-;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;20059:9:13::1;20071:17;20080:7;20071:8;:17::i;:::-;20098:88;::::0;-1:-1:-1;;;20098:88:13;;20059:29;;-1:-1:-1;;;;;;20098:18:13;::::1;::::0;::::1;::::0;:88:::1;::::0;20117:8;;20127:12;;20141:10;;20153:16;;20171:14;;20098:88:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;1350:1:3;19835:358:13::0;;;;;;:::o;20347:228::-;20429:12;;-1:-1:-1;;;;;20429:12:13;20445:10;20429:26;20421:66;;;;-1:-1:-1;;;20421:66:13;;;;;;;:::i;:::-;20497:9;20509:17;20518:7;20509:8;:17::i;:::-;20536:32;;-1:-1:-1;;;20536:32:13;;20497:29;;-1:-1:-1;;;;;;20536:27:13;;;;;:32;;20564:3;;20536:32;;;:::i;10487:1471::-;10652:25;;;10629:20;10652:25;;;:12;:25;;;;;;:38;;;;10678:11;;;;10652:38;:::i;:::-;;;;;;;;;;;;;;;;:46;;;;;;;;;;10629:69;;;;;;;;;-1:-1:-1;;10629:69:13;;;;;;;;;;;;;;;;;;;;;;;10652:38;;:46;;10629:69;;;10652:46;10629:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10733:1;10716:7;:14;:18;10708:56;;;;-1:-1:-1;;;10708:56:13;;;;;;;:::i;:::-;10795:51;;;;;;;;;-1:-1:-1;10795:51:13;;;:25;;;;;:12;:25;;;;;;:38;;:51;;:25;:38;;10821:11;;;;10795:38;:::i;:::-;;;;;;;;;;;;;:46;10834:6;10795:46;;;;;;;;;;;:51;;;;;;;;;;;;:::i;:::-;-1:-1:-1;10943:2:13;10930:16;;10924:23;10971:48;;;871:1;10971:48;10967:985;;;11038:17;11057;11076:10;11088:16;11106:20;11158:7;11130:119;;;;;;;;;;;;:::i;:::-;11035:214;;;;;;;;;;;11263:104;11284:11;11297;;11263:104;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11310:6:13;;-1:-1:-1;11318:9:13;;-1:-1:-1;11329:9:13;;-1:-1:-1;11340:2:13;11344:8;11354:12;11263:20;:104::i;:::-;10967:985;;;;;;;;11461:38;;;927:1;11461:38;11457:495;;;11518:17;11537;11556:21;11579:10;11591:21;11614:14;11660:7;11632:131;;;;;;;;;;;;:::i;:::-;11515:248;;;;;;;;;;;;;11777:92;11789:11;11802;;11777:92;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11815:6:13;;-1:-1:-1;11823:9:13;;-1:-1:-1;11834:9:13;;-1:-1:-1;11845:13:13;11860:2;11864:1;11867;11777:11;:92::i;:::-;11457:495;;;;;;;;;11900:41;;-1:-1:-1;;;11900:41:13;;;;;;;:::i;11457:495::-;10487:1471;;;;;;:::o;9249:1232::-;-1:-1:-1;;;;;9481:30:13;;9473:81;;;;-1:-1:-1;;;9473:81:13;;;;;;;:::i;:::-;9587:25;;;9564:20;9587:25;;;:12;:25;;;;;;:38;;;;9613:11;;;;9587:38;:::i;:::-;;;;;;;;;;;;;;;;:46;;;;;;;;;;9564:69;;;;;;;;;-1:-1:-1;;9564:69:13;;;;;;;;;;;;;;;;;;;;;;;9587:38;;:46;;9564:69;;;9587:46;9564:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9668:1;9651:7;:14;:18;9643:56;;;;-1:-1:-1;;;9643:56:13;;;;;;;:::i;:::-;9817:2;9804:16;;9798:23;9856:42;;;805:1;9856:42;9848:86;;;;-1:-1:-1;;;9848:86:13;;;;;;;:::i;:::-;-1:-1:-1;9975:51:13;;;;;;;;;-1:-1:-1;9975:51:13;;;:25;;;;;:12;:25;;;;;;:38;;:51;;:25;:38;;10001:11;;;;9975:38;:::i;:::-;;;;;;;;;;;;;:46;10014:6;9975:46;;;;;;;;;;;:51;;;;;;;;;;;;:::i;:::-;-1:-1:-1;10146:2:13;10133:16;;10127:23;10195:2;10182:16;;10176:23;10219;;:::i;:::-;10266:9;10278:19;10287:9;10278:8;:19::i;:::-;10315:40;;-1:-1:-1;;;10315:40:13;;10266:31;;-1:-1:-1;;;;;;10315:16:13;;;;;:40;;10332:11;;10345:9;;10315:40;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10376:6;;:98;;-1:-1:-1;;;10376:98:13;;10311:44;;-1:-1:-1;;;;;;10376:6:13;;-1:-1:-1;10376:26:13;;10410:9;;10376:98;;10421:11;;10434:14;;10311:44;;10453:11;;10466:7;;10376:98;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9249:1232;;;;;;;;;;:::o;1700:145:3:-;1291:12;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;1806:1:::1;1790:6:::0;;1769:40:::1;::::0;-1:-1:-1;;;;;1790:6:3;;::::1;::::0;1769:40:::1;::::0;1806:1;;1769:40:::1;1836:1;1819:19:::0;;-1:-1:-1;;;;;;1819:19:3::1;::::0;;1700:145::o;17749:416:13:-;17973:7;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;-1:-1:-1;;;;;18000:22:13;::::1;17992:65;;;;-1:-1:-1::0;;;17992:65:13::1;;;;;;;:::i;:::-;18074:7;::::0;:84:::1;::::0;-1:-1:-1;;;18074:84:13;;-1:-1:-1;;;;;18074:7:13;;::::1;::::0;:18:::1;::::0;:84:::1;::::0;18093:7;;18102:6;;18110:15;;18127:14;;18143:5;;18150:7;;18074:84:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;18067:91;;1350:1:3;17749:416:13::0;;;;;;;;:::o;18685:277::-;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;18856:9:13::1;18868:17;18877:7;18868:8;:17::i;:::-;18895:60;::::0;-1:-1:-1;;;18895:60:13;;18856:29;;-1:-1:-1;;;;;;18895:26:13;::::1;::::0;::::1;::::0;:60:::1;::::0;18922:11;;18935:10;;18947:7;;18895:60:::1;;;:::i;14380:402::-:0;2864:6;;-1:-1:-1;;;;;2864:6:13;2842:10;:29;2834:72;;;;-1:-1:-1;;;2834:72:13;;;;;;;:::i;:::-;14666:109:::1;14687:11;14700;14713:6;14721:10;14733;14745:3;14750:9;14761:13;14666:20;:109::i;:::-;14380:402:::0;;;;;;;;:::o;5936:1147::-;1680:1:8;2260:7;;:19;;2252:63;;;;;-1:-1:-1;;;2252:63:8;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:63:8;;;;;;;;;;;;;;;1680:1;2390:7;:18;-1:-1:-1;;;;;6266:30:13;::::1;6258:81;;;;-1:-1:-1::0;;;6258:81:13::1;;;;;;;:::i;:::-;6369:1;6357:9;:13;6349:65;;;;-1:-1:-1::0;;;6349:65:13::1;;;;;;;:::i;:::-;6424:21;;:::i;:::-;6455:23;;:::i;:::-;6502:9;6514:20;6523:10;6514:8;:20::i;:::-;6502:32;;6548:16;6567:4;-1:-1:-1::0;;;;;6567:17:13::1;;6585:9;6567:28;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6548:47;;6661:4;-1:-1:-1::0;;;;;6661:9:13::1;;6671:11;6684:10;6696;6708:8;6718:12;6732:5;6661:77;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6657:81;;6752:4;-1:-1:-1::0;;;;;6752:17:13::1;;6770:11;6783:10;6795;6807:9;6752:65;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;6835:4;-1:-1:-1::0;;;;;6835:16:13::1;;6852:11;6865:10;6835:41;;;;;;;;;;;;;;;;:::i;:::-;;::::0;::::1;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6831:45;;2419:1:8;;6966:6:13;;;;;;;;;-1:-1:-1::0;;;;;6966:6:13::1;-1:-1:-1::0;;;;;6966:11:13::1;;6985:9;6996:11;7009:10;7021;7033:14;7049:1;7052;7055:11;7068:3;;6966:110;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;1637:1:8;2563:22;;-1:-1:-1;;;;;;;;;;;;;;5936:1147:13:o;4370:407::-;1680:1:8;2260:7;;:19;;2252:63;;;;;-1:-1:-1;;;2252:63:8;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:63:8;;;;;;;;;;;;;;;1680:1;2390:7;:18;4512:9:13::1;4524:17;4533:7:::0;4524:8:::1;:17::i;:::-;4512:29;;4551:19;4573:4;-1:-1:-1::0;;;;;4573:16:13::1;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4551:40:::0;-1:-1:-1;4613:43:13::1;4551:40:::0;4613:26:::1;:9:::0;4551:40;4613:13:::1;:26::i;:::-;:30:::0;::::1;:43::i;:::-;4601:55;;4666:69;4684:4;-1:-1:-1::0;;;;;4684:10:13::1;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4698:10;4718:4;4725:9;4666:17;:69::i;:::-;4745:25;::::0;-1:-1:-1;;;4745:25:13;;-1:-1:-1;;;;;4745:9:13;::::1;::::0;::::1;::::0;:25:::1;::::0;4755:3;;4760:9;;4745:25:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;1637:1:8;2563:22;;-1:-1:-1;;;;4370:407:13:o;1068:85:3:-;1114:7;1140:6;-1:-1:-1;;;;;1140:6:3;1068:85;:::o;7452:878:13:-;1680:1:8;2260:7;;:19;;2252:63;;;;;-1:-1:-1;;;2252:63:8;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:63:8;;;;;;;;;;;;;;;1680:1;2390:7;:18;-1:-1:-1;;;;;7751:30:13;::::1;7743:81;;;;-1:-1:-1::0;;;7743:81:13::1;;;;;;;:::i;:::-;7834:9;7846:20;7855:10;7846:8;:20::i;:::-;7834:32;;7896:1;7884:9;:13;7876:59;;;;-1:-1:-1::0;;;7876:59:13::1;;;;;;;:::i;:::-;7964:69;::::0;-1:-1:-1;;;7964:69:13;;7945:16:::1;::::0;-1:-1:-1;;;;;7964:16:13;::::1;::::0;::::1;::::0;:69:::1;::::0;7981:10:::1;::::0;7993:9;;8004:11;;8017:10;;8029:3;;;;7964:69:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7945:88;;8062:1;8051:8;:12;8043:72;;;;-1:-1:-1::0;;;8043:72:13::1;;;;;;;:::i;:::-;8152:41;::::0;-1:-1:-1;;;8152:41:13;;8126:23:::1;::::0;-1:-1:-1;;;;;8152:16:13;::::1;::::0;::::1;::::0;:41:::1;::::0;8169:11;;8182:10;;8152:41:::1;;;:::i;:::-;;::::0;::::1;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8126:67;;8203:6;;;;;;;;;-1:-1:-1::0;;;;;8203:6:13::1;-1:-1:-1::0;;;;;8203:18:13::1;;8229:9;8240:11;8253:10;8265;8277:14;8293:1;8296:8;8306:3;;8311:11;8203:120;;;;;;;;;;;;;;;;;;;;;;;:::i;19673:156::-:0;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;19756:9:13::1;19768:17;19777:7;19768:8;:17::i;:::-;19795:27;::::0;-1:-1:-1;;;19795:27:13;;19756:29;;-1:-1:-1;;;;;;19795:16:13;::::1;::::0;::::1;::::0;:27:::1;::::0;19812:9;;19795:27:::1;;;:::i;8336:509::-:0;1680:1:8;2260:7;;:19;;2252:63;;;;;-1:-1:-1;;;2252:63:8;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:63:8;;;;;;;;;;;;;;;1680:1;2390:7;:18;-1:-1:-1;;;;;8544:30:13;::::1;8536:81;;;;-1:-1:-1::0;;;8536:81:13::1;;;;;;;:::i;:::-;8627:9;8639:20;8648:10;8639:8;:20::i;:::-;8627:32;;8669:23;8695:4;-1:-1:-1::0;;;;;8695:16:13::1;;8712:11;8725:10;8695:41;;;;;;;;;;;;;;;;:::i;:::-;;::::0;::::1;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8746:6;::::0;:92:::1;::::0;-1:-1:-1;;;8746:92:13;;8669:67;;-1:-1:-1;;;;;;8746:6:13::1;::::0;:18:::1;::::0;8772:9:::1;::::0;8746:92:::1;::::0;8783:11;;8796:10;;8808;;8820:14;;8669:67;;8746:92:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;1637:1:8;2563:22;;-1:-1:-1;;;;;;;;;8336:509:13:o;4783:1147::-;1680:1:8;2260:7;;:19;;2252:63;;;;;-1:-1:-1;;;2252:63:8;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:63:8;;;;;;;;;;;;;;;1680:1;2390:7;:18;5138:13:13;5130:49:::1;;;;-1:-1:-1::0;;;5130:49:13::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;5197:30:13;::::1;5189:81;;;;-1:-1:-1::0;;;5189:81:13::1;;;;;;;:::i;:::-;5280:21;;:::i;:::-;5311:23;;:::i;:::-;5358:9;5370:20;5379:10;5370:8;:20::i;:::-;5358:32;;5422:19;5444:4;-1:-1:-1::0;;;;;5444:16:13::1;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5422:40:::0;-1:-1:-1;5492:43:13::1;5422:40:::0;5492:26:::1;:9:::0;5422:40;5492:13:::1;:26::i;:43::-;5480:55;;2419:1:8;5568:4:13;-1:-1:-1::0;;;;;5568:9:13::1;;5578:11;5591:10;5603;5615:9;5626:12;5640:4;5568:77;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5564:81;;5659:69;5677:4;-1:-1:-1::0;;;;;5677:10:13::1;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5691:10;5711:4;5718:9;5659:17;:69::i;:::-;5746:4;-1:-1:-1::0;;;;;5746:16:13::1;;5763:11;5776:10;5746:41;;;;;;;;;;;;;;;;:::i;:::-;;::::0;::::1;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5742:45;;2419:1:8;5807:6:13;;;;;;;;;-1:-1:-1::0;;;;;5807:6:13::1;-1:-1:-1::0;;;;;5807:11:13::1;;5826:9;5837:11;5850:10;5862;5874:14;5890:1;5893;5896:11;5909:3;;5914:8;;5807:116;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;1637:1:8;2563:22;;-1:-1:-1;;;;;;;;;;;;;;;;4783:1147:13:o;12510:277::-;2864:6;;-1:-1:-1;;;;;2864:6:13;2842:10;:29;2834:72;;;;-1:-1:-1;;;2834:72:13;;;;;;;:::i;:::-;12689:9:::1;12701:20;12710:10;12701:8;:20::i;:::-;12731:49;::::0;-1:-1:-1;;;12731:49:13;;12689:32;;-1:-1:-1;;;;;;12731:20:13;::::1;::::0;::::1;::::0;:49:::1;::::0;12752:11;;12765:10;;12777:2;;12731:49:::1;;;:::i;1309:31::-:0;;;-1:-1:-1;;;;;1309:31:13;;:::o;1407:27::-;;;-1:-1:-1;;;;;1407:27:13;;:::o;1254:22::-;;;-1:-1:-1;;;;;1254:22:13;;:::o;7089:357::-;7238:16;1680:1:8;2260:7;;:19;;2252:63;;;;;-1:-1:-1;;;2252:63:8;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:63:8;;;;;;;;;;;;;;;1680:1;2390:7;:18;7274:13:13;7266:59:::1;;;;-1:-1:-1::0;;;7266:59:13::1;;;;;;;:::i;:::-;7335:9;7347:20;7356:10;7347:20;;:8;:20::i;:::-;7388:51;::::0;-1:-1:-1;;;7388:51:13;;7335:32;;-1:-1:-1;;;;;;7388:23:13;::::1;::::0;::::1;::::0;:51:::1;::::0;7412:10:::1;::::0;7424:9;;7435:3;;7388:51:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1637:1:8::0;2563:22;;7377:62:13;7089:357;-1:-1:-1;;;;;7089:357:13:o;19492:175::-;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;19586:9:13::1;19598:17;19607:7;19598:8;:17::i;:::-;19625:35;::::0;-1:-1:-1;;;19625:35:13;;19586:29;;-1:-1:-1;;;;;;19625:18:13;::::1;::::0;::::1;::::0;:35:::1;::::0;19644:15;;19625:35:::1;;;:::i;18443:236::-:0;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;18586:9:13::1;18598:17;18607:7;18598:8;:17::i;:::-;18625:47;::::0;-1:-1:-1;;;18625:47:13;;18586:29;;-1:-1:-1;;;;;;18625:22:13;::::1;::::0;::::1;::::0;:47:::1;::::0;18648:11;;18661:10;;18625:47:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;20581:244:::0;20667:16;;-1:-1:-1;;;;;20667:16:13;20687:10;20667:30;20659:74;;;;-1:-1:-1;;;20659:74:13;;;;;;;:::i;:::-;20743:9;20755:17;20764:7;20755:8;:17::i;:::-;20782:36;;-1:-1:-1;;;20782:36:13;;20743:29;;-1:-1:-1;;;;;;20782:31:13;;;;;:36;;20814:3;;20782:36;;;:::i;19155:173::-;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;-1:-1:-1;;;;;19233:22:13;::::1;19225:65;;;;-1:-1:-1::0;;;19225:65:13::1;;;;;;;:::i;:::-;19300:12;:21:::0;;-1:-1:-1;;;;;;19300:21:13::1;-1:-1:-1::0;;;;;19300:21:13;;;::::1;::::0;;;::::1;::::0;;19155:173::o;1523:82::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1523:82:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1497:20::-;;;-1:-1:-1;;;;;1497:20:13;;:::o;1994:240:3:-;1291:12;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;-1:-1:-1;;;;;2082:22:3;::::1;2074:73;;;;-1:-1:-1::0;;;2074:73:3::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2183:6;::::0;;2162:38:::1;::::0;-1:-1:-1;;;;;2162:38:3;;::::1;::::0;2183:6;::::1;::::0;2162:38:::1;::::0;::::1;2210:6;:17:::0;;-1:-1:-1;;;;;;2210:17:3::1;-1:-1:-1::0;;;;;2210:17:3;;;::::1;::::0;;;::::1;::::0;;1994:240::o;20199:142:13:-;20270:9;20282:17;20291:7;20282:8;:17::i;:::-;20309:25;;-1:-1:-1;;;20309:25:13;;20270:29;;-1:-1:-1;;;;;;20309:14:13;;;;;:25;;20324:9;;20309:25;;;:::i;3518:198::-;3604:7;;:24;;-1:-1:-1;;;3604:24:13;;3576:9;;-1:-1:-1;;;;;3604:7:13;;:15;;:24;;3620:7;;3604:24;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3597:31;-1:-1:-1;;;;;;3646:29:13;;3638:71;;;;-1:-1:-1;;;3638:71:13;;;;;;;:::i;:::-;3518:198;;;:::o;598:104:7:-;685:10;598:104;:::o;16142:1502:13:-;16446:9;16458:20;16467:10;16458:8;:20::i;:::-;16535:49;;-1:-1:-1;;;16535:49:13;;16446:32;;-1:-1:-1;;;;;;16535:15:13;;;;;:49;;16551:11;;16564:10;;16576:3;;16581:2;;16535:49;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16535:49:13;;;;;;;;-1:-1:-1;;16535:49:13;;;;;;;;;;;;:::i;:::-;;;16531:1107;;927:1;17393:10;17421;17449:14;17481:3;17502:2;17522:8;17325:219;;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;17325:219:13;;;;;;;;;17276:25;;;;;;;:12;17325:219;17276:25;;;;;17325:219;;17276:38;;17302:11;;17276:38;:::i;:::-;;;;;;;;;;;;;:46;17315:6;17276:46;;;;;;;;;;;:268;;;;;;;;;;;;:::i;:::-;;17563:64;927:1;17594:11;17607;17620:6;17563:64;;;;;;;;;:::i;:::-;;;;;;;;16531:1107;;;16630:23;16649:3;16630:18;:23::i;:::-;:46;;;;;16675:1;16657:8;:15;:19;16630:46;16626:619;;;16779:3;-1:-1:-1;;;;;16761:32:13;;16799:14;16815:11;16828;16841:6;16849:4;-1:-1:-1;;;;;16849:10:13;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16863:8;16873;16761:121;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16757:474;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17040:49;;;;;;;;17051:4;-1:-1:-1;;;;;17051:10:13;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;17040:49:13;;;;;17065:8;17040:49;;;;17075:3;-1:-1:-1;;;;;17040:49:13;;;;;17080:8;17040:49;;;16987:16;:29;17004:11;16987:29;;;;;;;;;;;;;;;17017:11;16987:42;;;;;;:::i;:::-;;;;;;;;;;;;;;;;:50;;;;;;;;;;:102;;;;-1:-1:-1;;;;;;16987:102:13;;;-1:-1:-1;;;;;16987:102:13;;;;;;;;;;-1:-1:-1;16987:102:13;;;;;;;;;;;;;;;;;;;;;;;;;;;:50;;:102;;;;;;;;;;;:::i;:::-;;;;;17116:96;17132:11;17145;17158:6;17166:4;-1:-1:-1;;;;;17166:10:13;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;17180:8;17190:3;17195:8;17205:6;17116:96;;;;;;;;;;;;;:::i;:::-;;;;;;;;16937:294;16757:474;;16531:1107;16142:1502;;;;;;;;;;:::o;14788:917::-;15064:9;15076:20;15085:10;15076:8;:20::i;:::-;15110:80;;-1:-1:-1;;;15110:80:13;;15064:32;;-1:-1:-1;;;;;;15110:24:13;;;;;:80;;15135:11;;15148:10;;15160:3;;15165:9;;15176:13;;15110:80;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15106:470;;871:1;15341:10;15369;15397:3;15418:9;15445:13;15263:209;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;15263:209:13;;;;;;;;;15214:25;;;;;;;:12;15263:209;15214:25;;;;;15263:209;;15214:38;;15240:11;;15214:38;:::i;:::-;;;;;;;;;;;;;:46;15253:6;15214:46;;;;;;;;;;;:258;;;;;;;;;;;;:::i;:::-;;15491:74;871:1;15532:11;15545;15558:6;15491:74;;;;;;;;;:::i;:::-;;;;;;;;15106:470;15636:6;15623:11;15590:108;;;;;;:::i;:::-;;;;;;;;;15610:11;15644:10;15656;15668:3;15673:9;15684:13;15590:108;;;;;;;;;;;:::i;:::-;;;;;;;;14788:917;;;;;;;;;:::o;4209:150:4:-;4267:7;4298:1;4294;:5;4286:44;;;;;-1:-1:-1;;;4286:44:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;4351:1;4347;:5;;;;;;4340:12;;4209:150;;;;;:::o;3530:215::-;3588:7;3611:6;3607:20;;-1:-1:-1;3626:1:4;3619:8;;3607:20;3649:5;;;3653:1;3649;:5;:1;3672:5;;;;;:10;3664:56;;;;-1:-1:-1;;;3664:56:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3737:1;3530:215;-1:-1:-1;;;3530:215:4:o;3820:433:13:-;4038:12;4052:17;4073:5;-1:-1:-1;;;;;4073:10:13;4107;4119:4;4125:2;4129:5;4084:51;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;4084:51:13;;;;;;;;;;;4073:63;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4037:99;;;;4154:7;:57;;;;-1:-1:-1;4166:11:13;;:16;;:44;;;4197:4;4186:24;;;;;;;;;;;;:::i;:::-;4146:100;;;;-1:-1:-1;;;4146:100:13;;;;;;;:::i;718:413:6:-;1078:20;1116:8;;;718:413::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;14:138:17;84:20;;113:33;84:20;113:33;:::i;157:377::-;;;274:3;267:4;259:6;255:17;251:27;241:2;;299:8;289;282:26;241:2;-1:-1:-1;329:20:17;;-1:-1:-1;;;;;361:30:17;;358:2;;;411:8;401;394:26;358:2;455:4;447:6;443:17;431:29;;507:3;500:4;491:6;483;479:19;475:30;472:39;469:2;;;524:1;521;514:12;469:2;231:303;;;;;:::o;539:485::-;;636:3;629:4;621:6;617:17;613:27;603:2;;658:5;651;644:20;603:2;698:6;685:20;729:49;744:33;774:2;744:33;:::i;:::-;729:49;:::i;:::-;803:2;794:7;787:19;849:3;842:4;837:2;829:6;825:15;821:26;818:35;815:2;;;870:5;863;856:20;815:2;939;932:4;924:6;920:17;913:4;904:7;900:18;887:55;962:16;;;980:4;958:27;951:42;;;;966:7;593:431;-1:-1:-1;;593:431:17:o;1029:711::-;;1145:4;1133:9;1128:3;1124:19;1120:30;1117:2;;;1167:5;1160;1153:20;1117:2;1204;1198:9;1246:4;1238:6;1234:17;1317:6;1305:10;1302:22;-1:-1:-1;;;;;1269:10:17;1266:34;1263:62;1260:2;;;1328:9;1260:2;1359:10;1355:2;1348:22;;1388:6;1379:15;;1424:9;1418:16;1410:6;1403:32;1489:2;1478:9;1474:18;1468:25;1463:2;1455:6;1451:15;1444:50;1548:2;1537:9;1533:18;1527:25;1522:2;1514:6;1510:15;1503:50;1607:2;1596:9;1592:18;1586:25;1581:2;1573:6;1569:15;1562:50;1667:3;1656:9;1652:19;1646:26;1640:3;1632:6;1628:16;1621:52;1728:3;1717:9;1713:19;1707:26;1701:3;1693:6;1689:16;1682:52;;1107:633;;;;:::o;1745:674::-;;1850:4;1838:9;1833:3;1829:19;1825:30;1822:2;;;1872:5;1865;1858:20;1822:2;1909;1903:9;1951:4;1943:6;1939:17;-1:-1:-1;;;;;2043:6:17;2031:10;2028:22;2023:2;2011:10;2008:18;2005:46;2002:2;;;2054:9;2002:2;2085:10;2081:2;2074:22;2114:6;2105:15;;2157:9;2144:23;2136:6;2129:39;2229:2;2218:9;2214:18;2201:32;2196:2;2188:6;2184:15;2177:57;2285:2;2274:9;2270:18;2257:32;2243:46;;2312:2;2304:6;2301:14;2298:2;;;2328:1;2325;2318:12;2298:2;;2365:47;2408:3;2399:6;2388:9;2384:22;2365:47;:::i;:::-;2360:2;2352:6;2348:15;2341:72;;;1812:607;;;;:::o;2424:161::-;2493:20;;2553:6;2542:18;;2532:29;;2522:2;;2575:1;2572;2565:12;2590:259;;2702:2;2690:9;2681:7;2677:23;2673:32;2670:2;;;2723:6;2715;2708:22;2670:2;2767:9;2754:23;2786:33;2813:5;2786:33;:::i;2854:263::-;;2977:2;2965:9;2956:7;2952:23;2948:32;2945:2;;;2998:6;2990;2983:22;2945:2;3035:9;3029:16;3054:33;3081:5;3054:33;:::i;3122:257::-;;3242:2;3230:9;3221:7;3217:23;3213:32;3210:2;;;3263:6;3255;3248:22;3210:2;3300:9;3294:16;3319:30;3343:5;3319:30;:::i;3384:433::-;;;3544:2;3532:9;3523:7;3519:23;3515:32;3512:2;;;3565:6;3557;3550:22;3512:2;3609:9;3596:23;3628:33;3655:5;3628:33;:::i;:::-;3680:5;-1:-1:-1;3737:2:17;3722:18;;3709:32;3750:35;3709:32;3750:35;:::i;:::-;3804:7;3794:17;;;3502:315;;;;;:::o;4103:504::-;;4253:2;4241:9;4232:7;4228:23;4224:32;4221:2;;;4274:6;4266;4259:22;4221:2;4312;4306:9;4354:2;4346:6;4342:15;4423:6;4411:10;4408:22;-1:-1:-1;;;;;4375:10:17;4372:34;4369:62;4366:2;;;4434:9;4366:2;4461;4454:22;4500:16;;4485:32;;4571:2;4556:18;;;4550:25;4533:15;;;4526:50;;;;-1:-1:-1;4492:6:17;4211:396;-1:-1:-1;4211:396:17:o;4612:263::-;;4760:3;4748:9;4739:7;4735:23;4731:33;4728:2;;;4782:6;4774;4767:22;4728:2;4810:59;4861:7;4850:9;4810:59;:::i;4880:573::-;;;;;5044:2;5032:9;5023:7;5019:23;5015:32;5012:2;;;5065:6;5057;5050:22;5012:2;5093:30;5113:9;5093:30;:::i;:::-;5083:40;;5174:2;5163:9;5159:18;5146:32;-1:-1:-1;;;;;5193:6:17;5190:30;5187:2;;;5238:6;5230;5223:22;5187:2;5282:60;5334:7;5325:6;5314:9;5310:22;5282:60;:::i;:::-;5002:451;;5361:8;;-1:-1:-1;5256:86:17;;5443:2;5428:18;5415:32;;5002:451;-1:-1:-1;;;;5002:451:17:o;5458:977::-;;;;;;;5689:3;5677:9;5668:7;5664:23;5660:33;5657:2;;;5711:6;5703;5696:22;5657:2;5739:30;5759:9;5739:30;:::i;:::-;5729:40;;5820:2;5809:9;5805:18;5792:32;-1:-1:-1;;;;;5884:2:17;5876:6;5873:14;5870:2;;;5905:6;5897;5890:22;5870:2;5949:60;6001:7;5992:6;5981:9;5977:22;5949:60;:::i;:::-;6028:8;;-1:-1:-1;5923:86:17;-1:-1:-1;6110:2:17;6095:18;;6082:32;;-1:-1:-1;6164:2:17;6149:18;;6136:32;;-1:-1:-1;6177:33:17;6136:32;6177:33;:::i;:::-;6229:5;;-1:-1:-1;6287:3:17;6272:19;;6259:33;;6304:16;;;6301:2;;;6338:6;6330;6323:22;6301:2;;6366:63;6421:7;6410:8;6399:9;6395:24;6366:63;:::i;:::-;6356:73;;;5647:788;;;;;;;;:::o;6440:484::-;;;;6594:2;6582:9;6573:7;6569:23;6565:32;6562:2;;;6615:6;6607;6600:22;6562:2;6643:30;6663:9;6643:30;:::i;:::-;6633:40;;6724:2;6713:9;6709:18;6696:32;-1:-1:-1;;;;;6743:6:17;6740:30;6737:2;;;6788:6;6780;6773:22;6737:2;6816:51;6859:7;6850:6;6839:9;6835:22;6816:51;:::i;:::-;6806:61;;;6914:2;6903:9;6899:18;6886:32;6876:42;;6552:372;;;;;:::o;6929:898::-;;;;;;;;;7168:3;7156:9;7147:7;7143:23;7139:33;7136:2;;;7190:6;7182;7175:22;7136:2;7218:30;7238:9;7218:30;:::i;:::-;7208:40;;7299:2;7288:9;7284:18;7271:32;-1:-1:-1;;;;;7318:6:17;7315:30;7312:2;;;7363:6;7355;7348:22;7312:2;7391:51;7434:7;7425:6;7414:9;7410:22;7391:51;:::i;:::-;7381:61;;;7489:2;7478:9;7474:18;7461:32;7451:42;;7540:2;7529:9;7525:18;7512:32;7502:42;;7591:3;7580:9;7576:19;7563:33;7553:43;;7646:3;7635:9;7631:19;7618:33;7660;7687:5;7660:33;:::i;:::-;7126:701;;;;-1:-1:-1;7126:701:17;;;;;;7712:5;;-1:-1:-1;;;7764:3:17;7749:19;;7736:33;;7816:3;7801:19;7788:33;;7126:701::o;7832:1788::-;;;;;;;;;;8113:9;8104:7;8100:23;8143:3;8139:2;8135:12;8132:2;;;8165:6;8157;8150:22;8132:2;8193:30;8213:9;8193:30;:::i;:::-;8183:40;;8274:2;8263:9;8259:18;8246:32;-1:-1:-1;;;;;8338:2:17;8330:6;8327:14;8324:2;;;8359:6;8351;8344:22;8324:2;8387:51;8430:7;8421:6;8410:9;8406:22;8387:51;:::i;:::-;8377:61;;8485:2;8474:9;8470:18;8457:32;8447:42;;8536:2;8525:9;8521:18;8508:32;8498:42;;8587:3;8576:9;8572:19;8559:33;8549:43;;8639:3;8628:9;8624:19;8611:33;8601:43;;8694:3;8683:9;8679:19;8666:33;8653:46;;8708:33;8735:5;8708:33;:::i;:::-;8760:5;8750:15;;8800:3;8793;8789:8;8785:2;8781:17;8777:27;8774:2;;;8822:6;8814;8807:22;8774:2;8860;8854:9;8840:23;;8902:3;8894:6;8890:16;8872:34;;8956:6;8944:10;8941:22;8936:2;8924:10;8921:18;8918:46;8915:2;;;8967:9;8915:2;8998:10;8994:2;8987:22;9061:3;9050:9;9046:19;9033:33;9025:6;9018:49;9128:3;9117:9;9113:19;9100:33;9095:2;9087:6;9083:15;9076:58;9195:3;9184:9;9180:19;9167:33;9162:2;9154:6;9150:15;9143:58;9262:3;9251:9;9247:19;9234:33;9229:2;9221:6;9217:15;9210:58;9330:3;9319:9;9315:19;9302:33;9296:3;9288:6;9284:16;9277:59;9398:3;9387:9;9383:19;9370:33;9364:3;9356:6;9352:16;9345:59;9423:6;9413:16;;9482:3;9471:9;9467:19;9454:33;9438:49;;9512:2;9502:8;9499:16;9496:2;;;9533:6;9525;9518:22;9496:2;;;9561:53;9606:7;9595:8;9584:9;9580:24;9561:53;:::i;:::-;9551:63;;;8080:1540;;;;;;;;;;;:::o;9625:1012::-;;;;;;;;;9866:3;9854:9;9845:7;9841:23;9837:33;9834:2;;;9888:6;9880;9873:22;9834:2;9916:30;9936:9;9916:30;:::i;:::-;9906:40;;9997:2;9986:9;9982:18;9969:32;-1:-1:-1;;;;;10061:2:17;10053:6;10050:14;10047:2;;;10082:6;10074;10067:22;10047:2;10110:51;10153:7;10144:6;10133:9;10129:22;10110:51;:::i;:::-;10100:61;;10208:2;10197:9;10193:18;10180:32;10170:42;;10259:2;10248:9;10244:18;10231:32;10221:42;;10310:3;10299:9;10295:19;10282:33;10272:43;;10362:3;10351:9;10347:19;10334:33;10324:43;;10420:3;10409:9;10405:19;10392:33;10376:49;;10450:2;10440:8;10437:16;10434:2;;;10471:6;10463;10456:22;10434:2;;10515:62;10569:7;10558:8;10547:9;10543:24;10515:62;:::i;:::-;9824:813;;;;-1:-1:-1;9824:813:17;;-1:-1:-1;9824:813:17;;;;;;10596:8;-1:-1:-1;;;9824:813:17:o;10642:401::-;;;;10787:2;10775:9;10766:7;10762:23;10758:32;10755:2;;;10808:6;10800;10793:22;10755:2;10836:30;10856:9;10836:30;:::i;:::-;10826:40;;10913:2;10902:9;10898:18;10885:32;10875:42;;10967:2;10956:9;10952:18;10939:32;10980:33;11007:5;10980:33;:::i;:::-;11032:5;11022:15;;;10745:298;;;;;:::o;11048:478::-;;;;;11218:3;11206:9;11197:7;11193:23;11189:33;11186:2;;;11240:6;11232;11225:22;11186:2;11268:30;11288:9;11268:30;:::i;:::-;11258:40;;11345:2;11334:9;11330:18;11317:32;11307:42;;11396:2;11385:9;11381:18;11368:32;11358:42;;11450:2;11439:9;11435:18;11422:32;11463:33;11490:5;11463:33;:::i;:::-;11176:350;;;;-1:-1:-1;11176:350:17;;-1:-1:-1;;11176:350:17:o;11531:1115::-;;;;;;;;;11796:3;11784:9;11775:7;11771:23;11767:33;11764:2;;;11818:6;11810;11803:22;11764:2;11846:30;11866:9;11846:30;:::i;:::-;11836:40;;11923:2;11912:9;11908:18;11895:32;11885:42;;11974:2;11963:9;11959:18;11946:32;11936:42;;12028:2;12017:9;12013:18;12000:32;12041:33;12068:5;12041:33;:::i;:::-;12093:5;-1:-1:-1;12145:3:17;12130:19;;12117:33;;-1:-1:-1;12201:3:17;12186:19;;12173:33;-1:-1:-1;;;;;12255:14:17;;;12252:2;;;12287:6;12279;12272:22;12252:2;12331:60;12383:7;12374:6;12363:9;12359:22;12331:60;:::i;:::-;12410:8;;-1:-1:-1;12305:86:17;-1:-1:-1;12498:3:17;12483:19;;12470:33;;-1:-1:-1;12515:16:17;;;12512:2;;;12549:6;12541;12534:22;12512:2;;12577:63;12632:7;12621:8;12610:9;12606:24;12577:63;:::i;:::-;12567:73;;;11754:892;;;;;;;;;;;:::o;12651:1184::-;;;;;;;;;;12933:3;12921:9;12912:7;12908:23;12904:33;12901:2;;;12955:6;12947;12940:22;12901:2;12983:30;13003:9;12983:30;:::i;:::-;12973:40;;13060:2;13049:9;13045:18;13032:32;13022:42;;13111:2;13100:9;13096:18;13083:32;13073:42;;13165:2;13154:9;13150:18;13137:32;13178:33;13205:5;13178:33;:::i;:::-;13230:5;-1:-1:-1;13282:3:17;13267:19;;13254:33;;-1:-1:-1;13334:3:17;13319:19;;13306:33;;-1:-1:-1;13390:3:17;13375:19;;13362:33;-1:-1:-1;;;;;13444:14:17;;;13441:2;;;13476:6;13468;13461:22;13441:2;13520:60;13572:7;13563:6;13552:9;13548:22;13520:60;:::i;:::-;13599:8;;-1:-1:-1;13494:86:17;-1:-1:-1;13687:3:17;13672:19;;13659:33;;-1:-1:-1;13704:16:17;;;13701:2;;;13738:6;13730;13723:22;13701:2;;13766:63;13821:7;13810:8;13799:9;13795:24;13766:63;:::i;13840:1409::-;;;;;;;;;;;;14159:3;14147:9;14138:7;14134:23;14130:33;14127:2;;;14181:6;14173;14166:22;14127:2;14209:30;14229:9;14209:30;:::i;:::-;14199:40;;14286:2;14275:9;14271:18;14258:32;14248:42;;14337:2;14326:9;14322:18;14309:32;14299:42;;14360:40;14396:2;14385:9;14381:18;14360:40;:::i;:::-;14350:50;;14447:3;14436:9;14432:19;14419:33;14409:43;;14499:3;14488:9;14484:19;14471:33;14461:43;;-1:-1:-1;;;;;14591:2:17;14584:3;14573:9;14569:19;14556:33;14553:41;14550:2;;;14612:6;14604;14597:22;14550:2;14640:88;14720:7;14712:3;14701:9;14697:19;14684:33;14673:9;14669:49;14640:88;:::i;:::-;14630:98;;14778:2;14771:3;14760:9;14756:19;14743:33;14740:41;14737:2;;;14799:6;14791;14784:22;14737:2;14843:87;14922:7;14914:3;14903:9;14899:19;14886:33;14875:9;14871:49;14843:87;:::i;:::-;14949:8;;-1:-1:-1;14976:8:17;-1:-1:-1;15027:3:17;15012:19;;14999:33;14996:41;-1:-1:-1;14993:2:17;;;15055:6;15047;15040:22;14993:2;;15100:87;15179:7;15171:3;15160:9;15156:19;15143:33;15132:9;15128:49;15100:87;:::i;:::-;15206:8;15196:18;;15234:9;15223:20;;;;14117:1132;;;;;;;;;;;;;;:::o;15254:804::-;;;;;15434:9;15425:7;15421:23;15464:3;15460:2;15456:12;15453:2;;;15486:6;15478;15471:22;15453:2;15514:30;15534:9;15514:30;:::i;:::-;15504:40;-1:-1:-1;15591:2:17;15576:18;;15563:32;;-1:-1:-1;15642:2:17;15627:18;;;15614:32;;-1:-1:-1;;;15662:16:17;;15658:25;15655:2;;;15701:6;15693;15686:22;15655:2;;15739;15733:9;15781:2;15773:6;15769:15;15850:6;15838:10;15835:22;-1:-1:-1;;;;;15802:10:17;15799:34;15796:62;15793:2;;;15861:9;15793:2;15888;15881:22;15955:2;15940:18;;15927:32;15912:48;;16021:3;16006:19;;;15993:33;15988:2;15976:15;;15969:58;-1:-1:-1;15401:657:17;;;;-1:-1:-1;15401:657:17;;15919:6;15401:657::o;16063:1196::-;;;;;;;;16303:3;16291:9;16282:7;16278:23;16274:33;16271:2;;;16325:6;16317;16310:22;16271:2;16353:30;16373:9;16353:30;:::i;:::-;16343:40;;16433:2;16422:9;16418:18;16405:32;16446:31;16471:5;16446:31;:::i;:::-;16496:5;-1:-1:-1;16552:2:17;16537:18;;16524:32;-1:-1:-1;;;;;16605:14:17;;;16602:2;;;16637:6;16629;16622:22;16602:2;16681:60;16733:7;16724:6;16713:9;16709:22;16681:60;:::i;:::-;16760:8;;-1:-1:-1;16655:86:17;-1:-1:-1;16848:2:17;16833:18;;16820:32;;-1:-1:-1;16864:16:17;;;16861:2;;;16898:6;16890;16883:22;16861:2;16942:62;16996:7;16985:8;16974:9;16970:24;16942:62;:::i;:::-;17023:8;;-1:-1:-1;16916:88:17;-1:-1:-1;17111:3:17;17096:19;;17083:33;;-1:-1:-1;17128:16:17;;;17125:2;;;17162:6;17154;17147:22;17125:2;;17190:63;17245:7;17234:8;17223:9;17219:24;17190:63;:::i;:::-;17180:73;;;16261:998;;;;;;;;;;:::o;17264:194::-;;17387:2;17375:9;17366:7;17362:23;17358:32;17355:2;;;17408:6;17400;17393:22;17355:2;-1:-1:-1;17436:16:17;;17345:113;-1:-1:-1;17345:113:17:o;17463:327::-;;;17592:2;17580:9;17571:7;17567:23;17563:32;17560:2;;;17613:6;17605;17598:22;17560:2;17654:9;17641:23;17631:33;;17714:2;17703:9;17699:18;17686:32;17727:33;17754:5;17727:33;:::i;17795:1061::-;;;;;;;18008:3;17996:9;17987:7;17983:23;17979:33;17976:2;;;18030:6;18022;18015:22;17976:2;18071:9;18058:23;18048:33;;18131:2;18120:9;18116:18;18103:32;18144:33;18171:5;18144:33;:::i;:::-;18196:5;-1:-1:-1;18253:2:17;18238:18;;18225:32;18266:33;18225:32;18266:33;:::i;:::-;18318:7;-1:-1:-1;18377:2:17;18362:18;;18349:32;18390:33;18349:32;18390:33;:::i;:::-;18442:7;-1:-1:-1;18500:3:17;18485:19;;18472:33;-1:-1:-1;;;;;18554:14:17;;;18551:2;;;18586:6;18578;18571:22;18551:2;18614:51;18657:7;18648:6;18637:9;18633:22;18614:51;:::i;:::-;18604:61;;18718:3;18707:9;18703:19;18690:33;18674:49;;18748:2;18738:8;18735:16;18732:2;;;18769:6;18761;18754:22;18732:2;;18797:53;18842:7;18831:8;18820:9;18816:24;18797:53;:::i;18861:321::-;;;18987:2;18975:9;18966:7;18962:23;18958:32;18955:2;;;19008:6;19000;18993:22;18955:2;19049:9;19036:23;19026:33;;19109:2;19098:9;19094:18;19081:32;19122:30;19146:5;19122:30;:::i;19187:734::-;;;;;;;19375:3;19363:9;19354:7;19350:23;19346:33;19343:2;;;19397:6;19389;19382:22;19343:2;19438:9;19425:23;19415:33;;19498:2;19487:9;19483:18;19470:32;19511:30;19535:5;19511:30;:::i;:::-;19560:5;-1:-1:-1;19612:2:17;19597:18;;19584:32;;-1:-1:-1;19663:2:17;19648:18;;19635:32;;-1:-1:-1;19719:3:17;19704:19;;19691:33;19733:32;19691:33;19733:32;:::i;:::-;19784:7;-1:-1:-1;19843:3:17;19828:19;;19815:33;19857:32;19815:33;19857:32;:::i;:::-;19908:7;19898:17;;;19333:588;;;;;;;;:::o;19926:332::-;;;;20071:2;20059:9;20050:7;20046:23;20042:32;20039:2;;;20092:6;20084;20077:22;20039:2;20133:9;20120:23;20110:33;;20162:39;20197:2;20186:9;20182:18;20162:39;:::i;:::-;20152:49;;20248:2;20237:9;20233:18;20220:32;20210:42;;20029:229;;;;;:::o;20263:407::-;;;;;20424:3;20412:9;20403:7;20399:23;20395:33;20392:2;;;20446:6;20438;20431:22;20392:2;20487:9;20474:23;20464:33;;20516:39;20551:2;20540:9;20536:18;20516:39;:::i;:::-;20506:49;;20602:2;20591:9;20587:18;20574:32;20564:42;;20625:39;20660:2;20649:9;20645:18;20625:39;:::i;:::-;20615:49;;20382:288;;;;;;;:::o;20675:401::-;;;;;20837:3;20825:9;20816:7;20812:23;20808:33;20805:2;;;20859:6;20851;20844:22;20805:2;20900:9;20887:23;20877:33;;20929:39;20964:2;20953:9;20949:18;20929:39;:::i;:::-;20795:281;;20919:49;;-1:-1:-1;;;;21015:2:17;21000:18;;20987:32;;21066:2;21051:18;21038:32;;20795:281::o;21081:258::-;;;21210:2;21198:9;21189:7;21185:23;21181:32;21178:2;;;21231:6;21223;21216:22;21178:2;-1:-1:-1;;21259:23:17;;;21329:2;21314:18;;;21301:32;;-1:-1:-1;21168:171:17:o;21344:255::-;;;21484:2;21472:9;21463:7;21459:23;21455:32;21452:2;;;21505:6;21497;21490:22;21452:2;-1:-1:-1;;21533:16:17;;21589:2;21574:18;;;21568:25;21533:16;;21568:25;;-1:-1:-1;21442:157:17:o;21604:395::-;;;;21750:2;21738:9;21729:7;21725:23;21721:32;21718:2;;;21771:6;21763;21756:22;21718:2;21812:9;21799:23;21789:33;;21869:2;21858:9;21854:18;21841:32;21831:42;;21923:2;21912:9;21908:18;21895:32;21936:33;21963:5;21936:33;:::i;22004:650::-;;;;;;;22218:3;22206:9;22197:7;22193:23;22189:33;22186:2;;;22240:6;22232;22225:22;22186:2;22277:9;22271:16;22296:31;22321:5;22296:31;:::i;:::-;22346:5;22336:15;;;22391:2;22380:9;22376:18;22370:25;22360:35;;22435:2;22424:9;22420:18;22414:25;22404:35;;22484:2;22473:9;22469:18;22463:25;22497:35;22524:7;22497:35;:::i;:::-;22551:7;22541:17;;;22598:3;22587:9;22583:19;22577:26;22567:36;;22643:3;22632:9;22628:19;22622:26;22612:36;;22176:478;;;;;;;;:::o;22659:1261::-;;;;;;;;22924:3;22912:9;22903:7;22899:23;22895:33;22892:2;;;22946:6;22938;22931:22;22892:2;22983:9;22977:16;23002:31;23027:5;23002:31;:::i;:::-;23052:5;23042:15;;;23097:2;23086:9;23082:18;23076:25;23066:35;;23141:2;23130:9;23126:18;23120:25;23110:35;;23185:2;23174:9;23170:18;23164:25;23154:35;;23234:3;23223:9;23219:19;23213:26;23248:35;23275:7;23248:35;:::i;:::-;23302:7;-1:-1:-1;23328:69:17;23389:7;23383:3;23368:19;;23328:69;:::i;:::-;23318:79;;23441:3;23430:9;23426:19;23420:26;-1:-1:-1;;;;;23461:6:17;23458:30;23455:2;;;23506:6;23498;23491:22;23455:2;23534:22;;23587:4;23579:13;;23575:27;-1:-1:-1;23565:2:17;;23621:6;23613;23606:22;23565:2;23655;23649:9;23680:49;23695:33;23725:2;23695:33;:::i;23680:49::-;23752:2;23745:5;23738:17;23792:7;23787:2;23782;23778;23774:11;23770:20;23767:33;23764:2;;;23818:6;23810;23803:22;23764:2;23836:54;23887:2;23882;23875:5;23871:14;23866:2;23862;23858:11;23836:54;:::i;:::-;23909:5;23899:15;;;;;22882:1038;;;;;;;;;;:::o;23925:270::-;;24015:6;24010:3;24003:19;24067:6;24060:5;24053:4;24048:3;24044:14;24031:43;24119:3;24112:4;24103:6;24098:3;24094:16;24090:27;24083:40;24184:4;24177:2;24173:7;24168:2;24160:6;24156:15;24152:29;24147:3;24143:39;24139:50;24132:57;;23993:202;;;;;:::o;24200:259::-;;24281:5;24275:12;24308:6;24303:3;24296:19;24324:63;24380:6;24373:4;24368:3;24364:14;24357:4;24350:5;24346:16;24324:63;:::i;:::-;24441:2;24420:15;-1:-1:-1;;24416:29:17;24407:39;;;;24448:4;24403:50;;24251:208;-1:-1:-1;;24251:208:17:o;24464:153::-;24542:12;;24530:25;;24604:4;24593:16;;;24587:23;24571:14;;24564:47;24520:97::o;24622:375::-;24704:5;24698:12;24693:3;24686:25;24760:4;24753:5;24749:16;24743:23;24736:4;24731:3;24727:14;24720:47;24816:4;24809:5;24805:16;24799:23;24792:4;24787:3;24783:14;24776:47;24872:4;24865:5;24861:16;24855:23;24848:4;24843:3;24839:14;24832:47;24928:4;24921:5;24917:16;24911:23;24904:4;24899:3;24895:14;24888:47;24984:4;24977:5;24973:16;24967:23;24960:4;24955:3;24951:14;24944:47;24676:321;;:::o;25002:311::-;;25091:5;25085:12;25080:3;25073:25;25147:4;25140:5;25136:16;25130:23;25123:4;25118:3;25114:14;25107:47;25200:4;25193:5;25189:16;25183:23;25238:4;25231;25226:3;25222:14;25215:28;25259:48;25301:4;25296:3;25292:14;25278:12;25259:48;:::i;:::-;25252:55;25063:250;-1:-1:-1;;;;25063:250:17:o;25318:273::-;;25501:6;25493;25488:3;25475:33;25527:16;;25552:15;;;25527:16;25465:126;-1:-1:-1;25465:126:17:o;25596:274::-;;25763:6;25757:13;25779:53;25825:6;25820:3;25813:4;25805:6;25801:17;25779:53;:::i;:::-;25848:16;;;;;25733:137;-1:-1:-1;;25733:137:17:o;25875:203::-;-1:-1:-1;;;;;26039:32:17;;;;26021:51;;26009:2;25994:18;;25976:102::o;26083:383::-;-1:-1:-1;;;;;26349:15:17;;;26331:34;;26396:2;26381:18;;26374:34;;;;26444:15;;;26439:2;26424:18;;26417:43;26281:2;26266:18;;26248:218::o;26471:578::-;;26775:1;26771;26766:3;26762:11;26758:19;26750:6;26746:32;26735:9;26728:51;26815:6;26810:2;26799:9;26795:18;26788:34;26870:6;26862;26858:19;26853:2;26842:9;26838:18;26831:47;26914:6;26909:2;26898:9;26894:18;26887:34;26958:3;26952;26941:9;26937:19;26930:32;26979:64;27038:3;27027:9;27023:19;27015:6;27007;26979:64;:::i;:::-;26971:72;26718:331;-1:-1:-1;;;;;;;;26718:331:17:o;27054:375::-;-1:-1:-1;;;;;27312:15:17;;;27294:34;;27364:15;;;;27359:2;27344:18;;27337:43;27411:2;27396:18;;27389:34;;;;27244:2;27229:18;;27211:218::o;27434:274::-;-1:-1:-1;;;;;27626:32:17;;;;27608:51;;27690:2;27675:18;;27668:34;27596:2;27581:18;;27563:145::o;27713:490::-;-1:-1:-1;;;;;27982:15:17;;;27964:34;;28029:2;28014:18;;28007:34;;;28077:15;;28072:2;28057:18;;28050:43;28129:3;28124:2;28109:18;;28102:31;;;27713:490;;28150:47;;28177:19;;28169:6;28150:47;:::i;28208:187::-;28373:14;;28366:22;28348:41;;28336:2;28321:18;;28303:92::o;28400:493::-;28666:14;;28659:22;28641:41;;28713:2;28698:18;;28691:34;;;;28756:2;28741:18;;28734:34;;;;28811:14;28804:22;28799:2;28784:18;;28777:50;28871:14;28864:22;28858:3;28843:19;;28836:51;28628:3;28613:19;;28595:298::o;28898:219::-;;29045:2;29034:9;29027:21;29065:46;29107:2;29096:9;29092:18;29084:6;29065:46;:::i;29569:412::-;29771:2;29753:21;;;29810:2;29790:18;;;29783:30;29849:34;29844:2;29829:18;;29822:62;-1:-1:-1;;;29915:2:17;29900:18;;29893:46;29971:3;29956:19;;29743:238::o;29986:354::-;30188:2;30170:21;;;30227:2;30207:18;;;30200:30;30266:32;30261:2;30246:18;;30239:60;30331:2;30316:18;;30160:180::o;30345:403::-;30547:2;30529:21;;;30586:2;30566:18;;;30559:30;30625:34;30620:2;30605:18;;30598:62;-1:-1:-1;;;30691:2:17;30676:18;;30669:37;30738:3;30723:19;;30519:229::o;30753:354::-;30955:2;30937:21;;;30994:2;30974:18;;;30967:30;31033:32;31028:2;31013:18;;31006:60;31098:2;31083:18;;30927:180::o;31112:351::-;31314:2;31296:21;;;31353:2;31333:18;;;31326:30;31392:29;31387:2;31372:18;;31365:57;31454:2;31439:18;;31286:177::o;31468:349::-;31670:2;31652:21;;;31709:2;31689:18;;;31682:30;31748:27;31743:2;31728:18;;31721:55;31808:2;31793:18;;31642:175::o;31822:354::-;32024:2;32006:21;;;32063:2;32043:18;;;32036:30;32102:32;32097:2;32082:18;;32075:60;32167:2;32152:18;;31996:180::o;32181:353::-;32383:2;32365:21;;;32422:2;32402:18;;;32395:30;32461:31;32456:2;32441:18;;32434:59;32525:2;32510:18;;32355:179::o;32539:355::-;32741:2;32723:21;;;32780:2;32760:18;;;32753:30;32819:33;32814:2;32799:18;;32792:61;32885:2;32870:18;;32713:181::o;32899:352::-;33101:2;33083:21;;;33140:2;33120:18;;;33113:30;33179;33174:2;33159:18;;33152:58;33242:2;33227:18;;33073:178::o;33256:397::-;33458:2;33440:21;;;33497:2;33477:18;;;33470:30;33536:34;33531:2;33516:18;;33509:62;-1:-1:-1;;;33602:2:17;33587:18;;33580:31;33643:3;33628:19;;33430:223::o;33658:411::-;33860:2;33842:21;;;33899:2;33879:18;;;33872:30;33938:34;33933:2;33918:18;;33911:62;-1:-1:-1;;;34004:2:17;33989:18;;33982:45;34059:3;34044:19;;33832:237::o;34074:354::-;34276:2;34258:21;;;34315:2;34295:18;;;34288:30;34354:32;34349:2;34334:18;;34327:60;34419:2;34404:18;;34248:180::o;34433:355::-;34635:2;34617:21;;;34674:2;34654:18;;;34647:30;34713:33;34708:2;34693:18;;34686:61;34779:2;34764:18;;34607:181::o;34793:347::-;34995:2;34977:21;;;35034:2;35014:18;;;35007:30;35073:25;35068:2;35053:18;;35046:53;35131:2;35116:18;;34967:173::o;35145:355::-;35347:2;35329:21;;;35386:2;35366:18;;;35359:30;35425:33;35420:2;35405:18;;35398:61;35491:2;35476:18;;35319:181::o;35505:353::-;35707:2;35689:21;;;35746:2;35726:18;;;35719:30;35785:31;35780:2;35765:18;;35758:59;35849:2;35834:18;;35679:179::o;35863:402::-;36065:2;36047:21;;;36104:2;36084:18;;;36077:30;36143:34;36138:2;36123:18;;36116:62;-1:-1:-1;;;36209:2:17;36194:18;;36187:36;36255:3;36240:19;;36037:228::o;36270:771::-;36659:6;36647:19;;36629:38;;-1:-1:-1;;;;;36703:32:17;;36698:2;36683:18;;36676:60;36270:771;36745:58;36799:2;36784:18;;36776:6;36745:58;:::i;:::-;36840:3;36834;36823:9;36819:19;36812:32;36867:57;36919:3;36908:9;36904:19;36896:6;36867:57;:::i;:::-;36973:9;36965:6;36961:22;36955:3;36944:9;36940:19;36933:51;37001:34;37028:6;37020;37001:34;:::i;37046:733::-;;37371:6;37363;37359:19;37348:9;37341:38;37415:3;37410:2;37399:9;37395:18;37388:31;37442:64;37501:3;37490:9;37486:19;37478:6;37470;37442:64;:::i;:::-;37537:2;37522:18;;37515:34;;;-1:-1:-1;;;;;37585:32:17;;37580:2;37565:18;;37558:60;37649:3;37634:19;;37627:35;;;37699:22;;;37605:3;37678:19;;37671:51;37739:34;37703:6;37758;37739:34;:::i;:::-;37731:42;37331:448;-1:-1:-1;;;;;;;;;;37331:448:17:o;37784:991::-;;38153:3;38195:6;38187;38183:19;38172:9;38165:38;38239:2;38234;38223:9;38219:18;38212:30;38265:46;38307:2;38296:9;38292:18;38284:6;38265:46;:::i;:::-;38342:2;38327:18;;38320:34;;;-1:-1:-1;;;;;38428:15:17;;;38423:2;38408:18;;38401:43;38475:3;38460:19;;38453:35;;;38525:15;;38381:3;38504:19;;38497:44;38578:22;;;38572:3;38557:19;;38550:51;38251:60;-1:-1:-1;38624:34:17;38251:60;38643:6;38624:34;:::i;:::-;38610:48;;38707:9;38699:6;38695:22;38689:3;38678:9;38674:19;38667:51;38735:34;38762:6;38754;38735:34;:::i;:::-;38727:42;38133:642;-1:-1:-1;;;;;;;;;;;38133:642:17:o;38780:706::-;;39095:6;39087;39083:19;39072:9;39065:38;39139:3;39134:2;39123:9;39119:18;39112:31;39166:47;39208:3;39197:9;39193:19;39185:6;39166:47;:::i;:::-;39244:2;39229:18;;39222:34;;;-1:-1:-1;;;;;39292:32:17;;39287:2;39272:18;;39265:60;39356:3;39341:19;;39334:35;;;39406:22;;;39312:3;39385:19;;39378:51;39446:34;39410:6;39465;39446:34;:::i;:::-;39438:42;39055:431;-1:-1:-1;;;;;;;;;39055:431:17:o;39491:259::-;39693:6;39681:19;;;;39663:38;;39732:2;39717:18;;39710:34;39651:2;39636:18;;39618:132::o;39755:436::-;40022:6;40010:19;;;;39992:38;;40061:2;40046:18;;40039:34;;;;-1:-1:-1;;;;;40109:32:17;40104:2;40089:18;;40082:60;40173:2;40158:18;;40151:34;39979:3;39964:19;;39946:245::o;40196:590::-;40513:6;40501:19;;;;40483:38;;40552:2;40537:18;;40530:34;;;;-1:-1:-1;;;;;40600:32:17;;;;40595:2;40580:18;;40573:60;40664:2;40649:18;;40642:34;40707:3;40692:19;;40685:35;40764:14;40757:22;40620:3;40736:19;;40729:51;40470:3;40455:19;;40437:349::o;40791:500::-;41100:6;41088:19;;41070:38;;41139:2;41124:18;;41117:34;;;-1:-1:-1;;;;;41187:32:17;;41182:2;41167:18;;41160:60;41057:3;41042:19;;41229:56;41281:2;41266:18;;41258:6;41229:56;:::i;:::-;41024:267;;;;;;;:::o;41296:500::-;41583:6;41571:19;;;;41553:38;;41622:2;41607:18;;41600:34;;;;-1:-1:-1;;;;;41670:32:17;;;;41665:2;41650:18;;41643:60;41734:2;41719:18;;41712:34;41777:3;41762:19;;41755:35;41540:3;41525:19;;41507:289::o;41801:409::-;42086:6;42074:19;;42056:38;;42125:2;42110:18;;42103:34;;;42043:3;42028:19;;42146:58;42200:2;42185:18;;42177:6;42146:58;:::i;42215:358::-;42423:6;42456:15;;;42438:34;;42503:2;42488:18;;42481:34;;;;42551:15;;;42546:2;42531:18;;42524:43;42401:2;42386:18;;42368:205::o;42578:330::-;42808:6;42796:19;;;;42778:38;;42847:2;42832:18;;42825:34;;;;42890:2;42875:18;;42868:34;42766:2;42751:18;;42733:175::o;42913:594::-;43270:6;43258:19;;43240:38;;43309:2;43294:18;;43287:34;;;43352:2;43337:18;;43330:34;;;-1:-1:-1;;;;;43400:32:17;;43395:2;43380:18;;43373:60;43227:3;43212:19;;43442:59;43496:3;43481:19;;43473:6;43442:59;:::i;43512:1297::-;44124:6;44112:19;;44094:38;;44163:2;44148:18;;44141:34;;;44206:2;44191:18;;44184:34;;;-1:-1:-1;;;;;44254:32:17;;44249:2;44234:18;;44227:60;43512:1297;44082:3;44296:59;44350:3;44335:19;;44327:6;44296:59;:::i;:::-;44364:57;44416:3;44405:9;44401:19;44393:6;44364:57;:::i;:::-;44458:2;44452:3;44441:9;44437:19;44430:31;44484:56;44536:2;44525:9;44521:18;44513:6;44484:56;:::i;:::-;44470:70;;44589:9;44581:6;44577:22;44571:3;44560:9;44556:19;44549:51;44623;44667:6;44659;44651;44623:51;:::i;:::-;44609:65;;44723:9;44715:6;44711:22;44705:3;44694:9;44690:19;44683:51;44751:52;44796:6;44787:7;44779:6;44751:52;:::i;:::-;44743:60;44062:747;-1:-1:-1;;;;;;;;;;;;;;44062:747:17:o;44814:1332::-;45469:6;45457:19;;45439:38;;45508:2;45493:18;;45486:34;;;45551:2;45536:18;;45529:34;;;-1:-1:-1;;;;;45599:32:17;;45594:2;45579:18;;45572:60;44814:1332;45427:3;45641:59;45695:3;45680:19;;45672:6;45641:59;:::i;:::-;45709:57;45761:3;45750:9;45746:19;45738:6;45709:57;:::i;:::-;45803:2;45797:3;45786:9;45782:19;45775:31;45829:56;45881:2;45870:9;45866:18;45858:6;45829:56;:::i;:::-;45815:70;;45934:9;45926:6;45922:22;45916:3;45905:9;45901:19;45894:51;45968;46012:6;46004;45996;45968:51;:::i;:::-;46056:22;;;46050:3;46035:19;;;46028:51;;;;-1:-1:-1;46088:20:17;;46137:2;46125:15;;45407:739;-1:-1:-1;;;;;;;;;45407:739:17:o;46151:1033::-;46656:6;46644:19;;46626:38;;46695:2;46680:18;;46673:34;;;46738:2;46723:18;;46716:34;;;-1:-1:-1;;;;;46786:32:17;;46781:2;46766:18;;46759:60;46151:1033;46614:3;46828:59;46882:3;46867:19;;46859:6;46828:59;:::i;:::-;46924:6;46918:3;46907:9;46903:19;46896:35;46968:2;46962:3;46951:9;46947:19;46940:31;46994:63;47053:2;47042:9;47038:18;47030:6;47022;46994:63;:::i;:::-;46980:77;;47106:9;47098:6;47094:22;47088:3;47077:9;47073:19;47066:51;47134:44;47171:6;47163;47134:44;:::i;:::-;47126:52;46594:590;-1:-1:-1;;;;;;;;;;;;46594:590:17:o;47189:572::-;47504:6;47492:19;;;;47474:38;;47543:2;47528:18;;47521:34;;;;47586:2;47571:18;;47564:34;;;;-1:-1:-1;;;;;47634:32:17;47629:2;47614:18;;47607:60;47698:3;47683:19;;47676:35;47654:3;47727:19;;47720:35;47461:3;47446:19;;47428:333::o;47766:616::-;;48073:6;48065;48061:19;48050:9;48043:38;48117:6;48112:2;48101:9;48097:18;48090:34;48160:6;48155:2;48144:9;48140:18;48133:34;48203:3;48198:2;48187:9;48183:18;48176:31;48224:64;48283:3;48272:9;48268:19;48260:6;48252;48224:64;:::i;:::-;48319:3;48304:19;;48297:35;;;;-1:-1:-1;48363:3:17;48348:19;48341:35;48216:72;48033:349;-1:-1:-1;;;;;48033:349:17:o;48387:802::-;;48740:6;48732;48728:19;48717:9;48710:38;48796:4;48788:6;48784:17;48779:2;48768:9;48764:18;48757:45;48838:3;48833:2;48822:9;48818:18;48811:31;48865:64;48924:3;48913:9;48909:19;48901:6;48893;48865:64;:::i;:::-;48977:9;48969:6;48965:22;48960:2;48949:9;48945:18;48938:50;49011:51;49055:6;49047;49039;49011:51;:::i;:::-;48997:65;;49111:9;49103:6;49099:22;49093:3;49082:9;49078:19;49071:51;49139:44;49176:6;49168;49139:44;:::i;49194:177::-;49340:25;;;49328:2;49313:18;;49295:76::o;49376:713::-;49659:25;;;-1:-1:-1;;;;;49720:32:17;;49715:2;49700:18;;49693:60;49801:4;49789:17;;;49784:2;49769:18;;49762:45;49843:17;;49838:2;49823:18;;49816:45;49898:3;49892;49877:19;;49870:32;;;49376:713;;49925:47;;49952:19;;49944:6;49925:47;:::i;:::-;50021:9;50013:6;50009:22;50003:3;49992:9;49988:19;49981:51;50049:34;50076:6;50068;50049:34;:::i;50094:248::-;50268:25;;;50324:2;50309:18;;50302:34;50256:2;50241:18;;50223:119::o;50347:452::-;;50584:4;50576:6;50572:17;50561:9;50554:36;50638:6;50630;50626:19;50621:2;50610:9;50606:18;50599:47;50682:3;50677:2;50666:9;50662:18;50655:31;50703:47;50745:3;50734:9;50730:19;50722:6;50703:47;:::i;:::-;50695:55;;50786:6;50781:2;50770:9;50766:18;50759:34;50544:255;;;;;;;:::o;50804:568::-;51117:4;51105:17;;;;51087:36;;51154:2;51139:18;;51132:34;;;;51197:2;51182:18;;51175:34;;;;-1:-1:-1;;;;;51245:32:17;51240:2;51225:18;;51218:60;51309:3;51294:19;;51287:35;51265:3;51338:19;;51331:35;51074:3;51059:19;;51041:331::o;51377:629::-;;51688:4;51680:6;51676:17;51665:9;51658:36;51730:6;51725:2;51714:9;51710:18;51703:34;51773:6;51768:2;51757:9;51753:18;51746:34;51828:4;51820:6;51816:17;51811:2;51800:9;51796:18;51789:45;51871:6;51865:3;51854:9;51850:19;51843:35;51915:3;51909;51898:9;51894:19;51887:32;51936:64;51995:3;51984:9;51980:19;51972:6;51964;51936:64;:::i;52011:775::-;52406:4;52394:17;;52376:36;;52443:2;52428:18;;52421:34;;;52486:2;52471:18;;52464:34;;;52529:2;52514:18;;52507:34;;;-1:-1:-1;;;;;52578:32:17;;52572:3;52557:19;;52550:61;52011:775;52364:3;52620:57;52598:3;52657:19;;52649:6;52620:57;:::i;:::-;52714:2;52708:3;52697:9;52693:19;52686:31;52734:46;52776:2;52765:9;52761:18;52753:6;52734:46;:::i;52791:612::-;;53096:4;53088:6;53084:17;53073:9;53066:36;53138:6;53133:2;53122:9;53118:18;53111:34;53181:6;53176:2;53165:9;53161:18;53154:34;53224:6;53219:2;53208:9;53204:18;53197:34;53268:6;53262:3;53251:9;53247:19;53240:35;53312:3;53306;53295:9;53291:19;53284:32;53333:64;53392:3;53381:9;53377:19;53369:6;53361;53333:64;:::i;53408:242::-;53478:2;53472:9;53508:17;;;-1:-1:-1;;;;;53540:34:17;;53576:22;;;53537:62;53534:2;;;53602:9;53534:2;53629;53622:22;53452:198;;-1:-1:-1;53452:198:17:o;53655:181::-;;-1:-1:-1;;;;;53730:6:17;53727:30;53724:2;;;53760:9;53724:2;-1:-1:-1;53819:2:17;53796:17;-1:-1:-1;;53792:31:17;53825:4;53788:42;;53714:122::o;53841:258::-;53913:1;53923:113;53937:6;53934:1;53931:13;53923:113;;;54013:11;;;54007:18;53994:11;;;53987:39;53959:2;53952:10;53923:113;;;54054:6;54051:1;54048:13;54045:2;;;54089:1;54080:6;54075:3;54071:16;54064:27;54045:2;;53894:205;;;:::o;54104:133::-;-1:-1:-1;;;;;54181:31:17;;54171:42;;54161:2;;54227:1;54224;54217:12;54161:2;54151:86;:::o;54242:120::-;54330:5;54323:13;54316:21;54309:5;54306:32;54296:2;;54352:1;54349;54342:12;54367:116;54453:4;54446:5;54442:16;54435:5;54432:27;54422:2;;54473:1;54470;54463:12
Swarm Source
ipfs://d86582ffb411c85869be51806318cb203c2835996c58fcb8521dd7b53c5baece
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.