Contract Overview
Balance:
0 MATIC
My Name Tag:
Not Available
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Registry
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity)
/** *Submitted for verification at polygonscan.com on 2022-07-14 */ // File: Utils.sol pragma solidity 0.8.9; contract Utils { function getChainID() internal view returns (uint256) { uint256 chainID; assembly { chainID := chainid() } return chainID; } function max(uint a, uint b) internal pure returns (uint) { return a > b ? a : b; } function min(uint a, uint b) internal pure returns (uint) { return a < b ? a : b; } function round(uint a, uint m) internal pure returns (uint ) { return ((a + m - 1) / m) * m; } } // File: @openzeppelin/contracts/security/ReentrancyGuard.sol // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract 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 making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } // File: Ownable.sol pragma solidity 0.8.9; contract Ownable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); function owner() public view returns (address) { return _owner; } modifier onlyOwner() { require(_owner == msg.sender || _owner == address(0x0), "Ownable: caller is not the 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; } } // File: interfaces/IHermesContract.sol pragma solidity 0.8.9; interface IHermesContract { enum Status { Active, Paused, Punishment, Closed } function initialize(address _token, address _operator, uint16 _hermesFee, uint256 _minStake, uint256 _maxStake, address payable _routerAddress) external; function openChannel(address _party, uint256 _amountToLend) external; function getOperator() external view returns (address); function getStake() external view returns (uint256); function getStatus() external view returns (Status); } // File: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); } // File: interfaces/IERC20Token.sol pragma solidity 0.8.9; abstract contract IERC20Token is IERC20 { function upgrade(uint256 value) public virtual; } // File: FundsRecovery.sol pragma solidity 0.8.9; contract FundsRecovery is Ownable, ReentrancyGuard { address payable internal fundsDestination; IERC20Token public token; event DestinationChanged(address indexed previousDestination, address indexed newDestination); /** * Setting new destination of funds recovery. */ function setFundsDestination(address payable _newDestination) public virtual onlyOwner { require(_newDestination != address(0)); emit DestinationChanged(fundsDestination, _newDestination); fundsDestination = _newDestination; } /** * Getting funds destination address. */ function getFundsDestination() public view returns (address) { return fundsDestination; } /** * Possibility to recover funds in case they were sent to this address before smart contract deployment */ function claimNativeCoin() public nonReentrant { require(fundsDestination != address(0)); fundsDestination.transfer(address(this).balance); } /** Transfers selected tokens into owner address. */ function claimTokens(address _token) public nonReentrant { require(fundsDestination != address(0)); require(_token != address(token), "native token funds can't be recovered"); uint256 _amount = IERC20Token(_token).balanceOf(address(this)); IERC20Token(_token).transfer(fundsDestination, _amount); } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } // File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else if (signature.length == 64) { bytes32 r; bytes32 vs; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) vs := mload(add(signature, 0x40)) } return tryRecover(hash, r, vs); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } } // File: Registry.sol pragma solidity 0.8.9; interface Channel { function initialize(address _token, address _dex, address _identityHash, address _hermesId, uint256 _fee) external; } contract Registry is FundsRecovery, Utils { using ECDSA for bytes32; uint256 public lastNonce; address payable public dex; // Any uniswap v2 compatible DEX router address uint256 public minimalHermesStake; Registry public parentRegistry; // Contract could have parent registry if Registry SC was already upgraded struct Implementation { address channelImplAddress; address hermesImplAddress; } Implementation[] internal implementations; struct Hermes { address operator; // hermes operator who will sign promises uint256 implVer; // version of hermes implementation smart contract function() external view returns(uint256) stake; bytes url; // hermes service URL } mapping(address => Hermes) private hermeses; mapping(address => address) private identities; // key: identity, value: beneficiary wallet address event RegisteredIdentity(address indexed identity, address beneficiary); event RegisteredHermes(address indexed hermesId, address hermesOperator, bytes ur); event HermesURLUpdated(address indexed hermesId, bytes newURL); event ConsumerChannelCreated(address indexed identity, address indexed hermesId, address channelAddress); event BeneficiaryChanged(address indexed identity, address newBeneficiary); event MinimalHermesStakeChanged(uint256 newMinimalStake); // Reject any ethers sent to this smart-contract receive() external payable { revert("Registry: Rejecting tx with ethers sent"); } // We're using `initialize` instead of `constructor` to ensure easy way to deploy Registry into // deterministic address on any EVM compatible chain. Registry should be first be deployed using // `deployRegistry` scripts and then initialized with wanted token and implementations. function initialize(address _tokenAddress, address payable _dexAddress, uint256 _minimalHermesStake, address _channelImplementation, address _hermesImplementation, address payable _parentRegistry) public onlyOwner { require(!isInitialized(), "Registry: is already initialized"); minimalHermesStake = _minimalHermesStake; require(_tokenAddress != address(0), "Registry: token smart contract can't be deployed into 0x0 address"); token = IERC20Token(_tokenAddress); require(_dexAddress != address(0), "Registry: dex can't be deployed into 0x0 address"); dex = _dexAddress; // Set initial channel implementations setImplementations(_channelImplementation, _hermesImplementation); // We set initial owner to be sure transferOwnership(msg.sender); // Set parent registry, if `0x0` then this is root registry parentRegistry = Registry(_parentRegistry); } function isInitialized() public view returns (bool) { return address(token) != address(0); } // Register provider and open his channel with given hermes // _stakeAmount - it's amount of tokens staked into hermes to guarantee incomming channel's balance. // _beneficiary - payout address during settlements in hermes channel, if provided 0x0 then will be set to consumer channel address. function registerIdentity(address _hermesId, uint256 _stakeAmount, uint256 _transactorFee, address _beneficiary, bytes memory _signature) public { require(isActiveHermes(_hermesId), "Registry: provided hermes have to be active"); // Check if given signature is valid address _identity = keccak256(abi.encodePacked(getChainID(), address(this), _hermesId, _stakeAmount, _transactorFee, _beneficiary)).recover(_signature); require(_identity != address(0), "Registry: wrong identity signature"); // Tokens amount to get from channel to cover tx fee and provider's stake uint256 _totalFee = _stakeAmount + _transactorFee; require(_totalFee <= token.balanceOf(getChannelAddress(_identity, _hermesId)), "Registry: not enough funds in channel to cover fees"); // Open consumer channel _openChannel(_identity, _hermesId, _beneficiary, _totalFee); // If stake is provided we additionally are opening channel with hermes (a.k.a provider channel) if (_stakeAmount > 0) { IHermesContract(_hermesId).openChannel(_identity, _stakeAmount); } // Pay fee for transaction maker if (_transactorFee > 0) { token.transfer(msg.sender, _transactorFee); } } // Deploys consumer channel and sets beneficiary as newly created channel address function openConsumerChannel(address _hermesId, uint256 _transactorFee, bytes memory _signature) public { require(isActiveHermes(_hermesId), "Registry: provided hermes have to be active"); // Check if given signature is valid address _identity = keccak256(abi.encodePacked(getChainID(), address(this), _hermesId, _transactorFee)).recover(_signature); require(_identity != address(0), "Registry: wrong channel openinig signature"); require(_transactorFee <= token.balanceOf(getChannelAddress(_identity, _hermesId)), "Registry: not enough funds in channel to cover fees"); _openChannel(_identity, _hermesId, address(0), _transactorFee); } // Allows to securely deploy channel's smart contract without consumer signature function openConsumerChannel(address _identity, address _hermesId) public { require(isActiveHermes(_hermesId), "Registry: provided hermes have to be active"); require(!isChannelOpened(_identity, _hermesId), "Registry: such consumer channel is already opened"); _openChannel(_identity, _hermesId, address(0), 0); } // Deploy payment channel for given consumer identity // We're using minimal proxy (EIP1167) to save on gas cost and blockchain space. function _openChannel(address _identity, address _hermesId, address _beneficiary, uint256 _fee) internal returns (address) { bytes32 _salt = keccak256(abi.encodePacked(_identity, _hermesId)); bytes memory _code = getProxyCode(getChannelImplementation(hermeses[_hermesId].implVer)); Channel _channel = Channel(deployMiniProxy(uint256(_salt), _code)); _channel.initialize(address(token), dex, _identity, _hermesId, _fee); emit ConsumerChannelCreated(_identity, _hermesId, address(_channel)); // If beneficiary was not provided, then we're going to use consumer channel for that if (_beneficiary == address(0)) { _beneficiary = address(_channel); } // Mark identity as registered (only during first channel opening) if (!isRegistered(_identity)) { identities[_identity] = _beneficiary; emit RegisteredIdentity(_identity, _beneficiary); } return address(_channel); } function registerHermes(address _hermesOperator, uint256 _hermesStake, uint16 _hermesFee, uint256 _minChannelStake, uint256 _maxChannelStake, bytes memory _url) public { require(isInitialized(), "Registry: only initialized registry can register hermeses"); require(_hermesOperator != address(0), "Registry: hermes operator can't be zero address"); require(_hermesStake >= minimalHermesStake, "Registry: hermes have to stake at least minimal stake amount"); address _hermesId = getHermesAddress(_hermesOperator); require(!isHermes(_hermesId), "Registry: hermes already registered"); // Deploy hermes contract (mini proxy which is pointing to implementation) IHermesContract _hermes = IHermesContract(deployMiniProxy(uint256(uint160(_hermesOperator)), getProxyCode(getHermesImplementation()))); // Transfer stake into hermes smart contract token.transferFrom(msg.sender, address(_hermes), _hermesStake); // Initialise hermes _hermes.initialize(address(token), _hermesOperator, _hermesFee, _minChannelStake, _maxChannelStake, dex); // Save info about newly created hermes hermeses[_hermesId] = Hermes(_hermesOperator, getLastImplVer(), _hermes.getStake, _url); // Approve hermes contract to `transferFrom` registry (used during hermes channel openings) token.approve(_hermesId, type(uint256).max); emit RegisteredHermes(_hermesId, _hermesOperator, _url); } function getChannelAddress(address _identity, address _hermesId) public view returns (address) { bytes32 _code = keccak256(getProxyCode(getChannelImplementation(hermeses[_hermesId].implVer))); bytes32 _salt = keccak256(abi.encodePacked(_identity, _hermesId)); return getCreate2Address(_salt, _code); } function getHermes(address _hermesId) public view returns (Hermes memory) { return isHermes(_hermesId) || !hasParentRegistry() ? hermeses[_hermesId] : parentRegistry.getHermes(_hermesId); } function getHermesAddress(address _hermesOperator) public view returns (address) { bytes32 _code = keccak256(getProxyCode(getHermesImplementation())); return getCreate2Address(bytes32(uint256(uint160(_hermesOperator))), _code); } function getHermesAddress(address _hermesOperator, uint256 _implVer) public view returns (address) { bytes32 _code = keccak256(getProxyCode(getHermesImplementation(_implVer))); return getCreate2Address(bytes32(uint256(uint160(_hermesOperator))), _code); } function getHermesURL(address _hermesId) public view returns (bytes memory) { return hermeses[_hermesId].url; } function updateHermesURL(address _hermesId, bytes memory _url, bytes memory _signature) public { require(isActiveHermes(_hermesId), "Registry: provided hermes has to be active"); // Check if given signature is valid address _operator = keccak256(abi.encodePacked(address(this), _hermesId, _url, lastNonce++)).recover(_signature); require(_operator == hermeses[_hermesId].operator, "wrong signature"); // Update URL hermeses[_hermesId].url = _url; emit HermesURLUpdated(_hermesId, _url); } // ------------ UTILS ------------ function getCreate2Address(bytes32 _salt, bytes32 _code) internal view returns (address) { return address(uint160(uint256(keccak256(abi.encodePacked( bytes1(0xff), address(this), bytes32(_salt), bytes32(_code) ))))); } function getProxyCode(address _implementation) public pure returns (bytes memory) { // `_code` is EIP 1167 - Minimal Proxy Contract // more information: https://eips.ethereum.org/EIPS/eip-1167 bytes memory _code = hex"3d602d80600a3d3981f3363d3d373d3d3d363d73bebebebebebebebebebebebebebebebebebebebe5af43d82803e903d91602b57fd5bf3"; bytes20 _targetBytes = bytes20(_implementation); for (uint8 i = 0; i < 20; i++) { _code[20 + i] = _targetBytes[i]; } return _code; } function deployMiniProxy(uint256 _salt, bytes memory _code) internal returns (address payable) { address payable _addr; assembly { _addr := create2(0, add(_code, 0x20), mload(_code), _salt) if iszero(extcodesize(_addr)) { revert(0, 0) } } return _addr; } function getBeneficiary(address _identity) public view returns (address) { if (hasParentRegistry()) return parentRegistry.getBeneficiary(_identity); return identities[_identity]; } function setBeneficiary(address _identity, address _newBeneficiary, bytes memory _signature) public { require(_newBeneficiary != address(0), "Registry: beneficiary can't be zero address"); // Always set beneficiary into root registry if (hasParentRegistry()) { parentRegistry.setBeneficiary(_identity, _newBeneficiary, _signature); } else { lastNonce = lastNonce + 1; // In signatures we should always use root registry (for backward compatibility) address _rootRegistry = hasParentRegistry() ? address(parentRegistry) : address(this); address _signer = keccak256(abi.encodePacked(getChainID(), _rootRegistry, _identity, _newBeneficiary, lastNonce)).recover(_signature); require(_signer == _identity, "Registry: have to be signed by identity owner"); identities[_identity] = _newBeneficiary; emit BeneficiaryChanged(_identity, _newBeneficiary); } } function setMinimalHermesStake(uint256 _newMinimalStake) public onlyOwner { require(isInitialized(), "Registry: only initialized registry can set new minimal hermes stake"); minimalHermesStake = _newMinimalStake; emit MinimalHermesStakeChanged(_newMinimalStake); } // -------- UTILS TO WORK WITH CHANNEL AND HERMES IMPLEMENTATIONS --------- function getChannelImplementation() public view returns (address) { return implementations[getLastImplVer()].channelImplAddress; } function getChannelImplementation(uint256 _implVer) public view returns (address) { return implementations[_implVer].channelImplAddress; } function getHermesImplementation() public view returns (address) { return implementations[getLastImplVer()].hermesImplAddress; } function getHermesImplementation(uint256 _implVer) public view returns (address) { return implementations[_implVer].hermesImplAddress; } function setImplementations(address _newChannelImplAddress, address _newHermesImplAddress) public onlyOwner { require(isInitialized(), "Registry: only initialized registry can set new implementations"); require(isSmartContract(_newChannelImplAddress) && isSmartContract(_newHermesImplAddress), "Registry: implementations have to be smart contracts"); implementations.push(Implementation(_newChannelImplAddress, _newHermesImplAddress)); } // Version of latest hermes and channel implementations function getLastImplVer() public view returns (uint256) { return implementations.length-1; } // ------------------------------------------------------------------------ function isSmartContract(address _addr) internal view returns (bool) { uint _codeLength; assembly { _codeLength := extcodesize(_addr) } return _codeLength != 0; } // If `parentRegistry` is not set, this is root registry and should return false function hasParentRegistry() public view returns (bool) { return address(parentRegistry) != address(0); } function isRegistered(address _identity) public view returns (bool) { if (hasParentRegistry()) return parentRegistry.isRegistered(_identity); // If we know its beneficiary address it is registered identity return identities[_identity] != address(0); } function isHermes(address _hermesId) public view returns (bool) { // To check if it actually properly created hermes address, we need to check if he has operator // and if with that operator we'll get proper hermes address which has code deployed there. address _hermesOperator = hermeses[_hermesId].operator; uint256 _implVer = hermeses[_hermesId].implVer; address _addr = getHermesAddress(_hermesOperator, _implVer); if (_addr != _hermesId) return false; // hermesId should be same as generated address return isSmartContract(_addr) || parentRegistry.isHermes(_hermesId); } function isActiveHermes(address _hermesId) internal view returns (bool) { // First we have to ensure that given address is registered hermes and only then check its status require(isHermes(_hermesId), "Registry: hermes have to be registered"); IHermesContract.Status status = IHermesContract(_hermesId).getStatus(); return status == IHermesContract.Status.Active; } function isChannelOpened(address _identity, address _hermesId) public view returns (bool) { return isSmartContract(getChannelAddress(_identity, _hermesId)) || isSmartContract(parentRegistry.getChannelAddress(_identity, _hermesId)); } function transferCollectedFeeTo(address _beneficiary) public onlyOwner{ uint256 _collectedFee = token.balanceOf(address(this)); require(_collectedFee > 0, "collected fee cannot be less than zero"); token.transfer(_beneficiary, _collectedFee); } }
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"identity","type":"address"},{"indexed":false,"internalType":"address","name":"newBeneficiary","type":"address"}],"name":"BeneficiaryChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"identity","type":"address"},{"indexed":true,"internalType":"address","name":"hermesId","type":"address"},{"indexed":false,"internalType":"address","name":"channelAddress","type":"address"}],"name":"ConsumerChannelCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousDestination","type":"address"},{"indexed":true,"internalType":"address","name":"newDestination","type":"address"}],"name":"DestinationChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"hermesId","type":"address"},{"indexed":false,"internalType":"bytes","name":"newURL","type":"bytes"}],"name":"HermesURLUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMinimalStake","type":"uint256"}],"name":"MinimalHermesStakeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"hermesId","type":"address"},{"indexed":false,"internalType":"address","name":"hermesOperator","type":"address"},{"indexed":false,"internalType":"bytes","name":"ur","type":"bytes"}],"name":"RegisteredHermes","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"identity","type":"address"},{"indexed":false,"internalType":"address","name":"beneficiary","type":"address"}],"name":"RegisteredIdentity","type":"event"},{"inputs":[],"name":"claimNativeCoin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"claimTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dex","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_identity","type":"address"}],"name":"getBeneficiary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_identity","type":"address"},{"internalType":"address","name":"_hermesId","type":"address"}],"name":"getChannelAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_implVer","type":"uint256"}],"name":"getChannelImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChannelImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFundsDestination","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_hermesId","type":"address"}],"name":"getHermes","outputs":[{"components":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"implVer","type":"uint256"},{"internalType":"function () view external returns (uint256)","name":"stake","type":"function"},{"internalType":"bytes","name":"url","type":"bytes"}],"internalType":"struct Registry.Hermes","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_hermesOperator","type":"address"},{"internalType":"uint256","name":"_implVer","type":"uint256"}],"name":"getHermesAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_hermesOperator","type":"address"}],"name":"getHermesAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_implVer","type":"uint256"}],"name":"getHermesImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getHermesImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_hermesId","type":"address"}],"name":"getHermesURL","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastImplVer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_implementation","type":"address"}],"name":"getProxyCode","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"hasParentRegistry","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"address payable","name":"_dexAddress","type":"address"},{"internalType":"uint256","name":"_minimalHermesStake","type":"uint256"},{"internalType":"address","name":"_channelImplementation","type":"address"},{"internalType":"address","name":"_hermesImplementation","type":"address"},{"internalType":"address payable","name":"_parentRegistry","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_identity","type":"address"},{"internalType":"address","name":"_hermesId","type":"address"}],"name":"isChannelOpened","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_hermesId","type":"address"}],"name":"isHermes","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_identity","type":"address"}],"name":"isRegistered","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimalHermesStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_hermesId","type":"address"},{"internalType":"uint256","name":"_transactorFee","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"openConsumerChannel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_identity","type":"address"},{"internalType":"address","name":"_hermesId","type":"address"}],"name":"openConsumerChannel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"parentRegistry","outputs":[{"internalType":"contract Registry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_hermesOperator","type":"address"},{"internalType":"uint256","name":"_hermesStake","type":"uint256"},{"internalType":"uint16","name":"_hermesFee","type":"uint16"},{"internalType":"uint256","name":"_minChannelStake","type":"uint256"},{"internalType":"uint256","name":"_maxChannelStake","type":"uint256"},{"internalType":"bytes","name":"_url","type":"bytes"}],"name":"registerHermes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_hermesId","type":"address"},{"internalType":"uint256","name":"_stakeAmount","type":"uint256"},{"internalType":"uint256","name":"_transactorFee","type":"uint256"},{"internalType":"address","name":"_beneficiary","type":"address"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"registerIdentity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_identity","type":"address"},{"internalType":"address","name":"_newBeneficiary","type":"address"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"setBeneficiary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_newDestination","type":"address"}],"name":"setFundsDestination","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newChannelImplAddress","type":"address"},{"internalType":"address","name":"_newHermesImplAddress","type":"address"}],"name":"setImplementations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMinimalStake","type":"uint256"}],"name":"setMinimalHermesStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20Token","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_beneficiary","type":"address"}],"name":"transferCollectedFeeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_hermesId","type":"address"},{"internalType":"bytes","name":"_url","type":"bytes"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"updateHermesURL","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405234801561001057600080fd5b5060018055614b61806100246000396000f3fe6080604052600436106102895760003560e01c8063acc831d011610153578063d16f38c8116100cb578063e617aaac1161007f578063f58c5b6e11610064578063f58c5b6e146107e3578063fc0c546a1461080e578063ff9935cb1461083b57600080fd5b8063e617aaac146107a3578063f2fde38b146107c357600080fd5b8063df8de3e7116100b0578063df8de3e714610736578063e0b6c32314610756578063e32525371461078357600080fd5b8063d16f38c8146106e9578063d5929fe31461071657600080fd5b8063c957543b11610122578063cdd596e011610107578063cdd596e014610689578063cf10c969146106a9578063d0171d79146106c957600080fd5b8063c957543b1461063c578063c9b84d4d1461065c57600080fd5b8063acc831d0146105bc578063add10dda146105dc578063bf1eb88a146105fc578063c3c5a5471461061c57600080fd5b80635f54be4b1161020157806385bff341116101b55780638da5cb5b1161019a5780638da5cb5b1461054f5780639936a87b1461057a578063ab8672131461058f57600080fd5b806385bff3411461050f5780638cfef5471461052f57600080fd5b806366cf5875116101e657806366cf5875146104b7578063692058c2146104cd5780637c671a21146104fa57600080fd5b80635f54be4b1461048d5780636332b080146104a257600080fd5b806341ca71ab116102585780634b6bd6be1161023d5780634b6bd6be14610429578063505a1b311461044957806352631ab41461046957600080fd5b806341ca71ab146103c45780634787d09c1461040957600080fd5b806304614e0b146103205780631de9db4014610342578063238e130a14610377578063392e53cd1461039757600080fd5b3661031b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f52656769737472793a2052656a656374696e672074782077697468206574686560448201527f72732073656e740000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b600080fd5b34801561032c57600080fd5b5061034061033b36600461430a565b61085b565b005b34801561034e57600080fd5b5061036261035d366004614363565b610b78565b60405190151581526020015b60405180910390f35b34801561038357600080fd5b5061034061039236600461439c565b610c47565b3480156103a357600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff161515610362565b3480156103d057600080fd5b506103e46103df3660046143b9565b610d97565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161036e565b34801561041557600080fd5b50610340610424366004614363565b610dd9565b34801561043557600080fd5b506103e46104443660046143d2565b610f17565b34801561045557600080fd5b506103e461046436600461439c565b610fcc565b34801561047557600080fd5b5061047f60045481565b60405190815260200161036e565b34801561049957600080fd5b506103406110c9565b3480156104ae57600080fd5b5061047f6111aa565b3480156104c357600080fd5b5061047f60065481565b3480156104d957600080fd5b506005546103e49073ffffffffffffffffffffffffffffffffffffffff1681565b34801561050657600080fd5b506103e46111c1565b34801561051b57600080fd5b5061034061052a366004614363565b611209565b34801561053b57600080fd5b506103e461054a3660046143b9565b6114b3565b34801561055b57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166103e4565b34801561058657600080fd5b506103e46114f8565b34801561059b57600080fd5b506105af6105aa36600461439c565b611543565b60405161036e9190614478565b3480156105c857600080fd5b506103e46105d736600461439c565b6115f8565b3480156105e857600080fd5b506103406105f736600461448b565b6116a8565b34801561060857600080fd5b506105af61061736600461439c565b611897565b34801561062857600080fd5b5061036261063736600461439c565b611953565b34801561064857600080fd5b506103406106573660046143b9565b611a4c565b34801561066857600080fd5b506007546103e49073ffffffffffffffffffffffffffffffffffffffff1681565b34801561069557600080fd5b506103626106a436600461439c565b611bf5565b3480156106b557600080fd5b506103406106c43660046144f7565b611d28565b3480156106d557600080fd5b506103406106e436600461456d565b612188565b3480156106f557600080fd5b5060075473ffffffffffffffffffffffffffffffffffffffff161515610362565b34801561072257600080fd5b506103406107313660046145b9565b6124dd565b34801561074257600080fd5b5061034061075136600461439c565b612b34565b34801561076257600080fd5b5061077661077136600461439c565b612dca565b60405161036e919061463e565b34801561078f57600080fd5b5061034061079e36600461439c565b612ff9565b3480156107af57600080fd5b506103e46107be366004614363565b61327b565b3480156107cf57600080fd5b506103406107de36600461439c565b6133be565b3480156107ef57600080fd5b5060025473ffffffffffffffffffffffffffffffffffffffff166103e4565b34801561081a57600080fd5b506003546103e49073ffffffffffffffffffffffffffffffffffffffff1681565b34801561084757600080fd5b506103406108563660046146af565b613590565b610864836138f2565b6108f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f52656769737472793a2070726f7669646564206865726d65732068617665207460448201527f6f206265206163746976650000000000000000000000000000000000000000006064820152608401610312565b600061096c82466040805160208101929092527fffffffffffffffffffffffffffffffffffffffff00000000000000000000000030606090811b8216928401929092529088901b166054820152606881018690526088015b60405160208183030381529060405280519060200120613a2790919063ffffffff16565b905073ffffffffffffffffffffffffffffffffffffffff8116610a11576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f52656769737472793a2077726f6e67206368616e6e656c206f70656e696e696760448201527f207369676e6174757265000000000000000000000000000000000000000000006064820152608401610312565b60035473ffffffffffffffffffffffffffffffffffffffff166370a08231610a39838761327b565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240160206040518083038186803b158015610a9d57600080fd5b505afa158015610ab1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad59190614728565b831115610b64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f52656769737472793a206e6f7420656e6f7567682066756e647320696e20636860448201527f616e6e656c20746f20636f7665722066656573000000000000000000000000006064820152608401610312565b610b718185600086613a4b565b5050505050565b6000610b8d610b87848461327b565b3b151590565b80610c4057506007546040517fe617aaac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301528481166024830152610c4092169063e617aaac9060440160206040518083038186803b158015610c0857600080fd5b505afa158015610c1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b879190614741565b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331480610c83575060005473ffffffffffffffffffffffffffffffffffffffff16155b610ce9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610312565b73ffffffffffffffffffffffffffffffffffffffff8116610d0957600080fd5b60025460405173ffffffffffffffffffffffffffffffffffffffff8084169216907fe1a66d77649cf0a57b9937073549f30f1c82bb865aaf066d2f299e37a62c6aad90600090a3600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600060088281548110610dac57610dac61475e565b600091825260209091206002909102015473ffffffffffffffffffffffffffffffffffffffff1692915050565b610de2816138f2565b610e6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f52656769737472793a2070726f7669646564206865726d65732068617665207460448201527f6f206265206163746976650000000000000000000000000000000000000000006064820152608401610312565b610e788282610b78565b15610f05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f52656769737472793a207375636820636f6e73756d6572206368616e6e656c2060448201527f697320616c7265616479206f70656e65640000000000000000000000000000006064820152608401610312565b610f128282600080613a4b565b505050565b600080610f266105aa846114b3565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b16602182015273ffffffffffffffffffffffffffffffffffffffff88166035820152605580820184905282518083039091018152607590910190915280519201919091209091505b949350505050565b6000610fef60075473ffffffffffffffffffffffffffffffffffffffff16151590565b1561109d576007546040517f505a1b3100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301529091169063505a1b319060240160206040518083038186803b15801561105f57600080fd5b505afa158015611073573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110979190614741565b92915050565b5073ffffffffffffffffffffffffffffffffffffffff9081166000908152600a60205260409020541690565b60026001541415611136576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610312565b600260018190555473ffffffffffffffffffffffffffffffffffffffff1661115d57600080fd5b60025460405173ffffffffffffffffffffffffffffffffffffffff909116904780156108fc02916000818181858888f193505050501580156111a3573d6000803e3d6000fd5b5060018055565b6008546000906111bc906001906147bc565b905090565b600060086111cd6111aa565b815481106111dd576111dd61475e565b600091825260209091206002909102015473ffffffffffffffffffffffffffffffffffffffff16919050565b60005473ffffffffffffffffffffffffffffffffffffffff16331480611245575060005473ffffffffffffffffffffffffffffffffffffffff16155b6112ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610312565b60035473ffffffffffffffffffffffffffffffffffffffff16611350576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f52656769737472793a206f6e6c7920696e697469616c697a656420726567697360448201527f7472792063616e20736574206e657720696d706c656d656e746174696f6e73006064820152608401610312565b813b151580156113605750803b15155b6113ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f52656769737472793a20696d706c656d656e746174696f6e732068617665207460448201527f6f20626520736d61727420636f6e7472616374730000000000000000000000006064820152608401610312565b6040805180820190915273ffffffffffffffffffffffffffffffffffffffff92831681529082166020820190815260088054600181018255600091909152915160029092027ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3810180549385167fffffffffffffffffffffffff000000000000000000000000000000000000000094851617905590517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee49091018054919093169116179055565b6000600882815481106114c8576114c861475e565b600091825260209091206001600290920201015473ffffffffffffffffffffffffffffffffffffffff1692915050565b600060086115046111aa565b815481106115145761151461475e565b600091825260209091206001600290920201015473ffffffffffffffffffffffffffffffffffffffff16919050565b60606000604051806060016040528060378152602001614af5603791399050606083901b60005b60148160ff1610156115ef57818160ff166014811061158b5761158b61475e565b1a60f81b8361159b8360146147d3565b60ff16815181106115ae576115ae61475e565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350806115e7816147f8565b91505061156a565b50909392505050565b6000806116066105aa6114f8565b8051602091820120604080517fff00000000000000000000000000000000000000000000000000000000000000818501527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b16602182015273ffffffffffffffffffffffffffffffffffffffff8716603582015260558082018490528251808303909101815260759091019091528051920191909120909150610c40565b6116b1836138f2565b61173d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f52656769737472793a2070726f7669646564206865726d65732068617320746f60448201527f20626520616374697665000000000000000000000000000000000000000000006064820152608401610312565b6000611770823086866004600081548092919061175990614818565b919050556040516020016109489493929190614851565b73ffffffffffffffffffffffffffffffffffffffff808616600090815260096020526040902054919250808316911614611806576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f77726f6e67207369676e617475726500000000000000000000000000000000006044820152606401610312565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260096020908152604090912084516118429260039092019186019061410c565b508373ffffffffffffffffffffffffffffffffffffffff167fd8c638c85547b8717e0d5ca292cff6dbe8fc02fa6e6863a047971c39511643c7846040516118899190614478565b60405180910390a250505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526009602052604090206003018054606091906118ce906148b1565b80601f01602080910402602001604051908101604052809291908181526020018280546118fa906148b1565b80156119475780601f1061191c57610100808354040283529160200191611947565b820191906000526020600020905b81548152906001019060200180831161192a57829003601f168201915b50505050509050919050565b600061197660075473ffffffffffffffffffffffffffffffffffffffff16151590565b15611a1e576007546040517fc3c5a54700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301529091169063c3c5a5479060240160206040518083038186803b1580156119e657600080fd5b505afa1580156119fa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110979190614905565b5073ffffffffffffffffffffffffffffffffffffffff9081166000908152600a602052604090205416151590565b60005473ffffffffffffffffffffffffffffffffffffffff16331480611a88575060005473ffffffffffffffffffffffffffffffffffffffff16155b611aee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610312565b60035473ffffffffffffffffffffffffffffffffffffffff16611bba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f52656769737472793a206f6e6c7920696e697469616c697a6564207265676973908201527f7472792063616e20736574206e6577206d696e696d616c206865726d6573207360648201527f74616b6500000000000000000000000000000000000000000000000000000000608482015260a401610312565b60068190556040518181527f645a9c74d34a0b1095b113252ad5e9afa0373f15b4b21760fb3a24b4b9d1ec309060200160405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff808216600090815260096020526040812080546001909101549192169082611c328383610f17565b90508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611c7257506000949350505050565b803b151580611d1f57506007546040517fcdd596e000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301529091169063cdd596e09060240160206040518083038186803b158015611ce757600080fd5b505afa158015611cfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d1f9190614905565b95945050505050565b611d31856138f2565b611dbd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f52656769737472793a2070726f7669646564206865726d65732068617665207460448201527f6f206265206163746976650000000000000000000000000000000000000000006064820152608401610312565b6000611e2a82466040805160208101929092527fffffffffffffffffffffffffffffffffffffffff00000000000000000000000030606090811b8216928401929092528a821b81166054840152606883018a9052608883018990529087901b1660a882015260bc01610948565b905073ffffffffffffffffffffffffffffffffffffffff8116611ecf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f52656769737472793a2077726f6e67206964656e74697479207369676e61747560448201527f72650000000000000000000000000000000000000000000000000000000000006064820152608401610312565b6000611edb8587614927565b60035490915073ffffffffffffffffffffffffffffffffffffffff166370a08231611f06848a61327b565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240160206040518083038186803b158015611f6a57600080fd5b505afa158015611f7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fa29190614728565b811115612031576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f52656769737472793a206e6f7420656e6f7567682066756e647320696e20636860448201527f616e6e656c20746f20636f7665722066656573000000000000000000000000006064820152608401610312565b61203d82888684613a4b565b5085156120cd576040517f24f453d100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018890528816906324f453d190604401600060405180830381600087803b1580156120b457600080fd5b505af11580156120c8573d6000803e3d6000fd5b505050505b841561217f576003546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810187905273ffffffffffffffffffffffffffffffffffffffff9091169063a9059cbb90604401602060405180830381600087803b15801561214557600080fd5b505af1158015612159573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217d9190614905565b505b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff821661222b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f52656769737472793a2062656e65666963696172792063616e2774206265207a60448201527f65726f20616464726573730000000000000000000000000000000000000000006064820152608401610312565b60075473ffffffffffffffffffffffffffffffffffffffff16156122d1576007546040517fd0171d7900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063d0171d79906122a39086908690869060040161493f565b600060405180830381600087803b1580156122bd57600080fd5b505af115801561217f573d6000803e3d6000fd5b6004546122df906001614927565b600455600061230560075473ffffffffffffffffffffffffffffffffffffffff16151590565b61230f5730612329565b60075473ffffffffffffffffffffffffffffffffffffffff165b9050600061239183466004546040805160208101939093527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088811b8216928501929092528a821b811660548501529089901b166068830152607c820152609c01610948565b90508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461244e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f52656769737472793a206861766520746f206265207369676e6564206279206960448201527f64656e74697479206f776e6572000000000000000000000000000000000000006064820152608401610312565b73ffffffffffffffffffffffffffffffffffffffff8581166000818152600a602090815260409182902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169489169485179055905192835290917f768099735d1c322a05a5b9d7b76d99682a1833d3f7055e5ede25e0f2eeaa8c6d910160405180910390a25050505050565b60035473ffffffffffffffffffffffffffffffffffffffff16612582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f52656769737472793a206f6e6c7920696e697469616c697a656420726567697360448201527f7472792063616e207265676973746572206865726d65736573000000000000006064820152608401610312565b73ffffffffffffffffffffffffffffffffffffffff8616612625576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f52656769737472793a206865726d6573206f70657261746f722063616e27742060448201527f6265207a65726f206164647265737300000000000000000000000000000000006064820152608401610312565b6006548510156126b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f52656769737472793a206865726d6573206861766520746f207374616b65206160448201527f74206c65617374206d696e696d616c207374616b6520616d6f756e74000000006064820152608401610312565b60006126c2876115f8565b90506126cd81611bf5565b1561275a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f52656769737472793a206865726d657320616c7265616479207265676973746560448201527f72656400000000000000000000000000000000000000000000000000000000006064820152608401610312565b60006127868873ffffffffffffffffffffffffffffffffffffffff166127816105aa6114f8565b613cbc565b6003546040517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8084166024830152604482018b90529293509116906323b872dd90606401602060405180830381600087803b15801561280257600080fd5b505af1158015612816573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061283a9190614905565b506003546005546040517f699a088500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff92831660048201528a8316602482015261ffff89166044820152606481018890526084810187905290821660a48201529082169063699a08859060c401600060405180830381600087803b1580156128d357600080fd5b505af11580156128e7573d6000803e3d6000fd5b5050505060405180608001604052808973ffffffffffffffffffffffffffffffffffffffff16815260200161291a6111aa565b815263fc0e3d90602084811b77ffffffffffffffffffffffffffffffffffffffff0000000090811692909217604090811b8285015292830187905273ffffffffffffffffffffffffffffffffffffffff868116600090815260098352849020855181547fffffffffffffffffffffffff0000000000000000000000000000000000000000169216919091178155848201516001820155848401516002820180547fffffffffffffffff0000000000000000000000000000000000000000000000001663ffffffff9290961c91821691909416179390931790915560608301518051612a0b926003850192019061410c565b50506003546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6024830152909116915063095ea7b390604401602060405180830381600087803b158015612aa157600080fd5b505af1158015612ab5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ad99190614905565b508173ffffffffffffffffffffffffffffffffffffffff167ff06d60cc2f463635fd237ad87f1d007af54840b82e7e4561707b1be63d91c2608985604051612b22929190614978565b60405180910390a25050505050505050565b60026001541415612ba1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610312565b600260018190555473ffffffffffffffffffffffffffffffffffffffff16612bc857600080fd5b60035473ffffffffffffffffffffffffffffffffffffffff82811691161415612c73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f6e617469766520746f6b656e2066756e64732063616e2774206265207265636f60448201527f76657265640000000000000000000000000000000000000000000000000000006064820152608401610312565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a082319060240160206040518083038186803b158015612cdb57600080fd5b505afa158015612cef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d139190614728565b6002546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526024810183905291925083169063a9059cbb90604401602060405180830381600087803b158015612d8957600080fd5b505af1158015612d9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dc19190614905565b50506001805550565b6040805160808101825260008082526020820181905291810191909152606080820152612df682611bf5565b80612e17575060075473ffffffffffffffffffffffffffffffffffffffff16155b612ee5576007546040517fe0b6c32300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301529091169063e0b6c3239060240160006040518083038186803b158015612e8657600080fd5b505afa158015612e9a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612ee091908101906149a7565b611097565b73ffffffffffffffffffffffffffffffffffffffff808316600090815260096020908152604091829020825160808101845281549094168452600181015491840191909152600281015477ffffffffffffffffffffffffffffffffffffffff00000000811663ffffffff90911617821b91830191909152600381018054606084019190612f71906148b1565b80601f0160208091040260200160405190810160405280929190818152602001828054612f9d906148b1565b8015612fea5780601f10612fbf57610100808354040283529160200191612fea565b820191906000526020600020905b815481529060010190602001808311612fcd57829003601f168201915b50505050508152505092915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331480613035575060005473ffffffffffffffffffffffffffffffffffffffff16155b61309b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610312565b6003546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a082319060240160206040518083038186803b15801561310557600080fd5b505afa158015613119573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061313d9190614728565b9050600081116131cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f636f6c6c6563746564206665652063616e6e6f74206265206c6573732074686160448201527f6e207a65726f00000000000000000000000000000000000000000000000000006064820152608401610312565b6003546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018490529091169063a9059cbb90604401602060405180830381600087803b15801561324357600080fd5b505af1158015613257573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f129190614905565b73ffffffffffffffffffffffffffffffffffffffff811660009081526009602052604081206001015481906132b3906105aa90610d97565b80519060200120905060008484604051602001613307929190606092831b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090811682529190921b16601482015260280190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201207fff00000000000000000000000000000000000000000000000000000000000000848301527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660218501526035840181905260558085018790528351808603909101815260759094019092528251920191909120909150611d1f565b60005473ffffffffffffffffffffffffffffffffffffffff163314806133fa575060005473ffffffffffffffffffffffffffffffffffffffff16155b613460576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610312565b73ffffffffffffffffffffffffffffffffffffffff8116613503576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610312565b6000805460405173ffffffffffffffffffffffffffffffffffffffff808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314806135cc575060005473ffffffffffffffffffffffffffffffffffffffff16155b613632576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610312565b60035473ffffffffffffffffffffffffffffffffffffffff16156136b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f52656769737472793a20697320616c726561647920696e697469616c697a65646044820152606401610312565b600684905573ffffffffffffffffffffffffffffffffffffffff8616613780576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f52656769737472793a20746f6b656e20736d61727420636f6e7472616374206360448201527f616e2774206265206465706c6f79656420696e746f203078302061646472657360648201527f7300000000000000000000000000000000000000000000000000000000000000608482015260a401610312565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff888116919091179091558516613853576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f52656769737472793a206465782063616e2774206265206465706c6f7965642060448201527f696e746f203078302061646472657373000000000000000000000000000000006064820152608401610312565b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff871617905561389d8383611209565b6138a6336133be565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555050505050565b60006138fd82611bf5565b613989576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f52656769737472793a206865726d6573206861766520746f206265207265676960448201527f73746572656400000000000000000000000000000000000000000000000000006064820152608401610312565b60008273ffffffffffffffffffffffffffffffffffffffff16634e69d5606040518163ffffffff1660e01b815260040160206040518083038186803b1580156139d157600080fd5b505afa1580156139e5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a099190614aa4565b90506000816003811115613a1f57613a1f614ac5565b149392505050565b6000806000613a368585613cd6565b91509150613a4381613d46565b509392505050565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086811b8216602084015285901b16603482015260009081906048016040516020818303038152906040528051906020012090506000613af46105aa600960008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154610d97565b90506000613b028383613cbc565b6003546005546040517ff7013ef600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482015290821660248201528a8216604482015289821660648201526084810188905291925082169063f7013ef69060a401600060405180830381600087803b158015613b9357600080fd5b505af1158015613ba7573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff8481168252808b1693508b1691507f2ed7bcf2ff03098102c7003d7ce2a633e4b49b8198b07de5383cdf4c0ab9228b9060200160405180910390a373ffffffffffffffffffffffffffffffffffffffff8616613c1b578095505b613c2488611953565b613cb15773ffffffffffffffffffffffffffffffffffffffff8881166000818152600a602090815260409182902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016948b169485179055905192835290917fefaf768237c22e140a862d5d375ad5c153479fac3f8bcf8b580a1651fd62c3ef910160405180910390a25b979650505050505050565b600080838351602085016000f59050803b610c4057600080fd5b600080825160411415613d0d5760208301516040840151606085015160001a613d0187828585613fa2565b94509450505050613d3f565b825160401415613d375760208301516040840151613d2c8683836140ba565b935093505050613d3f565b506000905060025b9250929050565b6000816004811115613d5a57613d5a614ac5565b1415613d635750565b6001816004811115613d7757613d77614ac5565b1415613ddf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610312565b6002816004811115613df357613df3614ac5565b1415613e5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610312565b6003816004811115613e6f57613e6f614ac5565b1415613efd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610312565b6004816004811115613f1157613f11614ac5565b1415613f9f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610312565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613fd957506000905060036140b1565b8460ff16601b14158015613ff157508460ff16601c14155b1561400257506000905060046140b1565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015614056573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166140aa576000600192509250506140b1565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316816140f060ff86901c601b614927565b90506140fe87828885613fa2565b935093505050935093915050565b828054614118906148b1565b90600052602060002090601f01602090048101928261413a5760008555614180565b82601f1061415357805160ff1916838001178555614180565b82800160010185558215614180579182015b82811115614180578251825591602001919060010190614165565b5061418c929150614190565b5090565b5b8082111561418c5760008155600101614191565b73ffffffffffffffffffffffffffffffffffffffff81168114613f9f57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715614219576142196141c7565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614266576142666141c7565b604052919050565b600067ffffffffffffffff821115614288576142886141c7565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126142c557600080fd5b81356142d86142d38261426e565b61421f565b8181528460208386010111156142ed57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121561431f57600080fd5b833561432a816141a5565b925060208401359150604084013567ffffffffffffffff81111561434d57600080fd5b614359868287016142b4565b9150509250925092565b6000806040838503121561437657600080fd5b8235614381816141a5565b91506020830135614391816141a5565b809150509250929050565b6000602082840312156143ae57600080fd5b8135610c40816141a5565b6000602082840312156143cb57600080fd5b5035919050565b600080604083850312156143e557600080fd5b82356143f0816141a5565b946020939093013593505050565b60005b83811015614419578181015183820152602001614401565b83811115614428576000848401525b50505050565b600081518084526144468160208601602086016143fe565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610c40602083018461442e565b6000806000606084860312156144a057600080fd5b83356144ab816141a5565b9250602084013567ffffffffffffffff808211156144c857600080fd5b6144d4878388016142b4565b935060408601359150808211156144ea57600080fd5b50614359868287016142b4565b600080600080600060a0868803121561450f57600080fd5b853561451a816141a5565b945060208601359350604086013592506060860135614538816141a5565b9150608086013567ffffffffffffffff81111561455457600080fd5b614560888289016142b4565b9150509295509295909350565b60008060006060848603121561458257600080fd5b833561458d816141a5565b9250602084013561459d816141a5565b9150604084013567ffffffffffffffff81111561434d57600080fd5b60008060008060008060c087890312156145d257600080fd5b86356145dd816141a5565b955060208701359450604087013561ffff811681146145fb57600080fd5b9350606087013592506080870135915060a087013567ffffffffffffffff81111561462557600080fd5b61463189828a016142b4565b9150509295509295509295565b6020815273ffffffffffffffffffffffffffffffffffffffff8251166020820152602082015160408201527fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000604083015116606082015260006060830151608080840152610fc460a084018261442e565b60008060008060008060c087890312156146c857600080fd5b86356146d3816141a5565b955060208701356146e3816141a5565b94506040870135935060608701356146fa816141a5565b9250608087013561470a816141a5565b915060a087013561471a816141a5565b809150509295509295509295565b60006020828403121561473a57600080fd5b5051919050565b60006020828403121561475357600080fd5b8151610c40816141a5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156147ce576147ce61478d565b500390565b600060ff821660ff84168060ff038211156147f0576147f061478d565b019392505050565b600060ff821660ff81141561480f5761480f61478d565b60010192915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561484a5761484a61478d565b5060010190565b60007fffffffffffffffffffffffffffffffffffffffff000000000000000000000000808760601b168352808660601b16601484015250835161489b8160288501602088016143fe565b6028920191820192909252604801949350505050565b600181811c908216806148c557607f821691505b602082108114156148ff577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60006020828403121561491757600080fd5b81518015158114610c4057600080fd5b6000821982111561493a5761493a61478d565b500190565b600073ffffffffffffffffffffffffffffffffffffffff808616835280851660208401525060606040830152611d1f606083018461442e565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000610fc4604083018461442e565b600060208083850312156149ba57600080fd5b825167ffffffffffffffff808211156149d257600080fd5b90840190608082870312156149e657600080fd5b6149ee6141f6565b82516149f9816141a5565b8152828401518482015260408301517fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000081168114614a3657600080fd5b6040820152606083015182811115614a4d57600080fd5b80840193505086601f840112614a6257600080fd5b82519150614a726142d38361426e565b8281528785848601011115614a8657600080fd5b614a95838683018787016143fe565b60608201529695505050505050565b600060208284031215614ab657600080fd5b815160048110610c4057600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfe3d602d80600a3d3981f3363d3d373d3d3d363d73bebebebebebebebebebebebebebebebebebebebe5af43d82803e903d91602b57fd5bf3a264697066735822122069ad65a1c8846f78818ebf888ec59c6436211956568469185d7bb5da32a87f7364736f6c63430008090033
Deployed ByteCode Sourcemap
21512:16971:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23056:49;;;;;216:2:1;23056:49:0;;;198:21:1;255:2;235:18;;;228:30;294:34;274:18;;;267:62;365:9;345:18;;;338:37;392:19;;23056:49:0;;;;;;;;21512:16971;;;;26224:701;;;;;;;;;;-1:-1:-1;26224:701:0;;;;;:::i;:::-;;:::i;:::-;;37949:247;;;;;;;;;;-1:-1:-1;37949:247:0;;;;;:::i;:::-;;:::i;:::-;;;3170:14:1;;3163:22;3145:41;;3133:2;3118:18;37949:247:0;;;;;;;;8021:258;;;;;;;;;;-1:-1:-1;8021:258:0;;;;;:::i;:::-;;:::i;24398:106::-;;;;;;;;;;-1:-1:-1;24476:5:0;;24468:28;24476:5;24468:28;;24398:106;;34917:152;;;;;;;;;;-1:-1:-1;34917:152:0;;;;;:::i;:::-;;:::i;:::-;;;3818:42:1;3806:55;;;3788:74;;3776:2;3761:18;34917:152:0;3642:226:1;27019:347:0;;;;;;;;;;-1:-1:-1;27019:347:0;;;;;:::i;:::-;;:::i;30885:278::-;;;;;;;;;;-1:-1:-1;30885:278:0;;;;;:::i;:::-;;:::i;33134:218::-;;;;;;;;;;-1:-1:-1;33134:218:0;;;;;:::i;:::-;;:::i;21593:24::-;;;;;;;;;;;;;;;;;;;4591:25:1;;;4579:2;4564:18;21593:24:0;4445:177:1;8586:164:0;;;;;;;;;;;;;:::i;35923:106::-;;;;;;;;;;;;;:::i;21709:33::-;;;;;;;;;;;;;;;;21624:26;;;;;;;;;;-1:-1:-1;21624:26:0;;;;;;;;34765:144;;;;;;;;;;;;;:::i;35385:469::-;;;;;;;;;;-1:-1:-1;35385:469:0;;;;;:::i;:::-;;:::i;35227:150::-;;;;;;;;;;-1:-1:-1;35227:150:0;;;;;:::i;:::-;;:::i;3539:79::-;;;;;;;;;;-1:-1:-1;3577:7:0;3604:6;;;3539:79;;35077:142;;;;;;;;;;;;;:::i;32215:548::-;;;;;;;;;;-1:-1:-1;32215:548:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;30625:252::-;;;;;;;;;;-1:-1:-1;30625:252:0;;;;;:::i;:::-;;:::i;31304:562::-;;;;;;;;;;-1:-1:-1;31304:562:0;;;;;:::i;:::-;;:::i;31171:125::-;;;;;;;;;;-1:-1:-1;31171:125:0;;;;;:::i;:::-;;:::i;36561:298::-;;;;;;;;;;-1:-1:-1;36561:298:0;;;;;:::i;:::-;;:::i;34378:296::-;;;;;;;;;;-1:-1:-1;34378:296:0;;;;;:::i;:::-;;:::i;21749:30::-;;;;;;;;;;-1:-1:-1;21749:30:0;;;;;;;;36867:658;;;;;;;;;;-1:-1:-1;36867:658:0;;;;;:::i;:::-;;:::i;24821:1308::-;;;;;;;;;;-1:-1:-1;24821:1308:0;;;;;:::i;:::-;;:::i;33360:1010::-;;;;;;;;;;-1:-1:-1;33360:1010:0;;;;;:::i;:::-;;:::i;36434:119::-;;;;;;;;;;-1:-1:-1;36516:14:0;;36508:37;36516:14;36508:37;;36434:119;;28549:1516;;;;;;;;;;-1:-1:-1;28549:1516:0;;;;;:::i;:::-;;:::i;8829:339::-;;;;;;;;;;-1:-1:-1;8829:339:0;;;;;:::i;:::-;;:::i;30414:203::-;;;;;;;;;;-1:-1:-1;30414:203:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;38204:276::-;;;;;;;;;;-1:-1:-1;38204:276:0;;;;;:::i;:::-;;:::i;30073:333::-;;;;;;;;;;-1:-1:-1;30073:333:0;;;;;:::i;:::-;;:::i;3777:244::-;;;;;;;;;;-1:-1:-1;3777:244:0;;;;;:::i;:::-;;:::i;8348:103::-;;;;;;;;;;-1:-1:-1;8427:16:0;;;;8348:103;;7817:24;;;;;;;;;;-1:-1:-1;7817:24:0;;;;;;;;23417:973;;;;;;;;;;-1:-1:-1;23417:973:0;;;;;:::i;:::-;;:::i;26224:701::-;26347:25;26362:9;26347:14;:25::i;:::-;26339:81;;;;;;;10788:2:1;26339:81:0;;;10770:21:1;10827:2;10807:18;;;10800:30;10866:34;10846:18;;;10839:62;10937:13;10917:18;;;10910:41;10968:19;;26339:81:0;10586:407:1;26339:81:0;26479:17;26499:103;26591:10;198:9;26509:72;;;;;;11211:19:1;;;;11249:66;26548:4:0;11353:2:1;11349:15;;;11345:24;;11331:12;;;11324:46;;;;11404:15;;;;11400:24;11386:12;;;11379:46;11441:12;;;11434:28;;;11478:13;;26509:72:0;;;;;;;;;;;;;26499:83;;;;;;:91;;:103;;;;:::i;:::-;26479:123;-1:-1:-1;26621:23:0;;;26613:78;;;;;;;11704:2:1;26613:78:0;;;11686:21:1;11743:2;11723:18;;;11716:30;11782:34;11762:18;;;11755:62;11853:12;11833:18;;;11826:40;11883:19;;26613:78:0;11502:406:1;26613:78:0;26730:5;;;;:15;26746:39;26764:9;26775;26746:17;:39::i;:::-;26730:56;;;;;;;;;;3818:42:1;3806:55;;;26730:56:0;;;3788:74:1;3761:18;;26730:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;26712:14;:74;;26704:138;;;;;;;12304:2:1;26704:138:0;;;12286:21:1;12343:2;12323:18;;;12316:30;12382:34;12362:18;;;12355:62;12453:21;12433:18;;;12426:49;12492:19;;26704:138:0;12102:415:1;26704:138:0;26855:62;26868:9;26879;26898:1;26902:14;26855:12;:62::i;:::-;;26328:597;26224:701;;;:::o;37949:247::-;38033:4;38057:56;38073:39;38091:9;38102;38073:17;:39::i;:::-;36268:18;36316:16;;;36120:220;38057:56;:131;;;-1:-1:-1;38133:14:0;;:54;;;;;:14;12775:15:1;;;38133:54:0;;;12757:34:1;12827:15;;;12807:18;;;12800:43;38117:71:0;;38133:14;;:32;;12669:18:1;;38133:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;38117:71::-;38050:138;37949:247;-1:-1:-1;;;37949:247:0:o;8021:258::-;3666:6;;:20;:6;3676:10;3666:20;;:46;;-1:-1:-1;3708:3:0;3690:6;:22;:6;:22;3666:46;3658:91;;;;;;;13312:2:1;3658:91:0;;;13294:21:1;;;13331:18;;;13324:30;13390:34;13370:18;;;13363:62;13442:18;;3658:91:0;13110:356:1;3658:91:0;8127:29:::1;::::0;::::1;8119:38;;;::::0;::::1;;8192:16;::::0;8173:53:::1;::::0;::::1;::::0;;::::1;::::0;8192:16:::1;::::0;8173:53:::1;::::0;8192:16:::1;::::0;8173:53:::1;8237:16;:34:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;8021:258::o;34917:152::-;34990:7;35017:15;35033:8;35017:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:44;;;;34917:152;-1:-1:-1;;34917:152:0:o;27019:347::-;27112:25;27127:9;27112:14;:25::i;:::-;27104:81;;;;;;;10788:2:1;27104:81:0;;;10770:21:1;10827:2;10807:18;;;10800:30;10866:34;10846:18;;;10839:62;10937:13;10917:18;;;10910:41;10968:19;;27104:81:0;10586:407:1;27104:81:0;27205:37;27221:9;27232;27205:15;:37::i;:::-;27204:38;27196:100;;;;;;;13862:2:1;27196:100:0;;;13844:21:1;13901:2;13881:18;;;13874:30;13940:34;13920:18;;;13913:62;14011:19;13991:18;;;13984:47;14048:19;;27196:100:0;13660:413:1;27196:100:0;27309:49;27322:9;27333;27352:1;27356;27309:12;:49::i;:::-;;27019:347;;:::o;30885:278::-;30975:7;30995:13;31021:47;31034:33;31058:8;31034:23;:33::i;31021:47::-;31011:58;;;;;;;32055:140;;;32086:12;32055:140;;;31323:92:1;31465:66;32121:4:0;31452:2:1;31448:15;31444:88;31431:11;;;31424:109;31113:33:0;;;31549:12:1;;;31542:28;31586:12;;;;31579:28;;;32055:140:0;;;;;;;;;;31623:12:1;;;;32055:140:0;;;32045:151;;;;;;;;31011:58;;-1:-1:-1;31087:68:0;31080:75;30885:278;-1:-1:-1;;;;30885:278:0:o;33134:218::-;33198:7;33222:19;36516:14;;36508:37;36516:14;36508:37;;;36434:119;33222:19;33218:85;;;33263:14;;:40;;;;;:14;3806:55:1;;;33263:40:0;;;3788:74:1;33263:14:0;;;;:29;;3761:18:1;;33263:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;33256:47;33134:218;-1:-1:-1;;33134:218:0:o;33218:85::-;-1:-1:-1;33323:21:0;;;;;;;;:10;:21;;;;;;;;33134:218::o;8586:164::-;2393:1;2991:7;;:19;;2983:63;;;;;;;14280:2:1;2983:63:0;;;14262:21:1;14319:2;14299:18;;;14292:30;14358:33;14338:18;;;14331:61;14409:18;;2983:63:0;14078:355:1;2983:63:0;2393:1;3124:7;:18;;;8652:16;:30:::1;:16;8644:39;;;::::0;::::1;;8694:16;::::0;:48:::1;::::0;:16:::1;::::0;;::::1;::::0;8720:21:::1;8694:48:::0;::::1;;;::::0;:16:::1;:48:::0;:16;:48;8720:21;8694:16;:48;::::1;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;2349:1:0;3303:22;;8586:164::o;35923:106::-;35997:15;:22;35970:7;;35997:24;;36020:1;;35997:24;:::i;:::-;35990:31;;35923:106;:::o;34765:144::-;34822:7;34849:15;34865:16;:14;:16::i;:::-;34849:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:52;;;;34765:144;-1:-1:-1;34765:144:0:o;35385:469::-;3666:6;;:20;:6;3676:10;3666:20;;:46;;-1:-1:-1;3708:3:0;3690:6;:22;:6;:22;3666:46;3658:91;;;;;;;13312:2:1;3658:91:0;;;13294:21:1;;;13331:18;;;13324:30;13390:34;13370:18;;;13363:62;13442:18;;3658:91:0;13110:356:1;3658:91:0;24476:5;;24468:28;24476:5;35504:91:::1;;;::::0;::::1;::::0;;14959:2:1;35504:91:0::1;::::0;::::1;14941:21:1::0;14998:2;14978:18;;;14971:30;15037:34;15017:18;;;15010:62;15108:33;15088:18;;;15081:61;15159:19;;35504:91:0::1;14757:427:1::0;35504:91:0::1;36268:18:::0;;36316:16;;35614:81:::1;;;;-1:-1:-1::0;36268:18:0;;36316:16;;35657:38:::1;35606:146;;;::::0;::::1;::::0;;15391:2:1;35606:146:0::1;::::0;::::1;15373:21:1::0;15430:2;15410:18;;;15403:30;15469:34;15449:18;;;15442:62;15540:22;15520:18;;;15513:50;15580:19;;35606:146:0::1;15189:416:1::0;35606:146:0::1;35784:61;::::0;;;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;;;::::1;;::::0;::::1;::::0;;;35763:15:::1;:83:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;35763:83:0;;;;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;::::1;::::0;;;::::1;;::::0;;;;;;;;;;;;;::::1;::::0;::::1;;::::0;;35385:469::o;35227:150::-;35299:7;35326:15;35342:8;35326:25;;;;;;;;:::i;:::-;;;;;;;;;:43;:25;;;;;:43;;;;;35227:150;-1:-1:-1;;35227:150:0:o;35077:142::-;35133:7;35160:15;35176:16;:14;:16::i;:::-;35160:33;;;;;;;;:::i;:::-;;;;;;;;;:51;:33;;;;;:51;;;;;35077:142;-1:-1:-1;35077:142:0:o;32215:548::-;32283:12;32435:18;:136;;;;;;;;;;;;;;;;;;-1:-1:-1;32607:24:0;;;;32584:20;32642:89;32664:2;32660:1;:6;;;32642:89;;;32704:12;32717:1;32704:15;;;;;;;;;:::i;:::-;;;;32688:5;32694:6;32699:1;32694:2;:6;:::i;:::-;32688:13;;;;;;;;;;:::i;:::-;;;;:31;;;;;;;;;;-1:-1:-1;32668:3:0;;;;:::i;:::-;;;;32642:89;;;-1:-1:-1;32750:5:0;;32215:548;-1:-1:-1;;;32215:548:0:o;30625:252::-;30697:7;30717:13;30743:39;30756:25;:23;:25::i;30743:39::-;30733:50;;;;;;;32055:140;;;32086:12;32055:140;;;31323:92:1;31465:66;32121:4:0;31452:2:1;31448:15;31444:88;31431:11;;;31424:109;30827:33:0;;;31549:12:1;;;31542:28;31586:12;;;;31579:28;;;32055:140:0;;;;;;;;;;31623:12:1;;;;32055:140:0;;;32045:151;;;;;;;;30733:50;;-1:-1:-1;30801:68:0;31914:293;31304:562;31418:25;31433:9;31418:14;:25::i;:::-;31410:80;;;;;;;16201:2:1;31410:80:0;;;16183:21:1;16240:2;16220:18;;;16213:30;16279:34;16259:18;;;16252:62;16350:12;16330:18;;;16323:40;16380:19;;31410:80:0;15999:406:1;31410:80:0;31549:17;31569:92;31650:10;31604:4;31611:9;31622:4;31628:9;;:11;;;;;;;;;:::i;:::-;;;;;31579:61;;;;;;;;;;;:::i;31569:92::-;31693:19;;;;;;;;:8;:19;;;;;:28;31549:112;;-1:-1:-1;31680:41:0;;;31693:28;;31680:41;31672:69;;;;;;;17436:2:1;31672:69:0;;;17418:21:1;17475:2;17455:18;;;17448:30;17514:17;17494:18;;;17487:45;17549:18;;31672:69:0;17234:339:1;31672:69:0;31777:19;;;;;;;:8;:19;;;;;;;;:30;;;;:23;;;;;:30;;;;:::i;:::-;;31842:9;31825:33;;;31853:4;31825:33;;;;;;:::i;:::-;;;;;;;;31399:467;31304:562;;;:::o;31171:125::-;31265:19;;;;;;;:8;:19;;;;;:23;;31258:30;;31233:12;;31265:23;31258:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31171:125;;;:::o;36561:298::-;36623:4;36644:19;36516:14;;36508:37;36516:14;36508:37;;;36434:119;36644:19;36640:83;;;36685:14;;:38;;;;;:14;3806:55:1;;;36685:38:0;;;3788:74:1;36685:14:0;;;;:27;;3761:18:1;;36685:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;36640:83::-;-1:-1:-1;36816:35:0;:21;;;36849:1;36816:21;;;:10;:21;;;;;;;:35;;;36561:298::o;34378:296::-;3666:6;;:20;:6;3676:10;3666:20;;:46;;-1:-1:-1;3708:3:0;3690:6;:22;:6;:22;3666:46;3658:91;;;;;;;13312:2:1;3658:91:0;;;13294:21:1;;;13331:18;;;13324:30;13390:34;13370:18;;;13363:62;13442:18;;3658:91:0;13110:356:1;3658:91:0;24476:5;;24468:28;24476:5;34463:96:::1;;;::::0;::::1;::::0;;18504:2:1;34463:96:0::1;::::0;::::1;18486:21:1::0;18543:2;18523:18;;;18516:30;;;18582:34;18562:18;;;18555:62;18653:34;18633:18;;;18626:62;18725:6;18704:19;;;18697:35;18749:19;;34463:96:0::1;18302:472:1::0;34463:96:0::1;34570:18;:37:::0;;;34623:43:::1;::::0;4591:25:1;;;34623:43:0::1;::::0;4579:2:1;4564:18;34623:43:0::1;;;;;;;34378:296:::0;:::o;36867:658::-;37174:19;;;;36925:4;37174:19;;;:8;:19;;;;;:28;;;37232:27;;;;36925:4;;37174:28;;36925:4;37286:43;37174:28;37232:27;37286:16;:43::i;:::-;37270:59;;37353:9;37344:18;;:5;:18;;;37340:49;;-1:-1:-1;37384:5:0;;36867:658;-1:-1:-1;;;;36867:658:0:o;37340:49::-;36268:18;;36316:16;;37457:60;;;-1:-1:-1;37483:14:0;;:34;;;;;:14;3806:55:1;;;37483:34:0;;;3788:74:1;37483:14:0;;;;:23;;3761:18:1;;37483:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;37450:67;36867:658;-1:-1:-1;;;;;36867:658:0:o;24821:1308::-;24985:25;25000:9;24985:14;:25::i;:::-;24977:81;;;;;;;10788:2:1;24977:81:0;;;10770:21:1;10827:2;10807:18;;;10800:30;10866:34;10846:18;;;10839:62;10937:13;10917:18;;;10910:41;10968:19;;24977:81:0;10586:407:1;24977:81:0;25117:17;25137:131;25257:10;198:9;25147:100;;;;;;19048:19:1;;;;19086:66;25186:4:0;19190:2:1;19186:15;;;19182:24;;19168:12;;;19161:46;;;;19241:15;;;19237:24;;19223:12;;;19216:46;19278:12;;;19271:28;;;19315:13;;;19308:29;;;19372:15;;;;19368:24;19353:13;;;19346:47;19409:13;;25147:100:0;18779:649:1;25137:131:0;25117:151;-1:-1:-1;25287:23:0;;;25279:70;;;;;;;19635:2:1;25279:70:0;;;19617:21:1;19674:2;19654:18;;;19647:30;19713:34;19693:18;;;19686:62;19784:4;19764:18;;;19757:32;19806:19;;25279:70:0;19433:398:1;25279:70:0;25445:17;25465:29;25480:14;25465:12;:29;:::i;:::-;25526:5;;25445:49;;-1:-1:-1;25526:5:0;;:15;25542:39;25560:9;25571;25542:17;:39::i;:::-;25526:56;;;;;;;;;;3818:42:1;3806:55;;;25526:56:0;;;3788:74:1;3761:18;;25526:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;25513:9;:69;;25505:133;;;;;;;12304:2:1;25505:133:0;;;12286:21:1;12343:2;12323:18;;;12316:30;12382:34;12362:18;;;12355:62;12453:21;12433:18;;;12426:49;12492:19;;25505:133:0;12102:415:1;25505:133:0;25685:59;25698:9;25709;25720:12;25734:9;25685:12;:59::i;:::-;-1:-1:-1;25867:16:0;;25863:112;;25900:63;;;;;:38;20161:55:1;;;25900:63:0;;;20143:74:1;20233:18;;;20226:34;;;25900:38:0;;;;;20116:18:1;;25900:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25863:112;26033:18;;26029:93;;26068:5;;:42;;;;;26083:10;26068:42;;;20143:74:1;20233:18;;;20226:34;;;26068:5:0;;;;;:14;;20116:18:1;;26068:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;26029:93;24966:1163;;24821:1308;;;;;:::o;33360:1010::-;33479:29;;;33471:85;;;;;;;20473:2:1;33471:85:0;;;20455:21:1;20512:2;20492:18;;;20485:30;20551:34;20531:18;;;20524:62;20622:13;20602:18;;;20595:41;20653:19;;33471:85:0;20271:407:1;33471:85:0;36516:14;;36508:37;36516:14;36508:37;33623:740;;33663:14;;:69;;;;;:14;;;;;:29;;:69;;33693:9;;33704:15;;33721:10;;33663:69;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33623:740;33777:9;;:13;;33789:1;33777:13;:::i;:::-;33765:9;:25;33901:21;33925:19;36516:14;;36508:37;36516:14;36508:37;;;36434:119;33925:19;:61;;33981:4;33925:61;;;33955:14;;;;33925:61;33901:85;-1:-1:-1;34001:15:0;34019:115;34123:10;198:9;34103;;34029:84;;;;;;21367:19:1;;;;21405:66;21509:2;21505:15;;;21501:24;;21487:12;;;21480:46;;;;21560:15;;;21556:24;;21542:12;;;21535:46;21615:15;;;;21611:24;21597:12;;;21590:46;21652:12;;;21645:28;21689:13;;34029:84:0;21126:582:1;34019:115:0;34001:133;;34168:9;34157:20;;:7;:20;;;34149:78;;;;;;;21915:2:1;34149:78:0;;;21897:21:1;21954:2;21934:18;;;21927:30;21993:34;21973:18;;;21966:62;22064:15;22044:18;;;22037:43;22097:19;;34149:78:0;21713:409:1;34149:78:0;34244:21;;;;;;;;:10;:21;;;;;;;;;:39;;;;;;;;;;;;34305:46;;3788:74:1;;;34244:21:0;;34305:46;;3761:18:1;34305:46:0;;;;;;;33750:613;;33360:1010;;;:::o;28549:1516::-;24476:5;;24468:28;24476:5;28728:85;;;;;;;22329:2:1;28728:85:0;;;22311:21:1;22368:2;22348:18;;;22341:30;22407:34;22387:18;;;22380:62;22478:27;22458:18;;;22451:55;22523:19;;28728:85:0;22127:421:1;28728:85:0;28832:29;;;28824:89;;;;;;;22755:2:1;28824:89:0;;;22737:21:1;22794:2;22774:18;;;22767:30;22833:34;22813:18;;;22806:62;22904:17;22884:18;;;22877:45;22939:19;;28824:89:0;22553:411:1;28824:89:0;28948:18;;28932:12;:34;;28924:107;;;;;;;23171:2:1;28924:107:0;;;23153:21:1;23210:2;23190:18;;;23183:30;23249:34;23229:18;;;23222:62;23320:30;23300:18;;;23293:58;23368:19;;28924:107:0;22969:424:1;28924:107:0;29044:17;29064:33;29081:15;29064:16;:33::i;:::-;29044:53;;29117:19;29126:9;29117:8;:19::i;:::-;29116:20;29108:68;;;;;;;23600:2:1;29108:68:0;;;23582:21:1;23639:2;23619:18;;;23612:30;23678:34;23658:18;;;23651:62;23749:5;23729:18;;;23722:33;23772:19;;29108:68:0;23398:399:1;29108:68:0;29273:23;29315:91;29347:15;29331:33;;29366:39;29379:25;:23;:25::i;29366:39::-;29315:15;:91::i;:::-;29474:5;;:62;;;;;29493:10;29474:62;;;24065:34:1;29474:5:0;24135:15:1;;;24115:18;;;24108:43;24167:18;;;24160:34;;;29273:134:0;;-1:-1:-1;29474:5:0;;;:18;;23977::1;;29474:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;29606:5:0;;29679:3;;29579:104;;;;;:18;29606:5;;;29579:104;;;24567:34:1;24637:15;;;24617:18;;;24610:43;24701:6;24689:19;;24669:18;;;24662:47;24725:18;;;24718:34;;;24768:19;;;24761:35;;;29679:3:0;;;24812:19:1;;;24805:44;29579:18:0;;;;;;24478:19:1;;29579:104:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29767:65;;;;;;;;29774:15;29767:65;;;;;;29791:16;:14;:16::i;:::-;29767:65;;29809:16;29767:65;;;;;;;;;;;;;;;;;;;;;;;;;;29809:16;29745:19;;;-1:-1:-1;29745:19:0;;;:8;:19;;;;;:87;;;;;;;;;;;;;;;;;;-1:-1:-1;29745:87:0;;;;;;;;;;;;;;29767:65;29745:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;29946:5:0;;:43;;;;;:5;20161:55:1;;;29946:43:0;;;20143:74:1;29971:17:0;20233:18:1;;;20226:34;29946:5:0;;;;-1:-1:-1;29946:13:0;;20116:18:1;;29946:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;30024:9;30007:50;;;30035:15;30052:4;30007:50;;;;;;;:::i;:::-;;;;;;;;28717:1348;;28549:1516;;;;;;:::o;8829:339::-;2393:1;2991:7;;:19;;2983:63;;;;;;;14280:2:1;2983:63:0;;;14262:21:1;14319:2;14299:18;;;14292:30;14358:33;14338:18;;;14331:61;14409:18;;2983:63:0;14078:355:1;2983:63:0;2393:1;3124:7;:18;;;8905:16;:30:::1;:16;8897:39;;;::::0;::::1;;8973:5;::::0;::::1;8955:24:::0;;::::1;8973:5:::0;::::1;8955:24;;8947:74;;;::::0;::::1;::::0;;25404:2:1;8947:74:0::1;::::0;::::1;25386:21:1::0;25443:2;25423:18;;;25416:30;25482:34;25462:18;;;25455:62;25553:7;25533:18;;;25526:35;25578:19;;8947:74:0::1;25202:401:1::0;8947:74:0::1;9050:44;::::0;;;;9088:4:::1;9050:44;::::0;::::1;3788:74:1::0;9032:15:0::1;::::0;9050:29:::1;::::0;::::1;::::0;::::1;::::0;3761:18:1;;9050:44:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9134:16;::::0;9105:55:::1;::::0;;;;:28:::1;9134:16:::0;;::::1;9105:55;::::0;::::1;20143:74:1::0;20233:18;;;20226:34;;;9032:62:0;;-1:-1:-1;9105:28:0;::::1;::::0;::::1;::::0;20116:18:1;;9105:55:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;2349:1:0;3303:22;;-1:-1:-1;8829:339:0:o;30414:203::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30506:19:0;30515:9;30506:8;:19::i;:::-;:43;;;-1:-1:-1;36516:14:0;;36508:37;36516:14;36508:37;30506:43;:103;;30574:14;;:35;;;;;:14;3806:55:1;;;30574:35:0;;;3788:74:1;30574:14:0;;;;:24;;3761:18:1;;30574:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;30506:103;;;30552:19;;;;;;;;:8;:19;;;;;;;;;30506:103;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30499:110;30414:203;-1:-1:-1;;30414:203:0:o;38204:276::-;3666:6;;:20;:6;3676:10;3666:20;;:46;;-1:-1:-1;3708:3:0;3690:6;:22;:6;:22;3666:46;3658:91;;;;;;;13312:2:1;3658:91:0;;;13294:21:1;;;13331:18;;;13324:30;13390:34;13370:18;;;13363:62;13442:18;;3658:91:0;13110:356:1;3658:91:0;38309:5:::1;::::0;:30:::1;::::0;;;;38333:4:::1;38309:30;::::0;::::1;3788:74:1::0;38285:21:0::1;::::0;38309:5:::1;;::::0;:15:::1;::::0;3761:18:1;;38309:30:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38285:54;;38374:1;38358:13;:17;38350:68;;;::::0;::::1;::::0;;27431:2:1;38350:68:0::1;::::0;::::1;27413:21:1::0;27470:2;27450:18;;;27443:30;27509:34;27489:18;;;27482:62;27580:8;27560:18;;;27553:36;27606:19;;38350:68:0::1;27229:402:1::0;38350:68:0::1;38429:5;::::0;:43:::1;::::0;;;;:5:::1;20161:55:1::0;;;38429:43:0::1;::::0;::::1;20143:74:1::0;20233:18;;;20226:34;;;38429:5:0;;::::1;::::0;:14:::1;::::0;20116:18:1;;38429:43:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;30073:333::-:0;30243:19;;;30159:7;30243:19;;;:8;:19;;;;;:27;;;30159:7;;30205:67;;30218:53;;:24;:53::i;30205:67::-;30195:78;;;;;;30179:94;;30284:13;30327:9;30338;30310:38;;;;;;;;27898:2:1;27894:15;;;27803:66;27890:24;;;27878:37;;27949:15;;;;27945:24;27940:2;27931:12;;27924:46;27995:2;27986:12;;27636:368;30310:38:0;;;;;;;;;;;;;;30300:49;;30310:38;30300:49;;;;32086:12;32055:140;;;31323:92:1;31465:66;32121:4:0;31452:2:1;31448:15;31444:88;31431:11;;;31424:109;31549:12;;;31542:28;;;31586:12;;;;31579:28;;;32055:140:0;;;;;;;;;;31623:12:1;;;;32055:140:0;;;32045:151;;;;;;;;30300:49;;-1:-1:-1;30367:31:0;31914:293;3777:244;3666:6;;:20;:6;3676:10;3666:20;;:46;;-1:-1:-1;3708:3:0;3690:6;:22;:6;:22;3666:46;3658:91;;;;;;;13312:2:1;3658:91:0;;;13294:21:1;;;13331:18;;;13324:30;13390:34;13370:18;;;13363:62;13442:18;;3658:91:0;13110:356:1;3658:91:0;3866:22:::1;::::0;::::1;3858:73;;;::::0;::::1;::::0;;28211:2:1;3858:73:0::1;::::0;::::1;28193:21:1::0;28250:2;28230:18;;;28223:30;28289:34;28269:18;;;28262:62;28360:8;28340:18;;;28333:36;28386:19;;3858:73:0::1;28009:402:1::0;3858:73:0::1;3968:6;::::0;;3947:38:::1;::::0;::::1;::::0;;::::1;::::0;3968:6;::::1;::::0;3947:38:::1;::::0;::::1;3996:6;:17:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;3777:244::o;23417:973::-;3666:6;;:20;:6;3676:10;3666:20;;:46;;-1:-1:-1;3708:3:0;3690:6;:22;:6;:22;3666:46;3658:91;;;;;;;13312:2:1;3658:91:0;;;13294:21:1;;;13331:18;;;13324:30;13390:34;13370:18;;;13363:62;13442:18;;3658:91:0;13110:356:1;3658:91:0;24476:5;;24468:28;24476:5;24468:28;23642:61:::1;;;::::0;::::1;::::0;;28618:2:1;23642:61:0::1;::::0;::::1;28600:21:1::0;;;28637:18;;;28630:30;28696:34;28676:18;;;28669:62;28748:18;;23642:61:0::1;28416:356:1::0;23642:61:0::1;23716:18;:40:::0;;;23777:27:::1;::::0;::::1;23769:105;;;::::0;::::1;::::0;;28979:2:1;23769:105:0::1;::::0;::::1;28961:21:1::0;29018:2;28998:18;;;28991:30;29057:34;29037:18;;;29030:62;29128:34;29108:18;;;29101:62;29200:3;29179:19;;;29172:32;29221:19;;23769:105:0::1;28777:469:1::0;23769:105:0::1;23885:5;:34:::0;;;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;;23940:25;::::1;23932:86;;;::::0;::::1;::::0;;29453:2:1;23932:86:0::1;::::0;::::1;29435:21:1::0;29492:2;29472:18;;;29465:30;29531:34;29511:18;;;29504:62;29602:18;29582;;;29575:46;29638:19;;23932:86:0::1;29251:412:1::0;23932:86:0::1;24029:3;:17:::0;;;::::1;;::::0;::::1;;::::0;;24107:65:::1;24126:22:::0;24150:21;24107:18:::1;:65::i;:::-;24229:29;24247:10;24229:17;:29::i;:::-;24340:14;:42:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;;;23417:973:0:o;37533:408::-;37599:4;37731:19;37740:9;37731:8;:19::i;:::-;37723:70;;;;;;;29870:2:1;37723:70:0;;;29852:21:1;29909:2;29889:18;;;29882:30;29948:34;29928:18;;;29921:62;30019:8;29999:18;;;29992:36;30045:19;;37723:70:0;29668:402:1;37723:70:0;37806:29;37854:9;37838:36;;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;37806:70;-1:-1:-1;37904:29:0;37894:6;:39;;;;;;;;:::i;:::-;;;37533:408;-1:-1:-1;;;37533:408:0:o;16185:231::-;16263:7;16284:17;16303:18;16325:27;16336:4;16342:9;16325:10;:27::i;:::-;16283:69;;;;16363:18;16375:5;16363:11;:18::i;:::-;-1:-1:-1;16399:9:0;16185:231;-1:-1:-1;;;16185:231:0:o;27519:1022::-;27679:38;;27803:66:1;27898:2;27894:15;;;27890:24;;27679:38:0;;;27878:37:1;27949:15;;;27945:24;27931:12;;;27924:46;27633:7:0;;;;27986:12:1;;27679:38:0;;;;;;;;;;;;27669:49;;;;;;27653:65;;27729:18;27750:67;27763:53;27788:8;:19;27797:9;27788:19;;;;;;;;;;;;;;;:27;;;27763:24;:53::i;27750:67::-;27729:88;-1:-1:-1;27828:16:0;27855:38;27879:5;27729:88;27855:15;:38::i;:::-;27933:5;;27941:3;;27905:68;;;;;:19;27933:5;;;27905:68;;;30867:34:1;27941:3:0;;;30917:18:1;;;30910:43;30989:15;;;30969:18;;;30962:43;31041:15;;;31021:18;;;31014:43;31073:19;;;31066:35;;;27828:66:0;;-1:-1:-1;27905:19:0;;;;;30778::1;;27905:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;27991:63:0;;;3806:55:1;;;3788:74;;27991:63:0;;;;-1:-1:-1;27991:63:0;;;-1:-1:-1;27991:63:0;;3776:2:1;3761:18;27991:63:0;;;;;;;28166:26;;;28162:91;;28232:8;28209:32;;28162:91;28346:23;28359:9;28346:12;:23::i;:::-;28341:156;;28386:21;;;;;;;;:10;:21;;;;;;;;;:36;;;;;;;;;;;;28442:43;;3788:74:1;;;28386:21:0;;28442:43;;3761:18:1;28442:43:0;;;;;;;28341:156;28524:8;27519:1022;-1:-1:-1;;;;;;;27519:1022:0:o;32771:355::-;32849:15;32877:21;32987:5;32979;32973:12;32966:4;32959:5;32955:16;32952:1;32944:49;32935:58;;33029:5;33017:18;33007:76;;33066:1;33063;33056:12;13979:1404;14060:7;14069:12;14294:9;:16;14314:2;14294:22;14290:1086;;;14638:4;14623:20;;14617:27;14688:4;14673:20;;14667:27;14746:4;14731:20;;14725:27;14333:9;14717:36;14789:25;14800:4;14717:36;14617:27;14667;14789:10;:25::i;:::-;14782:32;;;;;;;;;14290:1086;14836:9;:16;14856:2;14836:22;14832:544;;;15159:4;15144:20;;15138:27;15210:4;15195:20;;15189:27;15252:23;15263:4;15138:27;15189;15252:10;:23::i;:::-;15245:30;;;;;;;;14832:544;-1:-1:-1;15324:1:0;;-1:-1:-1;15328:35:0;14832:544;13979:1404;;;;;:::o;12250:643::-;12328:20;12319:5;:29;;;;;;;;:::i;:::-;;12315:571;;;12250:643;:::o;12315:571::-;12426:29;12417:5;:38;;;;;;;;:::i;:::-;;12413:473;;;12472:34;;;;;31848:2:1;12472:34:0;;;31830:21:1;31887:2;31867:18;;;31860:30;31926:26;31906:18;;;31899:54;31970:18;;12472:34:0;31646:348:1;12413:473:0;12537:35;12528:5;:44;;;;;;;;:::i;:::-;;12524:362;;;12589:41;;;;;32201:2:1;12589:41:0;;;32183:21:1;32240:2;32220:18;;;32213:30;32279:33;32259:18;;;32252:61;32330:18;;12589:41:0;31999:355:1;12524:362:0;12661:30;12652:5;:39;;;;;;;;:::i;:::-;;12648:238;;;12708:44;;;;;32561:2:1;12708:44:0;;;32543:21:1;32600:2;32580:18;;;32573:30;32639:34;32619:18;;;32612:62;32710:4;32690:18;;;32683:32;32732:19;;12708:44:0;32359:398:1;12648:238:0;12783:30;12774:5;:39;;;;;;;;:::i;:::-;;12770:116;;;12830:44;;;;;32964:2:1;12830:44:0;;;32946:21:1;33003:2;32983:18;;;32976:30;33042:34;33022:18;;;33015:62;33113:4;33093:18;;;33086:32;33135:19;;12830:44:0;32762:398:1;12770:116:0;12250:643;:::o;17637:1632::-;17768:7;;18702:66;18689:79;;18685:163;;;-1:-1:-1;18801:1:0;;-1:-1:-1;18805:30:0;18785:51;;18685:163;18862:1;:7;;18867:2;18862:7;;:18;;;;;18873:1;:7;;18878:2;18873:7;;18862:18;18858:102;;;-1:-1:-1;18913:1:0;;-1:-1:-1;18917:30:0;18897:51;;18858:102;19074:24;;;19057:14;19074:24;;;;;;;;;33392:25:1;;;33465:4;33453:17;;33433:18;;;33426:45;;;;33487:18;;;33480:34;;;33530:18;;;33523:34;;;19074:24:0;;33364:19:1;;19074:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;19074:24:0;;;;;;-1:-1:-1;;19113:20:0;;;19109:103;;19166:1;19170:29;19150:50;;;;;;;19109:103;19232:6;-1:-1:-1;19240:20:0;;-1:-1:-1;17637:1632:0;;;;;;;;:::o;16679:344::-;16793:7;;16852:66;16839:80;;16793:7;16946:25;16962:3;16947:18;;;16969:2;16946:25;:::i;:::-;16930:42;;16990:25;17001:4;17007:1;17010;17013;16990:10;:25::i;:::-;16983:32;;;;;;16679:344;;;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;422:154:1;508:42;501:5;497:54;490:5;487:65;477:93;;566:1;563;556:12;581:184;633:77;630:1;623:88;730:4;727:1;720:15;754:4;751:1;744:15;770:253;842:2;836:9;884:4;872:17;;919:18;904:34;;940:22;;;901:62;898:88;;;966:18;;:::i;:::-;1002:2;995:22;770:253;:::o;1028:334::-;1099:2;1093:9;1155:2;1145:13;;1160:66;1141:86;1129:99;;1258:18;1243:34;;1279:22;;;1240:62;1237:88;;;1305:18;;:::i;:::-;1341:2;1334:22;1028:334;;-1:-1:-1;1028:334:1:o;1367:245::-;1415:4;1448:18;1440:6;1437:30;1434:56;;;1470:18;;:::i;:::-;-1:-1:-1;1527:2:1;1515:15;1532:66;1511:88;1601:4;1507:99;;1367:245::o;1617:462::-;1659:5;1712:3;1705:4;1697:6;1693:17;1689:27;1679:55;;1730:1;1727;1720:12;1679:55;1766:6;1753:20;1797:48;1813:31;1841:2;1813:31;:::i;:::-;1797:48;:::i;:::-;1870:2;1861:7;1854:19;1916:3;1909:4;1904:2;1896:6;1892:15;1888:26;1885:35;1882:55;;;1933:1;1930;1923:12;1882:55;1998:2;1991:4;1983:6;1979:17;1972:4;1963:7;1959:18;1946:55;2046:1;2021:16;;;2039:4;2017:27;2010:38;;;;2025:7;1617:462;-1:-1:-1;;;1617:462:1:o;2084:523::-;2170:6;2178;2186;2239:2;2227:9;2218:7;2214:23;2210:32;2207:52;;;2255:1;2252;2245:12;2207:52;2294:9;2281:23;2313:31;2338:5;2313:31;:::i;:::-;2363:5;-1:-1:-1;2415:2:1;2400:18;;2387:32;;-1:-1:-1;2470:2:1;2455:18;;2442:32;2497:18;2486:30;;2483:50;;;2529:1;2526;2519:12;2483:50;2552:49;2593:7;2584:6;2573:9;2569:22;2552:49;:::i;:::-;2542:59;;;2084:523;;;;;:::o;2612:388::-;2680:6;2688;2741:2;2729:9;2720:7;2716:23;2712:32;2709:52;;;2757:1;2754;2747:12;2709:52;2796:9;2783:23;2815:31;2840:5;2815:31;:::i;:::-;2865:5;-1:-1:-1;2922:2:1;2907:18;;2894:32;2935:33;2894:32;2935:33;:::i;:::-;2987:7;2977:17;;;2612:388;;;;;:::o;3197:255::-;3264:6;3317:2;3305:9;3296:7;3292:23;3288:32;3285:52;;;3333:1;3330;3323:12;3285:52;3372:9;3359:23;3391:31;3416:5;3391:31;:::i;3457:180::-;3516:6;3569:2;3557:9;3548:7;3544:23;3540:32;3537:52;;;3585:1;3582;3575:12;3537:52;-1:-1:-1;3608:23:1;;3457:180;-1:-1:-1;3457:180:1:o;3873:315::-;3941:6;3949;4002:2;3990:9;3981:7;3977:23;3973:32;3970:52;;;4018:1;4015;4008:12;3970:52;4057:9;4044:23;4076:31;4101:5;4076:31;:::i;:::-;4126:5;4178:2;4163:18;;;;4150:32;;-1:-1:-1;;;3873:315:1:o;4874:258::-;4946:1;4956:113;4970:6;4967:1;4964:13;4956:113;;;5046:11;;;5040:18;5027:11;;;5020:39;4992:2;4985:10;4956:113;;;5087:6;5084:1;5081:13;5078:48;;;5122:1;5113:6;5108:3;5104:16;5097:27;5078:48;;4874:258;;;:::o;5137:316::-;5178:3;5216:5;5210:12;5243:6;5238:3;5231:19;5259:63;5315:6;5308:4;5303:3;5299:14;5292:4;5285:5;5281:16;5259:63;:::i;:::-;5367:2;5355:15;5372:66;5351:88;5342:98;;;;5442:4;5338:109;;5137:316;-1:-1:-1;;5137:316:1:o;5458:217::-;5605:2;5594:9;5587:21;5568:4;5625:44;5665:2;5654:9;5650:18;5642:6;5625:44;:::i;5680:674::-;5775:6;5783;5791;5844:2;5832:9;5823:7;5819:23;5815:32;5812:52;;;5860:1;5857;5850:12;5812:52;5899:9;5886:23;5918:31;5943:5;5918:31;:::i;:::-;5968:5;-1:-1:-1;6024:2:1;6009:18;;5996:32;6047:18;6077:14;;;6074:34;;;6104:1;6101;6094:12;6074:34;6127:49;6168:7;6159:6;6148:9;6144:22;6127:49;:::i;:::-;6117:59;;6229:2;6218:9;6214:18;6201:32;6185:48;;6258:2;6248:8;6245:16;6242:36;;;6274:1;6271;6264:12;6242:36;;6297:51;6340:7;6329:8;6318:9;6314:24;6297:51;:::i;6615:734::-;6719:6;6727;6735;6743;6751;6804:3;6792:9;6783:7;6779:23;6775:33;6772:53;;;6821:1;6818;6811:12;6772:53;6860:9;6847:23;6879:31;6904:5;6879:31;:::i;:::-;6929:5;-1:-1:-1;6981:2:1;6966:18;;6953:32;;-1:-1:-1;7032:2:1;7017:18;;7004:32;;-1:-1:-1;7088:2:1;7073:18;;7060:32;7101:33;7060:32;7101:33;:::i;:::-;7153:7;-1:-1:-1;7211:3:1;7196:19;;7183:33;7239:18;7228:30;;7225:50;;;7271:1;7268;7261:12;7225:50;7294:49;7335:7;7326:6;7315:9;7311:22;7294:49;:::i;:::-;7284:59;;;6615:734;;;;;;;;:::o;7354:596::-;7440:6;7448;7456;7509:2;7497:9;7488:7;7484:23;7480:32;7477:52;;;7525:1;7522;7515:12;7477:52;7564:9;7551:23;7583:31;7608:5;7583:31;:::i;:::-;7633:5;-1:-1:-1;7690:2:1;7675:18;;7662:32;7703:33;7662:32;7703:33;:::i;:::-;7755:7;-1:-1:-1;7813:2:1;7798:18;;7785:32;7840:18;7829:30;;7826:50;;;7872:1;7869;7862:12;7955:830;8067:6;8075;8083;8091;8099;8107;8160:3;8148:9;8139:7;8135:23;8131:33;8128:53;;;8177:1;8174;8167:12;8128:53;8216:9;8203:23;8235:31;8260:5;8235:31;:::i;:::-;8285:5;-1:-1:-1;8337:2:1;8322:18;;8309:32;;-1:-1:-1;8393:2:1;8378:18;;8365:32;8441:6;8428:20;;8416:33;;8406:61;;8463:1;8460;8453:12;8406:61;8486:7;-1:-1:-1;8540:2:1;8525:18;;8512:32;;-1:-1:-1;8591:3:1;8576:19;;8563:33;;-1:-1:-1;8647:3:1;8632:19;;8619:33;8675:18;8664:30;;8661:50;;;8707:1;8704;8697:12;8661:50;8730:49;8771:7;8762:6;8751:9;8747:22;8730:49;:::i;:::-;8720:59;;;7955:830;;;;;;;;:::o;8790:638::-;8967:2;8956:9;8949:21;9025:42;9016:6;9010:13;9006:62;9001:2;8990:9;8986:18;8979:90;9123:2;9115:6;9111:15;9105:22;9100:2;9089:9;9085:18;9078:50;9192:66;9186:2;9178:6;9174:15;9168:22;9164:95;9159:2;9148:9;9144:18;9137:123;8930:4;9307:2;9299:6;9295:15;9289:22;9349:4;9342;9331:9;9327:20;9320:34;9371:51;9417:3;9406:9;9402:19;9388:12;9371:51;:::i;9683:898::-;9803:6;9811;9819;9827;9835;9843;9896:3;9884:9;9875:7;9871:23;9867:33;9864:53;;;9913:1;9910;9903:12;9864:53;9952:9;9939:23;9971:31;9996:5;9971:31;:::i;:::-;10021:5;-1:-1:-1;10078:2:1;10063:18;;10050:32;10091:33;10050:32;10091:33;:::i;:::-;10143:7;-1:-1:-1;10197:2:1;10182:18;;10169:32;;-1:-1:-1;10253:2:1;10238:18;;10225:32;10266:33;10225:32;10266:33;:::i;:::-;10318:7;-1:-1:-1;10377:3:1;10362:19;;10349:33;10391;10349;10391;:::i;:::-;10443:7;-1:-1:-1;10502:3:1;10487:19;;10474:33;10516;10474;10516;:::i;:::-;10568:7;10558:17;;;9683:898;;;;;;;;:::o;11913:184::-;11983:6;12036:2;12024:9;12015:7;12011:23;12007:32;12004:52;;;12052:1;12049;12042:12;12004:52;-1:-1:-1;12075:16:1;;11913:184;-1:-1:-1;11913:184:1:o;12854:251::-;12924:6;12977:2;12965:9;12956:7;12952:23;12948:32;12945:52;;;12993:1;12990;12983:12;12945:52;13025:9;13019:16;13044:31;13069:5;13044:31;:::i;13471:184::-;13523:77;13520:1;13513:88;13620:4;13617:1;13610:15;13644:4;13641:1;13634:15;14438:184;14490:77;14487:1;14480:88;14587:4;14584:1;14577:15;14611:4;14608:1;14601:15;14627:125;14667:4;14695:1;14692;14689:8;14686:34;;;14700:18;;:::i;:::-;-1:-1:-1;14737:9:1;;14627:125::o;15610:204::-;15648:3;15684:4;15681:1;15677:12;15716:4;15713:1;15709:12;15751:3;15745:4;15741:14;15736:3;15733:23;15730:49;;;15759:18;;:::i;:::-;15795:13;;15610:204;-1:-1:-1;;;15610:204:1:o;15819:175::-;15856:3;15900:4;15893:5;15889:16;15929:4;15920:7;15917:17;15914:43;;;15937:18;;:::i;:::-;15986:1;15973:15;;15819:175;-1:-1:-1;;15819:175:1:o;16410:195::-;16449:3;16480:66;16473:5;16470:77;16467:103;;;16550:18;;:::i;:::-;-1:-1:-1;16597:1:1;16586:13;;16410:195::o;16610:619::-;16823:3;16851:66;16959:2;16950:6;16946:2;16942:15;16938:24;16933:3;16926:37;17014:2;17005:6;17001:2;16997:15;16993:24;16988:2;16983:3;16979:12;16972:46;;17047:6;17041:13;17063:62;17118:6;17113:2;17108:3;17104:12;17097:4;17089:6;17085:17;17063:62;:::i;:::-;17184:2;17144:16;;17176:11;;;17169:27;;;;17220:2;17212:11;;16610:619;-1:-1:-1;;;;16610:619:1:o;17578:437::-;17657:1;17653:12;;;;17700;;;17721:61;;17775:4;17767:6;17763:17;17753:27;;17721:61;17828:2;17820:6;17817:14;17797:18;17794:38;17791:218;;;17865:77;17862:1;17855:88;17966:4;17963:1;17956:15;17994:4;17991:1;17984:15;17791:218;;17578:437;;;:::o;18020:277::-;18087:6;18140:2;18128:9;18119:7;18115:23;18111:32;18108:52;;;18156:1;18153;18146:12;18108:52;18188:9;18182:16;18241:5;18234:13;18227:21;18220:5;18217:32;18207:60;;18263:1;18260;18253:12;19836:128;19876:3;19907:1;19903:6;19900:1;19897:13;19894:39;;;19913:18;;:::i;:::-;-1:-1:-1;19949:9:1;;19836:128::o;20683:438::-;20849:4;20878:42;20959:2;20951:6;20947:15;20936:9;20929:34;21011:2;21003:6;20999:15;20994:2;20983:9;20979:18;20972:43;;21051:2;21046;21035:9;21031:18;21024:30;21071:44;21111:2;21100:9;21096:18;21088:6;21071:44;:::i;24860:337::-;25047:42;25039:6;25035:55;25024:9;25017:74;25127:2;25122;25111:9;25107:18;25100:30;24998:4;25147:44;25187:2;25176:9;25172:18;25164:6;25147:44;:::i;25918:1306::-;26012:6;26043:2;26086;26074:9;26065:7;26061:23;26057:32;26054:52;;;26102:1;26099;26092:12;26054:52;26135:9;26129:16;26164:18;26205:2;26197:6;26194:14;26191:34;;;26221:1;26218;26211:12;26191:34;26244:22;;;;26300:4;26282:16;;;26278:27;26275:47;;;26318:1;26315;26308:12;26275:47;26344:22;;:::i;:::-;26396:2;26390:9;26408:33;26433:7;26408:33;:::i;:::-;26450:22;;26510:11;;;26504:18;26488:14;;;26481:42;26557:2;26549:11;;26543:18;26597:66;26588:76;;26580:85;;26570:113;;26679:1;26676;26669:12;26570:113;26710:2;26699:14;;26692:27;26758:2;26750:11;;26744:18;26774:16;;;26771:36;;;26803:1;26800;26793:12;26771:36;26834:8;26830:2;26826:17;26816:27;;;26881:7;26874:4;26870:2;26866:13;26862:27;26852:55;;26903:1;26900;26893:12;26852:55;26932:2;26926:9;26916:19;;26957:48;26973:31;27001:2;26973:31;:::i;26957:48::-;27028:2;27021:5;27014:17;27068:7;27063:2;27058;27054;27050:11;27046:20;27043:33;27040:53;;;27089:1;27086;27079:12;27040:53;27102:54;27153:2;27148;27141:5;27137:14;27132:2;27128;27124:11;27102:54;:::i;:::-;27183:2;27172:14;;27165:29;27176:5;25918:1306;-1:-1:-1;;;;;;25918:1306:1:o;30075:270::-;30155:6;30208:2;30196:9;30187:7;30183:23;30179:32;30176:52;;;30224:1;30221;30214:12;30176:52;30256:9;30250:16;30295:1;30288:5;30285:12;30275:40;;30311:1;30308;30301:12;30350:184;30402:77;30399:1;30392:88;30499:4;30496:1;30489:15;30523:4;30520:1;30513:15
Swarm Source
ipfs://69ad65a1c8846f78818ebf888ec59c6436211956568469185d7bb5da32a87f73
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|