Source Code
Overview
CELO Balance
CELO Value
$0.00Multichain Info
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
This contract contains unverified libraries: IntegerSortedLinkedList, AddressLinkedList, AddressSortedLinkedList
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:
Accounts
Compiler Version
v0.5.13+commit.5b0b510c
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity ^0.5.13;
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/ownership/Ownable.sol";
import "./interfaces/IAccounts.sol";
import "../common/FixidityLib.sol";
import "../common/Initializable.sol";
import "../common/interfaces/ICeloVersionedContract.sol";
import "../common/Signatures.sol";
import "../common/UsingRegistry.sol";
import "../common/libraries/ReentrancyGuard.sol";
import "../../contracts-0.8/common/IsL2Check.sol";
contract Accounts is
IAccounts,
ICeloVersionedContract,
Ownable,
ReentrancyGuard,
Initializable,
UsingRegistry,
IsL2Check
{
using FixidityLib for FixidityLib.Fraction;
using SafeMath for uint256;
struct Signers {
// The address that is authorized to vote in governance and validator elections on behalf of the
// account. The account can vote as well, whether or not a vote signing key has been specified.
address vote;
// The address that is authorized to manage a validator or validator group and sign consensus
// messages on behalf of the account. The account can manage the validator, whether or not a
// validator signing key has been specified. However, if a validator signing key has been
// specified, only that key may actually participate in consensus.
address validator;
// The address of the key with which this account wants to sign attestations on the Attestations
// contract
address attestation;
}
struct SignerAuthorization {
bool started;
bool completed;
}
struct Account {
bool exists;
// [Deprecated] Each account may authorize signing keys to use for voting,
// validating or attestation. These keys may not be keys of other accounts,
// and may not be authorized by any other account for any purpose.
Signers signers;
// The address at which the account expects to receive transfers. If it's empty/0x0, the
// account indicates that an address exchange should be initiated with the dataEncryptionKey
address walletAddress;
// An optional human readable identifier for the account
string name;
// The ECDSA public key used to encrypt and decrypt data for this account
bytes dataEncryptionKey;
// The URL under which an account adds metadata and claims
string metadataURL;
}
struct PaymentDelegation {
// Address that should receive a fraction of validator payments.
address beneficiary;
// Fraction of payment to delegate to `beneficiary`.
FixidityLib.Fraction fraction;
}
mapping(address => Account) internal accounts;
// Maps authorized signers to the account that provided the authorization.
mapping(address => address) public authorizedBy;
// Default signers by account (replaces the legacy Signers struct on Account)
mapping(address => mapping(bytes32 => address)) defaultSigners;
// All signers and their roles for a given account
// solhint-disable-next-line max-line-length
mapping(address => mapping(bytes32 => mapping(address => SignerAuthorization))) signerAuthorizations;
bytes32 public constant EIP712_AUTHORIZE_SIGNER_TYPEHASH =
keccak256("AuthorizeSigner(address account,address signer,bytes32 role)");
bytes32 public eip712DomainSeparator;
// A per-account list of CIP8 storage roots, bypassing CIP3.
mapping(address => bytes[]) public offchainStorageRoots;
// Optional per-account validator payment delegation information.
mapping(address => PaymentDelegation) internal paymentDelegations;
bytes32 constant ValidatorSigner = keccak256(abi.encodePacked("celo.org/core/validator"));
bytes32 constant AttestationSigner = keccak256(abi.encodePacked("celo.org/core/attestation"));
bytes32 constant VoteSigner = keccak256(abi.encodePacked("celo.org/core/vote"));
event AttestationSignerAuthorized(address indexed account, address signer);
event VoteSignerAuthorized(address indexed account, address signer);
event ValidatorSignerAuthorized(address indexed account, address signer);
event SignerAuthorized(address indexed account, address signer, bytes32 indexed role);
event SignerAuthorizationStarted(address indexed account, address signer, bytes32 indexed role);
event SignerAuthorizationCompleted(address indexed account, address signer, bytes32 indexed role);
event AttestationSignerRemoved(address indexed account, address oldSigner);
event VoteSignerRemoved(address indexed account, address oldSigner);
event ValidatorSignerRemoved(address indexed account, address oldSigner);
event IndexedSignerSet(address indexed account, address signer, bytes32 role);
event IndexedSignerRemoved(address indexed account, address oldSigner, bytes32 role);
event DefaultSignerSet(address indexed account, address signer, bytes32 role);
event DefaultSignerRemoved(address indexed account, address oldSigner, bytes32 role);
event LegacySignerSet(address indexed account, address signer, bytes32 role);
event LegacySignerRemoved(address indexed account, address oldSigner, bytes32 role);
event SignerRemoved(address indexed account, address oldSigner, bytes32 indexed role);
event AccountDataEncryptionKeySet(address indexed account, bytes dataEncryptionKey);
event AccountNameSet(address indexed account, string name);
event AccountMetadataURLSet(address indexed account, string metadataURL);
event AccountWalletAddressSet(address indexed account, address walletAddress);
event AccountCreated(address indexed account);
event OffchainStorageRootAdded(address indexed account, bytes url);
event OffchainStorageRootRemoved(address indexed account, bytes url, uint256 index);
event PaymentDelegationSet(address indexed beneficiary, uint256 fraction);
/**
* @notice Sets initialized == true on implementation contracts
* @param test Set to true to skip implementation initialization
*/
constructor(bool test) public Initializable(test) {}
/**
* @notice Used in place of the constructor to allow the contract to be upgradable via proxy.
* @param registryAddress The address of the registry core smart contract.
*/
function initialize(address registryAddress) external initializer {
_transferOwnership(msg.sender);
setRegistry(registryAddress);
_setEip712DomainSeparator();
}
/**
* @notice Sets the EIP712 domain separator for the Celo Accounts abstraction.
*/
function setEip712DomainSeparator() external {
_setEip712DomainSeparator();
}
/**
* @notice Convenience Setter for the dataEncryptionKey and wallet address for an account
* @param name A string to set as the name of the account
* @param dataEncryptionKey secp256k1 public key for data encryption. Preferably compressed.
* @param walletAddress The wallet address to set for the account
* @param v The recovery id of the incoming ECDSA signature.
* @param r Output value r of the ECDSA signature.
* @param s Output value s of the ECDSA signature.
* @dev v, r, s constitute `signer`'s signature on `msg.sender` (unless the wallet address
* is 0x0 or msg.sender).
*/
function setAccount(
string calldata name,
bytes calldata dataEncryptionKey,
address walletAddress,
uint8 v,
bytes32 r,
bytes32 s
) external {
if (!isAccount(msg.sender)) {
createAccount();
}
setName(name);
setAccountDataEncryptionKey(dataEncryptionKey);
setWalletAddress(walletAddress, v, r, s);
}
/**
* @notice Setter for the metadata of an account.
* @param metadataURL The URL to access the metadata.
*/
function setMetadataURL(string calldata metadataURL) external {
require(isAccount(msg.sender), "Unknown account");
Account storage account = accounts[msg.sender];
account.metadataURL = metadataURL;
emit AccountMetadataURLSet(msg.sender, metadataURL);
}
/**
* @notice Adds a new CIP8 storage root.
* @param url The URL pointing to the offchain storage root.
*/
function addStorageRoot(bytes calldata url) external {
require(isAccount(msg.sender), "Unknown account");
offchainStorageRoots[msg.sender].push(url);
emit OffchainStorageRootAdded(msg.sender, url);
}
/**
* @notice Removes a CIP8 storage root.
* @param index The index of the storage root to be removed in the account's
* list of storage roots.
* @dev The order of storage roots may change after this operation (the last
* storage root will be moved to `index`), be aware of this if removing
* multiple storage roots at a time.
*/
function removeStorageRoot(uint256 index) external {
require(isAccount(msg.sender), "Unknown account");
require(index < offchainStorageRoots[msg.sender].length, "Invalid storage root index");
uint256 lastIndex = offchainStorageRoots[msg.sender].length - 1;
bytes memory url = offchainStorageRoots[msg.sender][index];
offchainStorageRoots[msg.sender][index] = offchainStorageRoots[msg.sender][lastIndex];
offchainStorageRoots[msg.sender].length--;
emit OffchainStorageRootRemoved(msg.sender, url, index);
}
/**
* @notice Authorizes an address to sign votes on behalf of the account.
* @param signer The address of the signing key to authorize.
* @param v The recovery id of the incoming ECDSA signature.
* @param r Output value r of the ECDSA signature.
* @param s Output value s of the ECDSA signature.
* @dev v, r, s constitute `signer`'s signature on `msg.sender`.
*/
function authorizeVoteSigner(
address signer,
uint8 v,
bytes32 r,
bytes32 s
) external nonReentrant {
legacyAuthorizeSignerWithSignature(signer, VoteSigner, v, r, s);
setIndexedSigner(signer, VoteSigner);
emit VoteSignerAuthorized(msg.sender, signer);
}
/**
* @notice Authorizes an address to sign consensus messages on behalf of the account.
* @param signer The address of the signing key to authorize.
* @param v The recovery id of the incoming ECDSA signature.
* @param r Output value r of the ECDSA signature.
* @param s Output value s of the ECDSA signature.
* @dev v, r, s constitute `signer`'s signature on `msg.sender`.
*/
function authorizeValidatorSigner(
address signer,
uint8 v,
bytes32 r,
bytes32 s
) external nonReentrant {
legacyAuthorizeSignerWithSignature(signer, ValidatorSigner, v, r, s);
setIndexedSigner(signer, ValidatorSigner);
require(!getValidators().isValidator(msg.sender), "Cannot authorize validator signer");
emit ValidatorSignerAuthorized(msg.sender, signer);
}
/**
* @notice Authorizes an address to sign consensus messages on behalf of the account.
* @param signer The address of the signing key to authorize.
* @param v The recovery id of the incoming ECDSA signature.
* @param r Output value r of the ECDSA signature.
* @param s Output value s of the ECDSA signature.
* @param ecdsaPublicKey The ECDSA public key corresponding to `signer`.
* @dev v, r, s constitute `signer`'s signature on `msg.sender`.
*/
function authorizeValidatorSignerWithPublicKey(
address signer,
uint8 v,
bytes32 r,
bytes32 s,
bytes calldata ecdsaPublicKey
) external nonReentrant {
legacyAuthorizeSignerWithSignature(signer, ValidatorSigner, v, r, s);
setIndexedSigner(signer, ValidatorSigner);
require(
getValidators().updateEcdsaPublicKey(msg.sender, signer, ecdsaPublicKey),
"Failed to update ECDSA public key"
);
emit ValidatorSignerAuthorized(msg.sender, signer);
}
/**
* @notice Authorizes an address to sign consensus messages on behalf of the account.
* @param signer The address of the signing key to authorize.
* @param ecdsaPublicKey The ECDSA public key corresponding to `signer`.
* @param blsPublicKey The BLS public key that the validator is using for consensus, should pass
* proof of possession. 96 bytes.
* @param blsPop The BLS public key proof-of-possession, which consists of a signature on the
* account address. 48 bytes.
* @param v The recovery id of the incoming ECDSA signature.
* @param r Output value r of the ECDSA signature.
* @param s Output value s of the ECDSA signature.
* @dev v, r, s constitute `signer`'s signature on `msg.sender`.
*/
function authorizeValidatorSignerWithKeys(
address signer,
uint8 v,
bytes32 r,
bytes32 s,
bytes calldata ecdsaPublicKey,
bytes calldata blsPublicKey,
bytes calldata blsPop
) external nonReentrant {
legacyAuthorizeSignerWithSignature(signer, ValidatorSigner, v, r, s);
setIndexedSigner(signer, ValidatorSigner);
require(
getValidators().updatePublicKeys(msg.sender, signer, ecdsaPublicKey, blsPublicKey, blsPop),
"Failed to update validator keys"
);
emit ValidatorSignerAuthorized(msg.sender, signer);
}
/**
* @notice Getter for the metadata of multiple accounts.
* @param accountsToQuery The addresses of the accounts to get the metadata for.
* @return The length of each string in bytes.
* @return All strings concatenated.
*/
function batchGetMetadataURL(
address[] calldata accountsToQuery
) external view returns (uint256[] memory, bytes memory) {
uint256 totalSize = 0;
uint256[] memory sizes = new uint256[](accountsToQuery.length);
for (uint256 i = 0; i < accountsToQuery.length; i = i.add(1)) {
sizes[i] = bytes(accounts[accountsToQuery[i]].metadataURL).length;
totalSize = totalSize.add(sizes[i]);
}
bytes memory data = new bytes(totalSize);
uint256 pointer = 0;
for (uint256 i = 0; i < accountsToQuery.length; i = i.add(1)) {
for (uint256 j = 0; j < sizes[i]; j = j.add(1)) {
data[pointer] = bytes(accounts[accountsToQuery[i]].metadataURL)[j];
pointer = pointer.add(1);
}
}
return (sizes, data);
}
/**
* @notice Returns the full list of offchain storage roots for an account.
* @param account The account whose storage roots to return.
* @return Concatenated storage root URLs.
* @return Lengths of storage root URLs.
*/
function getOffchainStorageRoots(
address account
) external view returns (bytes memory, uint256[] memory) {
require(isAccount(account), "Unknown account");
uint256 numberRoots = offchainStorageRoots[account].length;
uint256 totalLength = 0;
for (uint256 i = 0; i < numberRoots; i++) {
totalLength = totalLength.add(offchainStorageRoots[account][i].length);
}
bytes memory concatenated = new bytes(totalLength);
uint256 lastIndex = 0;
uint256[] memory lengths = new uint256[](numberRoots);
for (uint256 i = 0; i < numberRoots; i++) {
bytes storage root = offchainStorageRoots[account][i];
lengths[i] = root.length;
for (uint256 j = 0; j < lengths[i]; j++) {
concatenated[lastIndex] = root[j];
lastIndex++;
}
}
return (concatenated, lengths);
}
/**
* @notice Gets validator payment delegation settings.
* @param account Account of the validator.
* @return Beneficiary address of payment delegated.
* @return Fraction of payment delegated.
*/
function getPaymentDelegation(address account) external view returns (address, uint256) {
PaymentDelegation storage delegation = paymentDelegations[account];
return (delegation.beneficiary, delegation.fraction.unwrap());
}
/**
* @notice Returns the account associated with `signer`.
* @param signer The address of the account or currently authorized attestation signer.
* @dev Fails if the `signer` is not an account or currently authorized attestation signer.
* @return The associated account that the signer is authorized to attest for.
*/
function attestationSignerToAccount(address signer) external view returns (address) {
return signerToAccountWithRole(signer, AttestationSigner);
}
/**
* @notice Returns the account associated with `signer`.
* @param signer The address of the account or currently authorized vote signer.
* @dev Fails if the `signer` is not an account or currently authorized vote signer.
* @return The associated account that signer is authorized to vote for.
*/
function voteSignerToAccount(address signer) external view returns (address) {
return signerToAccountWithRole(signer, VoteSigner);
}
/**
* @notice Returns the account associated with `signer`.
* @param signer The address of the account or previously authorized signer.
* @dev Fails if the `signer` is not an account or previously authorized signer.
* @return The associated account.
*/
function signerToAccount(address signer) external view returns (address) {
address authorizingAccount = authorizedBy[signer];
if (authorizingAccount != address(0)) {
return authorizingAccount;
} else {
require(isAccount(signer), "Must first register address with Account.createAccount");
return signer;
}
}
/**
* @notice Checks whether or not the account has a signer
* registered for the plaintext role.
* @dev See `hasIndexedSigner` for more gas efficient call.
*/
function hasAuthorizedSigner(address account, string calldata role) external view returns (bool) {
return hasIndexedSigner(account, keccak256(abi.encodePacked(role)));
}
/**
* @notice Returns if account has specified a dedicated vote signer.
* @param account The address of the account.
* @return Whether the account has specified a dedicated vote signer.
*/
function hasAuthorizedVoteSigner(address account) external view returns (bool) {
return hasLegacySigner(account, VoteSigner);
}
/**
* @notice Returns if account has specified a dedicated validator signer.
* @param account The address of the account.
* @return Whether the account has specified a dedicated validator signer.
*/
function hasAuthorizedValidatorSigner(address account) external view returns (bool) {
return hasLegacySigner(account, ValidatorSigner);
}
/**
* @notice Returns if account has specified a dedicated attestation signer.
* @param account The address of the account.
* @return Whether the account has specified a dedicated attestation signer.
*/
function hasAuthorizedAttestationSigner(address account) external view returns (bool) {
return hasLegacySigner(account, AttestationSigner);
}
/**
* @notice Getter for the name of an account.
* @param account The address of the account to get the name for.
* @return name The name of the account.
*/
function getName(address account) external view returns (string memory) {
return accounts[account].name;
}
/**
* @notice Getter for the metadata of an account.
* @param account The address of the account to get the metadata for.
* @return metadataURL The URL to access the metadata.
*/
function getMetadataURL(address account) external view returns (string memory) {
return accounts[account].metadataURL;
}
/**
* @notice Getter for the data encryption key and version.
* @param account The address of the account to get the key for
* @return dataEncryptionKey secp256k1 public key for data encryption. Preferably compressed.
*/
function getDataEncryptionKey(address account) external view returns (bytes memory) {
return accounts[account].dataEncryptionKey;
}
/**
* @notice Getter for the wallet address for an account
* @param account The address of the account to get the wallet address for
* @return Wallet address
*/
function getWalletAddress(address account) external view returns (address) {
return accounts[account].walletAddress;
}
/**
* @notice Check if an address has been an authorized signer for an account.
* @param signer The possibly authorized address.
* @return Returns `true` if authorized. Returns `false` otherwise.
*/
function isAuthorizedSigner(address signer) external view returns (bool) {
return (authorizedBy[signer] != address(0));
}
/**
* @notice Returns the storage, major, minor, and patch version of the contract.
* @return Storage version of the contract.
* @return Major version of the contract.
* @return Minor version of the contract.
* @return Patch version of the contract.
*/
function getVersionNumber() external pure returns (uint256, uint256, uint256, uint256) {
return (1, 1, 4, 2);
}
/**
* @notice Creates an account.
* @return True if account creation succeeded.
*/
function createAccount() public returns (bool) {
require(
isNotAccount(msg.sender) && isNotAuthorizedSigner(msg.sender),
"Account already exists or address is an authorized signer for another account"
);
Account storage account = accounts[msg.sender];
account.exists = true;
emit AccountCreated(msg.sender);
return true;
}
/**
* @notice Setter for the name of an account.
* @param name The name to set.
*/
function setName(string memory name) public {
require(isAccount(msg.sender), "Register with createAccount to set account name");
Account storage account = accounts[msg.sender];
account.name = name;
emit AccountNameSet(msg.sender, name);
}
/**
* @notice Setter for the wallet address for an account
* @param walletAddress The wallet address to set for the account
* @param v The recovery id of the incoming ECDSA signature.
* @param r Output value r of the ECDSA signature.
* @param s Output value s of the ECDSA signature.
* @dev Wallet address can be zero. This means that the owner of the wallet
* does not want to be paid directly without interaction, and instead wants users to
* contact them, using the data encryption key, and arrange a payment.
* @dev v, r, s constitute `signer`'s signature on `msg.sender` (unless the wallet address
* is 0x0 or msg.sender).
*/
function setWalletAddress(address walletAddress, uint8 v, bytes32 r, bytes32 s) public {
require(isAccount(msg.sender), "Unknown account");
if (!(walletAddress == msg.sender || walletAddress == address(0x0))) {
address signer = Signatures.getSignerOfAddress(msg.sender, v, r, s);
require(signer == walletAddress, "Invalid signature");
}
Account storage account = accounts[msg.sender];
account.walletAddress = walletAddress;
emit AccountWalletAddressSet(msg.sender, walletAddress);
}
/**
* @notice Setter for the data encryption key and version.
* @param dataEncryptionKey secp256k1 public key for data encryption. Preferably compressed.
*/
function setAccountDataEncryptionKey(bytes memory dataEncryptionKey) public {
require(dataEncryptionKey.length >= 33, "data encryption key length <= 32");
Account storage account = accounts[msg.sender];
account.dataEncryptionKey = dataEncryptionKey;
emit AccountDataEncryptionKeySet(msg.sender, dataEncryptionKey);
}
/**
* @notice Sets validator payment delegation settings.
* @param beneficiary The address that should receive a portion of validator
* payments.
* @param fraction The fraction of the validator's payment that should be
* diverted to `beneficiary` every epoch, given as FixidityLib value. Must not
* be greater than 1.
* @dev Use `deletePaymentDelegation` to unset the payment delegation.
*/
function setPaymentDelegation(address beneficiary, uint256 fraction) public {
require(isAccount(msg.sender), "Must first register address with Account.createAccount");
require(beneficiary != address(0), "Beneficiary cannot be address 0x0");
FixidityLib.Fraction memory f = FixidityLib.wrap(fraction);
require(f.lte(FixidityLib.fixed1()), "Fraction must not be greater than 1");
paymentDelegations[msg.sender] = PaymentDelegation(beneficiary, f);
emit PaymentDelegationSet(beneficiary, fraction);
}
/**
* @notice Removes a validator's payment delegation by setting benficiary and
* fraction to 0.
*/
function deletePaymentDelegation() public {
require(isAccount(msg.sender), "Must first register address with Account.createAccount");
paymentDelegations[msg.sender] = PaymentDelegation(address(0x0), FixidityLib.wrap(0));
emit PaymentDelegationSet(address(0x0), 0);
}
/**
* @notice Set the indexed signer for a specific role
* @param signer the address to set as default
* @param role the role to register a default signer for
*/
function setIndexedSigner(address signer, bytes32 role) public {
require(isAccount(msg.sender), "Must first register address with Account.createAccount");
require(isNotAccount(signer), "Cannot authorize account as signer");
require(
isNotAuthorizedSignerForAnotherAccount(msg.sender, signer),
"Not a signer for this account"
);
require(isSigner(msg.sender, signer, role), "Must authorize signer before setting as default");
Account storage account = accounts[msg.sender];
if (isLegacyRole(role)) {
if (role == VoteSigner) {
account.signers.vote = signer;
} else if (role == AttestationSigner) {
account.signers.attestation = signer;
} else if (role == ValidatorSigner) {
account.signers.validator = signer;
}
emit LegacySignerSet(msg.sender, signer, role);
} else {
defaultSigners[msg.sender][role] = signer;
emit DefaultSignerSet(msg.sender, signer, role);
}
emit IndexedSignerSet(msg.sender, signer, role);
}
/**
* @notice Authorizes an address to act as a signer, for `role`, on behalf of the account.
* @param signer The address of the signing key to authorize.
* @param role The role to authorize signing for.
* @param v The recovery id of the incoming ECDSA signature.
* @param r Output value r of the ECDSA signature.
* @param s Output value s of the ECDSA signature.
* @dev v, r, s constitute `signer`'s EIP712 signature over `role`, `msg.sender`
* and `signer`.
*/
function authorizeSignerWithSignature(
address signer,
bytes32 role,
uint8 v,
bytes32 r,
bytes32 s
) public {
authorizeAddressWithRole(signer, role, v, r, s);
signerAuthorizations[msg.sender][role][signer] = SignerAuthorization({
started: true,
completed: true
});
emit SignerAuthorized(msg.sender, signer, role);
}
/**
* @notice Authorizes an address to sign attestations on behalf of the account.
* @param signer The address of the signing key to authorize.
* @param v The recovery id of the incoming ECDSA signature.
* @param r Output value r of the ECDSA signature.
* @param s Output value s of the ECDSA signature.
* @dev v, r, s constitute `signer`'s signature on `msg.sender`.
*/
function authorizeAttestationSigner(address signer, uint8 v, bytes32 r, bytes32 s) public {
legacyAuthorizeSignerWithSignature(signer, AttestationSigner, v, r, s);
setIndexedSigner(signer, AttestationSigner);
emit AttestationSignerAuthorized(msg.sender, signer);
}
/**
* @notice Begin the process of authorizing an address to sign on behalf of the account
* @param signer The address of the signing key to authorize.
* @param role The role to authorize signing for.
*/
function authorizeSigner(address signer, bytes32 role) public {
require(isAccount(msg.sender), "Must first register sender with Account.createAccount");
require(
isNotAccount(signer) && isNotAuthorizedSignerForAnotherAccount(msg.sender, signer),
"Cannot re-authorize address signer"
);
signerAuthorizations[msg.sender][role][signer] = SignerAuthorization({
started: true,
completed: false
});
emit SignerAuthorizationStarted(msg.sender, signer, role);
}
/**
* @notice Finish the process of authorizing an address to sign on behalf of the account.
* @param account The address of account that authorized signing.
* @param role The role to finish authorizing for.
*/
function completeSignerAuthorization(address account, bytes32 role) public {
require(
isAccount(account),
"Unknown Account: Address that authorized signing must be a registered Account"
);
require(
isNotAccount(msg.sender) && isNotAuthorizedSignerForAnotherAccount(account, msg.sender),
"Cannot re-authorize address signer"
);
require(
signerAuthorizations[account][role][msg.sender].started == true,
"Signer authorization not started"
);
authorizedBy[msg.sender] = account;
signerAuthorizations[account][role][msg.sender].completed = true;
emit SignerAuthorizationCompleted(account, msg.sender, role);
}
/**
* @notice Removes the signer for a default role.
* @param role The role that has been authorized.
*/
function removeDefaultSigner(bytes32 role) public {
address signer = defaultSigners[msg.sender][role];
defaultSigners[msg.sender][role] = address(0);
emit DefaultSignerRemoved(msg.sender, signer, role);
}
/**
* @notice Removes the currently authorized and indexed signer
* for a specific role
* @param role The role of the signer.
*/
function removeIndexedSigner(bytes32 role) public {
address oldSigner = getIndexedSigner(msg.sender, role);
isLegacyRole(role) ? removeLegacySigner(role) : removeDefaultSigner(role);
emit IndexedSignerRemoved(msg.sender, oldSigner, role);
}
/**
* @notice Removes the currently authorized signer for a specific role and
* if the signer is indexed, remove that as well.
* @param signer The address of the signer.
* @param role The role that has been authorized.
*/
function removeSigner(address signer, bytes32 role) public {
if (isIndexedSigner(msg.sender, signer, role)) {
removeIndexedSigner(role);
}
delete signerAuthorizations[msg.sender][role][signer];
emit SignerRemoved(msg.sender, signer, role);
}
/**
* @notice Removes the currently authorized vote signer for the account.
* Note that the signers cannot be reauthorized after they have been removed.
*/
function removeVoteSigner() public {
address signer = getLegacySigner(msg.sender, VoteSigner);
removeSigner(signer, VoteSigner);
emit VoteSignerRemoved(msg.sender, signer);
}
/**
* @notice Removes the currently authorized validator signer for the account
* Note that the signers cannot be reauthorized after they have been removed.
*/
function removeValidatorSigner() public {
address signer = getLegacySigner(msg.sender, ValidatorSigner);
removeSigner(signer, ValidatorSigner);
emit ValidatorSignerRemoved(msg.sender, signer);
}
/**
* @notice Removes the currently authorized attestation signer for the account
* Note that the signers cannot be reauthorized after they have been removed.
*/
function removeAttestationSigner() public {
address signer = getLegacySigner(msg.sender, AttestationSigner);
removeSigner(signer, AttestationSigner);
emit AttestationSignerRemoved(msg.sender, signer);
}
/**
* @notice Whether or not the signer has been registered as the legacy signer for role
* @param _account The address of account that authorized signing.
* @param signer The address of the signer.
* @param role The role that has been authorized.
*/
function isLegacySigner(
address _account,
address signer,
bytes32 role
) public view returns (bool) {
Account storage account = accounts[_account];
if (role == ValidatorSigner && account.signers.validator == signer) {
return true;
} else if (role == AttestationSigner && account.signers.attestation == signer) {
return true;
} else if (role == VoteSigner && account.signers.vote == signer) {
return true;
} else {
return false;
}
}
/**
* @notice Whether or not the signer has been registered as the default signer for role
* @param account The address of account that authorized signing.
* @param signer The address of the signer.
* @param role The role that has been authorized.
*/
function isDefaultSigner(
address account,
address signer,
bytes32 role
) public view returns (bool) {
return defaultSigners[account][role] == signer;
}
/**
* @notice Whether or not the signer has been registered as an indexed signer for role
* @param account The address of account that authorized signing.
* @param signer The address of the signer.
* @param role The role that has been authorized.
*/
function isIndexedSigner(
address account,
address signer,
bytes32 role
) public view returns (bool) {
return
isLegacyRole(role)
? isLegacySigner(account, signer, role)
: isDefaultSigner(account, signer, role);
}
/**
* @notice Whether or not the signer has been registered as a signer for role
* @param account The address of account that authorized signing.
* @param signer The address of the signer.
* @param role The role that has been authorized.
*/
function isSigner(address account, address signer, bytes32 role) public view returns (bool) {
return
isLegacySigner(account, signer, role) ||
(signerAuthorizations[account][role][signer].completed && authorizedBy[signer] == account);
}
/**
* @notice Returns the account associated with `signer`.
* @param signer The address of an account or currently authorized validator signer.
* @dev Fails if the `signer` is not an account or currently authorized validator.
* @return The associated account that signer is authorized to validate for.
*/
function validatorSignerToAccount(address signer) public view returns (address) {
return signerToAccountWithRole(signer, ValidatorSigner);
}
/**
* @notice Returns the legacy signer for the specified account and
* role. If no signer has been specified it will return the account itself.
* @param _account The address of the account.
* @param role The role of the signer.
*/
function getLegacySigner(address _account, bytes32 role) public view returns (address) {
require(isLegacyRole(role), "Role is not a legacy signer");
Account storage account = accounts[_account];
address signer;
if (role == ValidatorSigner) {
signer = account.signers.validator;
} else if (role == AttestationSigner) {
signer = account.signers.attestation;
} else if (role == VoteSigner) {
signer = account.signers.vote;
}
return signer == address(0) ? _account : signer;
}
/**
* @notice Returns the default signer for the specified account and
* role. If no signer has been specified it will return the account itself.
* @param account The address of the account.
* @param role The role of the signer.
*/
function getDefaultSigner(address account, bytes32 role) public view returns (address) {
address defaultSigner = defaultSigners[account][role];
return defaultSigner == address(0) ? account : defaultSigner;
}
/**
* @notice Returns the indexed signer for the specified account and role.
* If no signer has been specified it will return the account itself.
* @param account The address of the account.
* @param role The role of the signer.
*/
function getIndexedSigner(address account, bytes32 role) public view returns (address) {
return isLegacyRole(role) ? getLegacySigner(account, role) : getDefaultSigner(account, role);
}
/**
* @notice Returns the vote signer for the specified account.
* @param account The address of the account.
* @return The address with which the account can sign votes.
*/
function getVoteSigner(address account) public view returns (address) {
return getLegacySigner(account, VoteSigner);
}
/**
* @notice Returns the validator signer for the specified account.
* @param account The address of the account.
* @return The address with which the account can register a validator or group.
*/
function getValidatorSigner(address account) public view returns (address) {
return getLegacySigner(account, ValidatorSigner);
}
/**
* @notice Returns the attestation signer for the specified account.
* @param account The address of the account.
* @return The address with which the account can sign attestations.
*/
function getAttestationSigner(address account) public view returns (address) {
return getLegacySigner(account, AttestationSigner);
}
/**
* @notice Checks whether or not the account has an indexed signer
* registered for one of the legacy roles
*/
function hasLegacySigner(address account, bytes32 role) public view returns (bool) {
return getLegacySigner(account, role) != account;
}
/**
* @notice Checks whether or not the account has an indexed signer
* registered for a role
*/
function hasDefaultSigner(address account, bytes32 role) public view returns (bool) {
return getDefaultSigner(account, role) != account;
}
/**
* @notice Checks whether or not the account has an indexed signer
* registered for the role
*/
function hasIndexedSigner(address account, bytes32 role) public view returns (bool) {
return isLegacyRole(role) ? hasLegacySigner(account, role) : hasDefaultSigner(account, role);
}
/**
* @notice Check if an account already exists.
* @param account The address of the account
* @return Returns `true` if account exists. Returns `false` otherwise.
*/
function isAccount(address account) public view returns (bool) {
return (accounts[account].exists);
}
/**
* @notice Returns the address that signed the provided role authorization.
* @param account The `account` property signed over in the EIP712 signature
* @param signer The `signer` property signed over in the EIP712 signature
* @param role The `role` property signed over in the EIP712 signature
* @param v The recovery id of the incoming ECDSA signature.
* @param r Output value r of the ECDSA signature.
* @param s Output value s of the ECDSA signature.
* @return The address that signed the provided role authorization.
*/
function getRoleAuthorizationSigner(
address account,
address signer,
bytes32 role,
uint8 v,
bytes32 r,
bytes32 s
) public view returns (address) {
bytes32 structHash = keccak256(
abi.encode(EIP712_AUTHORIZE_SIGNER_TYPEHASH, account, signer, role)
);
return Signatures.getSignerOfTypedDataHash(eip712DomainSeparator, structHash, v, r, s);
}
/**
* @notice Checks whether the role is one of Vote, Validator or Attestation
* @param role The role to check
*/
function isLegacyRole(bytes32 role) public pure returns (bool) {
return role == VoteSigner || role == ValidatorSigner || role == AttestationSigner;
}
/**
* @notice Sets the EIP712 domain separator for the Celo Accounts abstraction.
*/
function _setEip712DomainSeparator() internal {
uint256 chainId;
assembly {
chainId := chainid
}
eip712DomainSeparator = keccak256(
abi.encode(
keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
),
keccak256(bytes("Celo Core Contracts")),
keccak256("1.0"),
chainId,
address(this)
)
);
}
/**
* @notice Check if an account already exists.
* @param account The address of the account
* @return Returns `false` if account exists. Returns `true` otherwise.
*/
function isNotAccount(address account) internal view returns (bool) {
return (!accounts[account].exists);
}
/**
* @notice Check if an address has not been an authorized signer for an account.
* @param signer The possibly authorized address.
* @return Returns `false` if authorized. Returns `true` otherwise.
*/
function isNotAuthorizedSigner(address signer) internal view returns (bool) {
return (authorizedBy[signer] == address(0));
}
/**
* @notice Check if `signer` has not been authorized, and if it has been previously
* authorized that it was authorized by `account`.
* @param account The authorizing account address.
* @param signer The possibly authorized address.
* @return Returns `false` if authorized. Returns `true` otherwise.
*/
function isNotAuthorizedSignerForAnotherAccount(
address account,
address signer
) internal view returns (bool) {
return (authorizedBy[signer] == address(0) || authorizedBy[signer] == account);
}
function signerToAccountWithRole(address signer, bytes32 role) internal view returns (address) {
address account = authorizedBy[signer];
if (account != address(0)) {
require(isSigner(account, signer, role), "not active authorized signer for role");
return account;
}
require(isAccount(signer), "Must first register address with Account.createAccount");
return signer;
}
function legacyAuthorizeSignerWithSignature(
address signer,
bytes32 role,
uint8 v,
bytes32 r,
bytes32 s
) private {
authorizeAddress(signer, v, r, s);
signerAuthorizations[msg.sender][role][signer] = SignerAuthorization({
started: true,
completed: true
});
emit SignerAuthorized(msg.sender, signer, role);
}
/**
* @notice Remove one of the Validator, Attestation or
* Vote signers from an account. Should only be called from
* methods that check the role is a legacy signer.
* @param role The role that has been authorized.
*/
function removeLegacySigner(bytes32 role) private {
Account storage account = accounts[msg.sender];
address signer;
if (role == ValidatorSigner) {
signer = account.signers.validator;
account.signers.validator = address(0);
} else if (role == AttestationSigner) {
signer = account.signers.attestation;
account.signers.attestation = address(0);
} else if (role == VoteSigner) {
signer = account.signers.vote;
account.signers.vote = address(0);
}
emit LegacySignerRemoved(msg.sender, signer, role);
}
/**
* @notice Authorizes some role of `msg.sender`'s account to another address.
* @param authorized The address to authorize.
* @param v The recovery id of the incoming ECDSA signature.
* @param r Output value r of the ECDSA signature.
* @param s Output value s of the ECDSA signature.
* @dev Fails if the address is already authorized to another account or is an account itself.
* @dev Note that once an address is authorized, it may never be authorized again.
* @dev v, r, s constitute `authorized`'s signature on `msg.sender`.
*/
function authorizeAddress(address authorized, uint8 v, bytes32 r, bytes32 s) private {
address signer = Signatures.getSignerOfAddress(msg.sender, v, r, s);
require(signer == authorized, "Invalid signature");
authorize(authorized);
}
/**
* @notice Authorizes a role of `msg.sender`'s account to another address (`authorized`).
* @param authorized The address to authorize.
* @param role The role to authorize.
* @param v The recovery id of the incoming ECDSA signature.
* @param r Output value r of the ECDSA signature.
* @param s Output value s of the ECDSA signature.
* @dev Fails if the address is already authorized to another account or is an account itself.
* @dev Note that this signature is EIP712 compliant over the authorizing `account`
* (`msg.sender`), `signer` (`authorized`) and `role`.
*/
function authorizeAddressWithRole(
address authorized,
bytes32 role,
uint8 v,
bytes32 r,
bytes32 s
) private {
address signer = getRoleAuthorizationSigner(msg.sender, authorized, role, v, r, s);
require(signer == authorized, "Invalid signature");
authorize(authorized);
}
/**
* @notice Authorizes an address to `msg.sender`'s account
* @param authorized The address to authorize.
* @dev Fails if the address is already authorized for another account or is an account itself.
*/
function authorize(address authorized) private {
require(
isAccount(msg.sender),
"Unknown account: sender must register with createAccount first"
);
require(
isNotAccount(authorized) && isNotAuthorizedSignerForAnotherAccount(msg.sender, authorized),
"Cannot re-authorize address or locked gold account for another account"
);
authorizedBy[authorized] = msg.sender;
}
}pragma solidity ^0.5.13;
/**
* @title This interface describes the functions specific to Celo Stable Tokens, and in the
* absence of interface inheritance is intended as a companion to IERC20.sol and ICeloToken.sol.
*/
interface IStableToken {
function mint(address, uint256) external returns (bool);
function burn(uint256) external returns (bool);
function setInflationParameters(uint256, uint256) external;
function valueToUnits(uint256) external view returns (uint256);
function unitsToValue(uint256) external view returns (uint256);
function getInflationParameters()
external
view
returns (
uint256,
uint256,
uint256,
uint256
);
// NOTE: duplicated with IERC20.sol, remove once interface inheritance is supported.
function balanceOf(address) external view returns (uint256);
}pragma solidity ^0.5.13;
interface IReserve {
function setTobinTaxStalenessThreshold(uint256) external;
function addToken(address) external returns (bool);
function removeToken(address, uint256) external returns (bool);
function transferGold(address payable, uint256) external returns (bool);
function transferExchangeGold(address payable, uint256) external returns (bool);
function getReserveGoldBalance() external view returns (uint256);
function getUnfrozenReserveGoldBalance() external view returns (uint256);
function getOrComputeTobinTax() external returns (uint256, uint256);
function getTokens() external view returns (address[] memory);
function getReserveRatio() external view returns (uint256);
function addExchangeSpender(address) external;
function removeExchangeSpender(address, uint256) external;
function addSpender(address) external;
function removeSpender(address) external;
}pragma solidity ^0.5.13;
interface IExchange {
function buy(
uint256,
uint256,
bool
) external returns (uint256);
function sell(
uint256,
uint256,
bool
) external returns (uint256);
function exchange(
uint256,
uint256,
bool
) external returns (uint256);
function setUpdateFrequency(uint256) external;
function getBuyTokenAmount(uint256, bool) external view returns (uint256);
function getSellTokenAmount(uint256, bool) external view returns (uint256);
function getBuyAndSellBuckets(bool) external view returns (uint256, uint256);
}// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.5.13 <0.9.0;
interface ISortedOracles {
function addOracle(address, address) external;
function removeOracle(address, address, uint256) external;
function report(address, uint256, address, address) external;
function removeExpiredReports(address, uint256) external;
function isOldestReportExpired(address token) external view returns (bool, address);
function numRates(address) external view returns (uint256);
function medianRate(address) external view returns (uint256, uint256);
function numTimestamps(address) external view returns (uint256);
function medianTimestamp(address) external view returns (uint256);
}// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.5.13 <0.9.0;
interface IRandom {
function revealAndCommit(bytes32, bytes32, address) external;
function randomnessBlockRetentionWindow() external view returns (uint256);
function random() external view returns (bytes32);
function getBlockRandomness(uint256) external view returns (bytes32);
}// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.5.13 <0.9.0;
interface IAttestations {
function revoke(bytes32, uint256) external;
function withdraw(address) external;
// only owner
function setAttestationRequestFee(address, uint256) external;
function setAttestationExpiryBlocks(uint256) external;
function setSelectIssuersWaitBlocks(uint256) external;
function setMaxAttestations(uint256) external;
// view functions
function getUnselectedRequest(bytes32, address) external view returns (uint32, uint32, address);
function getAttestationIssuers(bytes32, address) external view returns (address[] memory);
function getAttestationStats(bytes32, address) external view returns (uint32, uint32);
function batchGetAttestationStats(
bytes32[] calldata
) external view returns (uint256[] memory, address[] memory, uint64[] memory, uint64[] memory);
function getAttestationState(
bytes32,
address,
address
) external view returns (uint8, uint32, address);
function getCompletableAttestations(
bytes32,
address
) external view returns (uint32[] memory, address[] memory, uint256[] memory, bytes memory);
function getAttestationRequestFee(address) external view returns (uint256);
function getMaxAttestations() external view returns (uint256);
function validateAttestationCode(
bytes32,
address,
uint8,
bytes32,
bytes32
) external view returns (address);
function lookupAccountsForIdentifier(bytes32) external view returns (address[] memory);
function requireNAttestationsRequested(bytes32, address, uint32) external view;
}// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.5.13 <0.9.0;
interface IValidators {
function registerValidator(
bytes calldata,
bytes calldata,
bytes calldata
) external returns (bool);
function registerValidatorNoBls(bytes calldata ecdsaPublicKey) external returns (bool);
function deregisterValidator(uint256) external returns (bool);
function affiliate(address) external returns (bool);
function deaffiliate() external returns (bool);
function updateBlsPublicKey(bytes calldata, bytes calldata) external returns (bool);
function registerValidatorGroup(uint256) external returns (bool);
function deregisterValidatorGroup(uint256) external returns (bool);
function addMember(address) external returns (bool);
function addFirstMember(address, address, address) external returns (bool);
function removeMember(address) external returns (bool);
function reorderMember(address, address, address) external returns (bool);
function updateCommission() external;
function setNextCommissionUpdate(uint256) external;
function resetSlashingMultiplier() external;
// only owner
function setCommissionUpdateDelay(uint256) external;
function setMaxGroupSize(uint256) external returns (bool);
function setMembershipHistoryLength(uint256) external returns (bool);
function setValidatorScoreParameters(uint256, uint256) external returns (bool);
function setGroupLockedGoldRequirements(uint256, uint256) external returns (bool);
function setValidatorLockedGoldRequirements(uint256, uint256) external returns (bool);
function setSlashingMultiplierResetPeriod(uint256) external;
function setDowntimeGracePeriod(uint256 value) external;
// only registered contract
function updateEcdsaPublicKey(address, address, bytes calldata) external returns (bool);
function updatePublicKeys(
address,
address,
bytes calldata,
bytes calldata,
bytes calldata
) external returns (bool);
function mintStableToEpochManager(uint256 amount) external;
// only VM
function updateValidatorScoreFromSigner(address, uint256) external;
function distributeEpochPaymentsFromSigner(address, uint256) external returns (uint256);
// only slasher
function forceDeaffiliateIfValidator(address) external;
function halveSlashingMultiplier(address) external;
// view functions
function maxGroupSize() external view returns (uint256);
function downtimeGracePeriod() external view returns (uint256);
function getCommissionUpdateDelay() external view returns (uint256);
function getValidatorScoreParameters() external view returns (uint256, uint256);
function getMembershipHistory(
address
) external view returns (uint256[] memory, address[] memory, uint256, uint256);
function calculateEpochScore(uint256) external view returns (uint256);
function calculateGroupEpochScore(uint256[] calldata) external view returns (uint256);
function getAccountLockedGoldRequirement(address) external view returns (uint256);
function meetsAccountLockedGoldRequirements(address) external view returns (bool);
function getValidatorBlsPublicKeyFromSigner(address) external view returns (bytes memory);
function getValidator(
address account
) external view returns (bytes memory, bytes memory, address, uint256, address);
function getValidatorsGroup(address account) external view returns (address affiliation);
function getValidatorGroup(
address
)
external
view
returns (address[] memory, uint256, uint256, uint256, uint256[] memory, uint256, uint256);
function getGroupNumMembers(address) external view returns (uint256);
function getTopGroupValidators(address, uint256) external view returns (address[] memory);
function getTopGroupValidatorsAccounts(address, uint256) external view returns (address[] memory);
function getGroupsNumMembers(
address[] calldata accounts
) external view returns (uint256[] memory);
function getNumRegisteredValidators() external view returns (uint256);
function groupMembershipInEpoch(address, uint256, uint256) external view returns (address);
function getValidatorLockedGoldRequirements() external view returns (uint256, uint256);
function getGroupLockedGoldRequirements() external view returns (uint256, uint256);
function getRegisteredValidators() external view returns (address[] memory);
function getRegisteredValidatorGroups() external view returns (address[] memory);
function isValidatorGroup(address) external view returns (bool);
function isValidator(address) external view returns (bool);
function getValidatorGroupSlashingMultiplier(address) external view returns (uint256);
function getMembershipInLastEpoch(address) external view returns (address);
function getMembershipInLastEpochFromSigner(address) external view returns (address);
function computeEpochReward(
address account,
uint256 score,
uint256 maxPayment
) external view returns (uint256);
function getMembershipHistoryLength() external view returns (uint256);
}// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.5.13 <0.9.0;
interface ILockedGold {
function lock() external payable;
function incrementNonvotingAccountBalance(address, uint256) external;
function decrementNonvotingAccountBalance(address, uint256) external;
function unlock(uint256) external;
function relock(uint256, uint256) external;
function withdraw(uint256) external;
function slash(
address account,
uint256 penalty,
address reporter,
uint256 reward,
address[] calldata lessers,
address[] calldata greaters,
uint256[] calldata indices
) external;
function addSlasher(string calldata slasherIdentifier) external;
function getAccountTotalLockedGold(address) external view returns (uint256);
function getTotalLockedGold() external view returns (uint256);
function getPendingWithdrawals(
address
) external view returns (uint256[] memory, uint256[] memory);
function getPendingWithdrawal(
address account,
uint256 index
) external view returns (uint256, uint256);
function getTotalPendingWithdrawals(address) external view returns (uint256);
function isSlasher(address) external view returns (bool);
function getAccountTotalDelegatedFraction(address account) external view returns (uint256);
function getAccountTotalGovernanceVotingPower(address account) external view returns (uint256);
function unlockingPeriod() external view returns (uint256);
function getAccountNonvotingLockedGold(address account) external view returns (uint256);
}// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.5.13 <0.9.0;
interface ILockedCelo {
function lock() external payable;
function incrementNonvotingAccountBalance(address, uint256) external;
function decrementNonvotingAccountBalance(address, uint256) external;
function unlock(uint256) external;
function relock(uint256, uint256) external;
function withdraw(uint256) external;
function slash(
address account,
uint256 penalty,
address reporter,
uint256 reward,
address[] calldata lessers,
address[] calldata greaters,
uint256[] calldata indices
) external;
function addSlasher(string calldata slasherIdentifier) external;
function getAccountNonvotingLockedGold(address account) external view returns (uint256);
function getAccountTotalLockedCelo(address) external view returns (uint256);
function getTotalLockedCelo() external view returns (uint256);
function getPendingWithdrawals(
address
) external view returns (uint256[] memory, uint256[] memory);
function getPendingWithdrawal(
address account,
uint256 index
) external view returns (uint256, uint256);
function getTotalPendingWithdrawals(address) external view returns (uint256);
function isSlasher(address) external view returns (bool);
function getAccountTotalDelegatedFraction(address account) external view returns (uint256);
function getAccountTotalGovernanceVotingPower(address account) external view returns (uint256);
function unlockingPeriod() external view returns (uint256);
function getAccountNonvotingLockedCelo(address account) external view returns (uint256);
}// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.5.13 <0.9.0;
interface IGovernance {
function removeVotesWhenRevokingDelegatedVotes(
address account,
uint256 maxAmountAllowed
) external;
function votePartially(
uint256 proposalId,
uint256 index,
uint256 yesVotes,
uint256 noVotes,
uint256 abstainVotes
) external returns (bool);
function setConstitution(address destination, bytes4 functionId, uint256 threshold) external;
function isVoting(address) external view returns (bool);
function getAmountOfGoldUsedForVoting(address account) external view returns (uint256);
function getProposal(
uint256 proposalId
) external view returns (address, uint256, uint256, uint256, string memory, uint256, bool);
function getReferendumStageDuration() external view returns (uint256);
}// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.5.13 <0.9.0;
interface IEpochRewards {
function updateTargetVotingYield() external;
function isReserveLow() external view returns (bool);
function calculateTargetEpochRewards() external view returns (uint256, uint256, uint256, uint256);
function getTargetVotingYieldParameters() external view returns (uint256, uint256, uint256);
function getRewardsMultiplierParameters() external view returns (uint256, uint256, uint256);
function getCommunityRewardFraction() external view returns (uint256);
function getCarbonOffsettingFraction() external view returns (uint256);
function getTargetVotingGoldFraction() external view returns (uint256);
function getRewardsMultiplier() external view returns (uint256);
function carbonOffsettingPartner() external view returns (address);
}// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.5.13 <0.9.0;
interface IElection {
function vote(address, uint256, address, address) external returns (bool);
function activate(address) external returns (bool);
function revokeActive(address, uint256, address, address, uint256) external returns (bool);
function revokeAllActive(address, address, address, uint256) external returns (bool);
function revokePending(address, uint256, address, address, uint256) external returns (bool);
function markGroupIneligible(address) external;
function markGroupEligible(address, address, address) external;
function allowedToVoteOverMaxNumberOfGroups(address) external returns (bool);
function forceDecrementVotes(
address,
uint256,
address[] calldata,
address[] calldata,
uint256[] calldata
) external returns (uint256);
function setAllowedToVoteOverMaxNumberOfGroups(bool flag) external;
// only owner
function setElectableValidators(uint256, uint256) external returns (bool);
function setMaxNumGroupsVotedFor(uint256) external returns (bool);
function setElectabilityThreshold(uint256) external returns (bool);
// only VM
function distributeEpochRewards(address, uint256, address, address) external;
// view functions
function electValidatorSigners() external view returns (address[] memory);
function electValidatorAccounts() external view returns (address[] memory);
function electNValidatorSigners(uint256, uint256) external view returns (address[] memory);
function electNValidatorAccounts(uint256, uint256) external view returns (address[] memory);
function getElectableValidators() external view returns (uint256, uint256);
function getElectabilityThreshold() external view returns (uint256);
function getNumVotesReceivable(address) external view returns (uint256);
function getTotalVotes() external view returns (uint256);
function getActiveVotes() external view returns (uint256);
function getTotalVotesByAccount(address) external view returns (uint256);
function getPendingVotesForGroupByAccount(address, address) external view returns (uint256);
function getActiveVotesForGroupByAccount(address, address) external view returns (uint256);
function getTotalVotesForGroupByAccount(address, address) external view returns (uint256);
function getActiveVoteUnitsForGroupByAccount(address, address) external view returns (uint256);
function getTotalVotesForGroup(address) external view returns (uint256);
function getActiveVotesForGroup(address) external view returns (uint256);
function getPendingVotesForGroup(address) external view returns (uint256);
function getGroupEligibility(address) external view returns (bool);
function getGroupEpochRewards(
address,
uint256,
uint256[] calldata
) external view returns (uint256);
function getGroupEpochRewardsBasedOnScore(
address group,
uint256 totalEpochRewards,
uint256 groupScore
) external view returns (uint256);
function getGroupsVotedForByAccount(address) external view returns (address[] memory);
function getEligibleValidatorGroups() external view returns (address[] memory);
function getTotalVotesForEligibleValidatorGroups()
external
view
returns (address[] memory, uint256[] memory);
function getCurrentValidatorSigners() external view returns (address[] memory);
function canReceiveVotes(address, uint256) external view returns (bool);
function hasActivatablePendingVotes(address, address) external view returns (bool);
function validatorSignerAddressFromCurrentSet(uint256 index) external view returns (address);
function numberValidatorsInCurrentSet() external view returns (uint256);
function owner() external view returns (address);
}// SPDX-License-Identifier: LGPL-3.0-only pragma solidity >=0.5.13 <0.8.20; /** * @title Helps contracts guard against reentrancy attacks. * @author Remco Bloemen <remco@2π.com>, Eenae <[email protected]> * @dev If you mark a function `nonReentrant`, you should also * mark it `external`. */ contract ReentrancyGuard { /// @dev counter to allow mutex lock with only one SSTORE operation uint256 private _guardCounter; /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { _guardCounter += 1; uint256 localCounter = _guardCounter; _; require(localCounter == _guardCounter, "reentrant call"); } constructor() public { // The counter starts at one to prevent changing it from zero to a non-zero // value, which is a more expensive operation. _guardCounter = 1; } }
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.5.13 <0.9.0;
interface IRegistry {
function setAddressFor(string calldata, address) external;
function getAddressForOrDie(bytes32) external view returns (address);
function getAddressFor(bytes32) external view returns (address);
function getAddressForStringOrDie(string calldata identifier) external view returns (address);
function getAddressForString(string calldata identifier) external view returns (address);
function isOneOf(bytes32[] calldata, address) external view returns (bool);
}// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.5.13 <0.9.0;
interface IFreezer {
function freeze(address target) external;
function unfreeze(address target) external;
function isFrozen(address) external view returns (bool);
}// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.5.13 <0.9.0;
interface IFeeCurrencyWhitelist {
function initialize() external;
function addToken(address) external;
function getWhitelist() external view returns (address[] memory);
}// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.5.13 <0.9.0;
interface IEpochManager {
function initializeSystem(
uint256 firstEpochNumber,
uint256 firstEpochBlock,
address[] calldata firstElected
) external;
function startNextEpochProcess() external;
function finishNextEpochProcess(
address[] calldata groups,
address[] calldata lessers,
address[] calldata greaters
) external;
function setToProcessGroups() external;
function processGroup(address group, address lesser, address greater) external;
function sendValidatorPayment(address) external;
function getCurrentEpoch() external view returns (uint256, uint256, uint256, uint256);
function getEpochByNumber(
uint256 epochNumber
) external view returns (uint256, uint256, uint256, uint256);
function getEpochByBlockNumber(
uint256 blockNumber
) external view returns (uint256, uint256, uint256, uint256);
function getEpochNumberOfBlock(uint256) external view returns (uint256);
function getCurrentEpochNumber() external view returns (uint256);
function numberOfElectedInCurrentSet() external view returns (uint256);
function getElectedAccounts() external view returns (address[] memory);
function getElectedAccountByIndex(uint256 index) external view returns (address);
function getElectedSigners() external view returns (address[] memory);
function getElectedSignerByIndex(uint256 index) external view returns (address);
function epochDuration() external view returns (uint256);
function firstKnownEpoch() external view returns (uint256);
function getEpochProcessingState()
external
view
returns (uint256, uint256, uint256, uint256, uint256);
function systemAlreadyInitialized() external view returns (bool);
function isBlocked() external view returns (bool);
function isTimeForNextEpoch() external view returns (bool);
function isOnEpochProcess() external view returns (bool);
function getFirstBlockAtEpoch(uint256) external view returns (uint256);
function getLastBlockAtEpoch(uint256) external view returns (uint256);
}// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.5.13 <0.9.0;
interface ICeloVersionedContract {
/**
* @notice Returns the storage, major, minor, and patch version of the contract.
* @return Storage version of the contract.
* @return Major version of the contract.
* @return Minor version of the contract.
* @return Patch version of the contract.
*/
function getVersionNumber() external pure returns (uint256, uint256, uint256, uint256);
}// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.5.13 <0.9.0;
interface ICeloUnreleasedTreasury {
/**
* @notice Releases the Celo to the specified address.
* @param to The address to release the amount to.
* @param amount The amount to release.
*/
function release(address to, uint256 amount) external;
function getRemainingBalanceToRelease() external view returns (uint256);
}// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.5.13 <0.9.0;
interface IAccounts {
function setAccountDataEncryptionKey(bytes calldata) external;
function setMetadataURL(string calldata) external;
function setName(string calldata) external;
function setWalletAddress(address, uint8, bytes32, bytes32) external;
function setAccount(string calldata, bytes calldata, address, uint8, bytes32, bytes32) external;
function authorizeVoteSigner(address, uint8, bytes32, bytes32) external;
function authorizeValidatorSigner(address, uint8, bytes32, bytes32) external;
function authorizeValidatorSignerWithPublicKey(
address,
uint8,
bytes32,
bytes32,
bytes calldata
) external;
function authorizeValidatorSignerWithKeys(
address,
uint8,
bytes32,
bytes32,
bytes calldata,
bytes calldata,
bytes calldata
) external;
function authorizeAttestationSigner(address, uint8, bytes32, bytes32) external;
function setEip712DomainSeparator() external;
function createAccount() external returns (bool);
function setPaymentDelegation(address, uint256) external;
function isAccount(address) external view returns (bool);
function voteSignerToAccount(address) external view returns (address);
function validatorSignerToAccount(address) external view returns (address);
function attestationSignerToAccount(address) external view returns (address);
function signerToAccount(address) external view returns (address);
function getAttestationSigner(address) external view returns (address);
function getValidatorSigner(address) external view returns (address);
function getVoteSigner(address) external view returns (address);
function hasAuthorizedVoteSigner(address) external view returns (bool);
function hasAuthorizedValidatorSigner(address) external view returns (bool);
function hasAuthorizedAttestationSigner(address) external view returns (bool);
function batchGetMetadataURL(
address[] calldata
) external view returns (uint256[] memory, bytes memory);
function getDataEncryptionKey(address) external view returns (bytes memory);
function getWalletAddress(address) external view returns (address);
function getMetadataURL(address) external view returns (string memory);
function getName(address) external view returns (string memory);
function getPaymentDelegation(address) external view returns (address, uint256);
function isSigner(address, address, bytes32) external view returns (bool);
}// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity ^0.5.13;
import "openzeppelin-solidity/contracts/ownership/Ownable.sol";
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import "./interfaces/IAccounts.sol";
import "./interfaces/IEpochManager.sol";
import "./interfaces/IFeeCurrencyWhitelist.sol";
import "./interfaces/IFreezer.sol";
import "./interfaces/IRegistry.sol";
import "./interfaces/ICeloUnreleasedTreasury.sol";
import "../governance/interfaces/IElection.sol";
import "../governance/interfaces/IEpochRewards.sol";
import "../governance/interfaces/IGovernance.sol";
import "../governance/interfaces/ILockedGold.sol";
import "../governance/interfaces/ILockedCelo.sol";
import "../governance/interfaces/IValidators.sol";
import "../identity/interfaces/IRandom.sol";
import "../identity/interfaces/IAttestations.sol";
import "../../lib/mento-core/contracts/interfaces/IExchange.sol";
import "../../lib/mento-core/contracts/interfaces/IReserve.sol";
import "../../lib/mento-core/contracts/interfaces/IStableToken.sol";
import "../stability/interfaces/ISortedOracles.sol";
contract UsingRegistry is Ownable {
// solhint-disable state-visibility
bytes32 constant ACCOUNTS_REGISTRY_ID = keccak256(abi.encodePacked("Accounts"));
bytes32 constant ATTESTATIONS_REGISTRY_ID = keccak256(abi.encodePacked("Attestations"));
bytes32 constant DOWNTIME_SLASHER_REGISTRY_ID = keccak256(abi.encodePacked("DowntimeSlasher"));
bytes32 constant DOUBLE_SIGNING_SLASHER_REGISTRY_ID =
keccak256(abi.encodePacked("DoubleSigningSlasher"));
bytes32 constant ELECTION_REGISTRY_ID = keccak256(abi.encodePacked("Election"));
bytes32 constant EXCHANGE_REGISTRY_ID = keccak256(abi.encodePacked("Exchange"));
bytes32 constant FEE_CURRENCY_WHITELIST_REGISTRY_ID =
keccak256(abi.encodePacked("FeeCurrencyWhitelist"));
bytes32 constant FREEZER_REGISTRY_ID = keccak256(abi.encodePacked("Freezer"));
bytes32 constant GOLD_TOKEN_REGISTRY_ID = keccak256(abi.encodePacked("GoldToken"));
bytes32 constant GOVERNANCE_REGISTRY_ID = keccak256(abi.encodePacked("Governance"));
bytes32 constant GOVERNANCE_SLASHER_REGISTRY_ID =
keccak256(abi.encodePacked("GovernanceSlasher"));
bytes32 constant LOCKED_GOLD_REGISTRY_ID = keccak256(abi.encodePacked("LockedGold"));
bytes32 constant RESERVE_REGISTRY_ID = keccak256(abi.encodePacked("Reserve"));
bytes32 constant RANDOM_REGISTRY_ID = keccak256(abi.encodePacked("Random"));
bytes32 constant SORTED_ORACLES_REGISTRY_ID = keccak256(abi.encodePacked("SortedOracles"));
bytes32 constant STABLE_TOKEN_REGISTRY_ID = keccak256(abi.encodePacked("StableToken"));
bytes32 constant VALIDATORS_REGISTRY_ID = keccak256(abi.encodePacked("Validators"));
bytes32 constant CELO_TOKEN_REGISTRY_ID = keccak256(abi.encodePacked("CeloToken"));
bytes32 constant LOCKED_CELO_REGISTRY_ID = keccak256(abi.encodePacked("LockedCelo"));
bytes32 constant CELO_UNRELEASED_TREASURY_REGISTRY_ID =
keccak256(abi.encodePacked("CeloUnreleasedTreasury"));
bytes32 constant EPOCH_REWARDS_REGISTRY_ID = keccak256(abi.encodePacked("EpochRewards"));
bytes32 constant EPOCH_MANAGER_ENABLER_REGISTRY_ID =
keccak256(abi.encodePacked("EpochManagerEnabler"));
bytes32 constant EPOCH_MANAGER_REGISTRY_ID = keccak256(abi.encodePacked("EpochManager"));
// solhint-enable state-visibility
IRegistry public registry;
event RegistrySet(address indexed registryAddress);
modifier onlyRegisteredContract(bytes32 identifierHash) {
require(registry.getAddressForOrDie(identifierHash) == msg.sender, "only registered contract");
_;
}
modifier onlyRegisteredContracts(bytes32[] memory identifierHashes) {
require(registry.isOneOf(identifierHashes, msg.sender), "only registered contracts");
_;
}
/**
* @notice Updates the address pointing to a Registry contract.
* @param registryAddress The address of a registry contract for routing to other contracts.
*/
function setRegistry(address registryAddress) public onlyOwner {
require(registryAddress != address(0), "Cannot register the null address");
registry = IRegistry(registryAddress);
emit RegistrySet(registryAddress);
}
function getAccounts() internal view returns (IAccounts) {
return IAccounts(registry.getAddressForOrDie(ACCOUNTS_REGISTRY_ID));
}
function getAttestations() internal view returns (IAttestations) {
return IAttestations(registry.getAddressForOrDie(ATTESTATIONS_REGISTRY_ID));
}
function getElection() internal view returns (IElection) {
return IElection(registry.getAddressForOrDie(ELECTION_REGISTRY_ID));
}
function getExchange() internal view returns (IExchange) {
return IExchange(registry.getAddressForOrDie(EXCHANGE_REGISTRY_ID));
}
function getFeeCurrencyWhitelistRegistry() internal view returns (IFeeCurrencyWhitelist) {
return IFeeCurrencyWhitelist(registry.getAddressForOrDie(FEE_CURRENCY_WHITELIST_REGISTRY_ID));
}
function getFreezer() internal view returns (IFreezer) {
return IFreezer(registry.getAddressForOrDie(FREEZER_REGISTRY_ID));
}
function getGoldToken() internal view returns (IERC20) {
return IERC20(registry.getAddressForOrDie(GOLD_TOKEN_REGISTRY_ID));
}
function getCeloToken() internal view returns (IERC20) {
return IERC20(registry.getAddressForOrDie(CELO_TOKEN_REGISTRY_ID));
}
function getGovernance() internal view returns (IGovernance) {
return IGovernance(registry.getAddressForOrDie(GOVERNANCE_REGISTRY_ID));
}
function getLockedGold() internal view returns (ILockedGold) {
return ILockedGold(registry.getAddressForOrDie(LOCKED_GOLD_REGISTRY_ID));
}
function getLockedCelo() internal view returns (ILockedCelo) {
return ILockedCelo(registry.getAddressForOrDie(LOCKED_CELO_REGISTRY_ID));
}
function getRandom() internal view returns (IRandom) {
return IRandom(registry.getAddressForOrDie(RANDOM_REGISTRY_ID));
}
function getReserve() internal view returns (IReserve) {
return IReserve(registry.getAddressForOrDie(RESERVE_REGISTRY_ID));
}
function getSortedOracles() internal view returns (ISortedOracles) {
return ISortedOracles(registry.getAddressForOrDie(SORTED_ORACLES_REGISTRY_ID));
}
function getStableToken() internal view returns (IStableToken) {
return IStableToken(registry.getAddressForOrDie(STABLE_TOKEN_REGISTRY_ID));
}
function getValidators() internal view returns (IValidators) {
return IValidators(registry.getAddressForOrDie(VALIDATORS_REGISTRY_ID));
}
function getCeloUnreleasedTreasury() internal view returns (ICeloUnreleasedTreasury) {
return
ICeloUnreleasedTreasury(registry.getAddressForOrDie(CELO_UNRELEASED_TREASURY_REGISTRY_ID));
}
function getEpochRewards() internal view returns (IEpochRewards) {
return IEpochRewards(registry.getAddressForOrDie(EPOCH_REWARDS_REGISTRY_ID));
}
function getEpochManager() internal view returns (IEpochManager) {
return IEpochManager(registry.getAddressForOrDie(EPOCH_MANAGER_REGISTRY_ID));
}
}pragma solidity ^0.5.13;
import "openzeppelin-solidity/contracts/cryptography/ECDSA.sol";
library Signatures {
/**
* @notice Given a signed address, returns the signer of the address.
* @param message The address that was signed.
* @param v The recovery id of the incoming ECDSA signature.
* @param r Output value r of the ECDSA signature.
* @param s Output value s of the ECDSA signature.
*/
function getSignerOfAddress(
address message,
uint8 v,
bytes32 r,
bytes32 s
) public pure returns (address) {
bytes32 hash = keccak256(abi.encodePacked(message));
return getSignerOfMessageHash(hash, v, r, s);
}
/**
* @notice Given a message hash, returns the signer of the address.
* @param messageHash The hash of a message.
* @param v The recovery id of the incoming ECDSA signature.
* @param r Output value r of the ECDSA signature.
* @param s Output value s of the ECDSA signature.
*/
function getSignerOfMessageHash(
bytes32 messageHash,
uint8 v,
bytes32 r,
bytes32 s
) public pure returns (address) {
bytes memory signature = new bytes(65);
// Concatenate (r, s, v) into signature.
assembly {
mstore(add(signature, 32), r)
mstore(add(signature, 64), s)
mstore8(add(signature, 96), v)
}
bytes32 prefixedHash = ECDSA.toEthSignedMessageHash(messageHash);
return ECDSA.recover(prefixedHash, signature);
}
/**
* @notice Given a domain separator and a structHash, construct the typed data hash
* @param eip712DomainSeparator Context specific domain separator
* @param structHash hash of the typed data struct
* @return The EIP712 typed data hash
*/
function toEthSignedTypedDataHash(
bytes32 eip712DomainSeparator,
bytes32 structHash
) public pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", eip712DomainSeparator, structHash));
}
/**
* @notice Given a domain separator and a structHash and a signature return the signer
* @param eip712DomainSeparator Context specific domain separator
* @param structHash hash of the typed data struct
* @param v The recovery id of the incoming ECDSA signature.
* @param r Output value r of the ECDSA signature.
* @param s Output value s of the ECDSA signature.
*/
function getSignerOfTypedDataHash(
bytes32 eip712DomainSeparator,
bytes32 structHash,
uint8 v,
bytes32 r,
bytes32 s
) public pure returns (address) {
bytes memory signature = new bytes(65);
// Concatenate (r, s, v) into signature.
assembly {
mstore(add(signature, 32), r)
mstore(add(signature, 64), s)
mstore8(add(signature, 96), v)
}
bytes32 prefixedHash = toEthSignedTypedDataHash(eip712DomainSeparator, structHash);
return ECDSA.recover(prefixedHash, signature);
}
}// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.5.13 <0.9.0;
/**
* @title Used with proxied contracts that have an `initialize` function.
* @notice Ensures the `initialize` function:
* - gets called only once
* - cannot be called on the logic contract.
*/
contract Initializable {
bool public initialized;
/**
* @notice Ensures the initializer function cannot be called more than once.
*/
modifier initializer() {
require(!initialized, "contract already initialized");
initialized = true;
_;
}
/**
* @notice By default, ensures that the `initialize` function cannot be called
* on the logic contract.
* @param testingDeployment When set to true, allows the `initialize` function
* to be called, which is useful in testing when not setting up with a Proxy.
*/
constructor(bool testingDeployment) public {
if (!testingDeployment) {
initialized = true;
}
}
}// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.5.13 <0.9.0;
/**
* @title FixidityLib
* @author Gadi Guy, Alberto Cuesta Canada
* @notice This library provides fixed point arithmetic with protection against
* overflow.
* All operations are done with uint256 and the operands must have been created
* with any of the newFrom* functions, which shift the comma digits() to the
* right and check for limits, or with wrap() which expects a number already
* in the internal representation of a fraction.
* When using this library be sure to use maxNewFixed() as the upper limit for
* creation of fixed point numbers.
* @dev All contained functions are pure and thus marked internal to be inlined
* on consuming contracts at compile time for gas efficiency.
*/
library FixidityLib {
struct Fraction {
uint256 value;
}
uint256 private constant FIXED1_UINT = 1000000000000000000000000;
/**
* @notice Number of positions that the comma is shifted to the right.
*/
function digits() internal pure returns (uint8) {
return 24;
}
/**
* @notice This is 1 in the fixed point units used in this library.
* @dev Test fixed1() equals 10^digits()
* Hardcoded to 24 digits.
*/
function fixed1() internal pure returns (Fraction memory) {
return Fraction(FIXED1_UINT);
}
/**
* @notice Wrap a uint256 that represents a 24-decimal fraction in a Fraction
* struct.
* @param x Number that already represents a 24-decimal fraction.
* @return A Fraction struct with contents x.
*/
function wrap(uint256 x) internal pure returns (Fraction memory) {
return Fraction(x);
}
/**
* @notice Unwraps the uint256 inside of a Fraction struct.
*/
function unwrap(Fraction memory x) internal pure returns (uint256) {
return x.value;
}
/**
* @notice The amount of decimals lost on each multiplication operand.
* @dev Test mulPrecision() equals sqrt(fixed1)
*/
function mulPrecision() internal pure returns (uint256) {
return 1000000000000;
}
/**
* @notice Maximum value that can be converted to fixed point. Optimize for deployment.
* @dev
* Test maxNewFixed() equals maxUint256() / fixed1()
*/
function maxNewFixed() internal pure returns (uint256) {
return 115792089237316195423570985008687907853269984665640564;
}
/**
* @notice Converts a uint256 to fixed point Fraction
* @dev Test newFixed(0) returns 0
* Test newFixed(1) returns fixed1()
* Test newFixed(maxNewFixed()) returns maxNewFixed() * fixed1()
* Test newFixed(maxNewFixed()+1) fails
*/
function newFixed(uint256 x) internal pure returns (Fraction memory) {
require(x <= maxNewFixed(), "can't create fixidity number larger than maxNewFixed()");
return Fraction(x * FIXED1_UINT);
}
/**
* @notice Converts a uint256 in the fixed point representation of this
* library to a non decimal. All decimal digits will be truncated.
*/
function fromFixed(Fraction memory x) internal pure returns (uint256) {
return x.value / FIXED1_UINT;
}
/**
* @notice Converts two uint256 representing a fraction to fixed point units,
* equivalent to multiplying dividend and divisor by 10^digits().
* @param numerator numerator must be <= maxNewFixed()
* @param denominator denominator must be <= maxNewFixed() and denominator can't be 0
* @dev
* Test newFixedFraction(1,0) fails
* Test newFixedFraction(0,1) returns 0
* Test newFixedFraction(1,1) returns fixed1()
* Test newFixedFraction(1,fixed1()) returns 1
*/
function newFixedFraction(
uint256 numerator,
uint256 denominator
) internal pure returns (Fraction memory) {
Fraction memory convertedNumerator = newFixed(numerator);
Fraction memory convertedDenominator = newFixed(denominator);
return divide(convertedNumerator, convertedDenominator);
}
/**
* @notice Returns the integer part of a fixed point number.
* @dev
* Test integer(0) returns 0
* Test integer(fixed1()) returns fixed1()
* Test integer(newFixed(maxNewFixed())) returns maxNewFixed()*fixed1()
*/
function integer(Fraction memory x) internal pure returns (Fraction memory) {
return Fraction((x.value / FIXED1_UINT) * FIXED1_UINT); // Can't overflow
}
/**
* @notice Returns the fractional part of a fixed point number.
* In the case of a negative number the fractional is also negative.
* @dev
* Test fractional(0) returns 0
* Test fractional(fixed1()) returns 0
* Test fractional(fixed1()-1) returns 10^24-1
*/
function fractional(Fraction memory x) internal pure returns (Fraction memory) {
return Fraction(x.value - (x.value / FIXED1_UINT) * FIXED1_UINT); // Can't overflow
}
/**
* @notice x+y.
* @dev The maximum value that can be safely used as an addition operator is defined as
* maxFixedAdd = maxUint256()-1 / 2, or
* 57896044618658097711785492504343953926634992332820282019728792003956564819967.
* Test add(maxFixedAdd,maxFixedAdd) equals maxFixedAdd + maxFixedAdd
* Test add(maxFixedAdd+1,maxFixedAdd+1) throws
*/
function add(Fraction memory x, Fraction memory y) internal pure returns (Fraction memory) {
uint256 z = x.value + y.value;
require(z >= x.value, "add overflow detected");
return Fraction(z);
}
/**
* @notice x-y.
* @dev
* Test subtract(6, 10) fails
*/
function subtract(Fraction memory x, Fraction memory y) internal pure returns (Fraction memory) {
require(x.value >= y.value, "substraction underflow detected");
return Fraction(x.value - y.value);
}
/**
* @notice x*y. If any of the operators is higher than the max multiplier value it
* might overflow.
* @dev The maximum value that can be safely used as a multiplication operator
* (maxFixedMul) is calculated as sqrt(maxUint256()*fixed1()),
* or 340282366920938463463374607431768211455999999999999
* Test multiply(0,0) returns 0
* Test multiply(maxFixedMul,0) returns 0
* Test multiply(0,maxFixedMul) returns 0
* Test multiply(fixed1()/mulPrecision(),fixed1()*mulPrecision()) returns fixed1()
* Test multiply(maxFixedMul,maxFixedMul) is around maxUint256()
* Test multiply(maxFixedMul+1,maxFixedMul+1) fails
*/
function multiply(Fraction memory x, Fraction memory y) internal pure returns (Fraction memory) {
if (x.value == 0 || y.value == 0) return Fraction(0);
if (y.value == FIXED1_UINT) return x;
if (x.value == FIXED1_UINT) return y;
// Separate into integer and fractional parts
// x = x1 + x2, y = y1 + y2
uint256 x1 = integer(x).value / FIXED1_UINT;
uint256 x2 = fractional(x).value;
uint256 y1 = integer(y).value / FIXED1_UINT;
uint256 y2 = fractional(y).value;
// (x1 + x2) * (y1 + y2) = (x1 * y1) + (x1 * y2) + (x2 * y1) + (x2 * y2)
uint256 x1y1 = x1 * y1;
if (x1 != 0) require(x1y1 / x1 == y1, "overflow x1y1 detected");
// x1y1 needs to be multiplied back by fixed1
// solium-disable-next-line mixedcase
uint256 fixed_x1y1 = x1y1 * FIXED1_UINT;
if (x1y1 != 0) require(fixed_x1y1 / x1y1 == FIXED1_UINT, "overflow x1y1 * fixed1 detected");
x1y1 = fixed_x1y1;
uint256 x2y1 = x2 * y1;
if (x2 != 0) require(x2y1 / x2 == y1, "overflow x2y1 detected");
uint256 x1y2 = x1 * y2;
if (x1 != 0) require(x1y2 / x1 == y2, "overflow x1y2 detected");
x2 = x2 / mulPrecision();
y2 = y2 / mulPrecision();
uint256 x2y2 = x2 * y2;
if (x2 != 0) require(x2y2 / x2 == y2, "overflow x2y2 detected");
// result = fixed1() * x1 * y1 + x1 * y2 + x2 * y1 + x2 * y2 / fixed1();
Fraction memory result = Fraction(x1y1);
result = add(result, Fraction(x2y1)); // Add checks for overflow
result = add(result, Fraction(x1y2)); // Add checks for overflow
result = add(result, Fraction(x2y2)); // Add checks for overflow
return result;
}
/**
* @notice 1/x
* @dev
* Test reciprocal(0) fails
* Test reciprocal(fixed1()) returns fixed1()
* Test reciprocal(fixed1()*fixed1()) returns 1 // Testing how the fractional is truncated
* Test reciprocal(1+fixed1()*fixed1()) returns 0 // Testing how the fractional is truncated
* Test reciprocal(newFixedFraction(1, 1e24)) returns newFixed(1e24)
*/
function reciprocal(Fraction memory x) internal pure returns (Fraction memory) {
require(x.value != 0, "can't call reciprocal(0)");
return Fraction((FIXED1_UINT * FIXED1_UINT) / x.value); // Can't overflow
}
/**
* @notice x/y. If the dividend is higher than the max dividend value, it
* might overflow. You can use multiply(x,reciprocal(y)) instead.
* @dev The maximum value that can be safely used as a dividend (maxNewFixed) is defined as
* divide(maxNewFixed,newFixedFraction(1,fixed1())) is around maxUint256().
* This yields the value 115792089237316195423570985008687907853269984665640564.
* Test maxNewFixed equals maxUint256()/fixed1()
* Test divide(maxNewFixed,1) equals maxNewFixed*(fixed1)
* Test divide(maxNewFixed+1,multiply(mulPrecision(),mulPrecision())) throws
* Test divide(fixed1(),0) fails
* Test divide(maxNewFixed,1) = maxNewFixed*(10^digits())
* Test divide(maxNewFixed+1,1) throws
*/
function divide(Fraction memory x, Fraction memory y) internal pure returns (Fraction memory) {
require(y.value != 0, "can't divide by 0");
uint256 X = x.value * FIXED1_UINT;
require(X / FIXED1_UINT == x.value, "overflow at divide");
return Fraction(X / y.value);
}
/**
* @notice x > y
*/
function gt(Fraction memory x, Fraction memory y) internal pure returns (bool) {
return x.value > y.value;
}
/**
* @notice x >= y
*/
function gte(Fraction memory x, Fraction memory y) internal pure returns (bool) {
return x.value >= y.value;
}
/**
* @notice x < y
*/
function lt(Fraction memory x, Fraction memory y) internal pure returns (bool) {
return x.value < y.value;
}
/**
* @notice x <= y
*/
function lte(Fraction memory x, Fraction memory y) internal pure returns (bool) {
return x.value <= y.value;
}
/**
* @notice x == y
*/
function equals(Fraction memory x, Fraction memory y) internal pure returns (bool) {
return x.value == y.value;
}
/**
* @notice x <= 1
*/
function isProperFraction(Fraction memory x) internal pure returns (bool) {
return lte(x, fixed1());
}
}// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.5.13 <0.8.20;
/**
* @title Based on predeploy returns whether this is L1 or L2.
*/
contract IsL2Check {
address constant proxyAdminAddress = 0x4200000000000000000000000000000000000018;
/**
* @notice Throws if called on L2.
*/
modifier onlyL1() {
allowOnlyL1();
_;
}
/**
* @notice Throws if called on L1.
*/
modifier onlyL2() {
if (!isL2()) {
revert("This method is not supported in L1.");
}
_;
}
/**
* @notice Checks to see if current network is Celo L2.
* @return Whether or not the current network is a Celo L2.
*/
function isL2() internal view returns (bool) {
uint32 size;
address _addr = proxyAdminAddress;
assembly {
size := extcodesize(_addr)
}
return (size > 0);
}
/**
* @notice Used to restrict usage of the parent function to L1 execution.
* @dev Reverts if called on a Celo L2 network.
*/
function allowOnlyL1() internal view {
if (isL2()) {
revert("This method is no longer supported in L2.");
}
}
}pragma solidity ^0.5.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP. Does not include
* the optional functions; to access them see {ERC20Detailed}.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}pragma solidity ^0.5.0;
import "../GSN/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor () internal {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(isOwner(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Returns true if the caller is the current owner.
*/
function isOwner() public view returns (bool) {
return _msgSender() == _owner;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
*/
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}pragma solidity ^0.5.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*
* _Available since v2.4.0._
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}pragma solidity ^0.5.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 {
/**
* @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.
*
* NOTE: This call _does not revert_ if the signature is invalid, or
* if the signer is otherwise unable to be retrieved. In those scenarios,
* the zero address is returned.
*
* 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) {
// Check the signature length
if (signature.length != 65) {
return (address(0));
}
// Divide the signature in r, s and v variables
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
// solhint-disable-next-line no-inline-assembly
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
// 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 (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): 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);
}
if (v != 27 && v != 28) {
return address(0);
}
// If the signature is valid (and not malleable), return the signer address
return ecrecover(hash, v, r, s);
}
/**
* @dev Returns an Ethereum Signed Message, created from a `hash`. This
* replicates the behavior of the
* https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`]
* JSON-RPC method.
*
* 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));
}
}pragma solidity ^0.5.0;
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
contract Context {
// Empty internal constructor, to prevent people from mistakenly deploying
// an instance of this contract, which should be used via inheritance.
constructor () internal { }
// solhint-disable-previous-line no-empty-blocks
function _msgSender() internal view returns (address payable) {
return msg.sender;
}
function _msgData() internal view returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}{
"remappings": [],
"optimizer": {
"enabled": false,
"runs": 200
},
"evmVersion": "istanbul",
"libraries": {
"/contracts/common/Accounts.sol": {
"Proposals": "0x38afc0dc55415ae27b81c24b5a5fbfe433ebfba8",
"IntegerSortedLinkedList": "0x411b40a81a07fcd3542ce5b3d7e215178c4ca2ef",
"AddressLinkedList": "0xd26d896d258e258eba71ff0873a878ec36538f8d",
"Signatures": "0x69baecd458e7c08b13a18e11887dbb078fb3cbb4",
"AddressSortedLinkedList": "0x4819ad0a0eb1304b1d7bc3afd7818017b52a87ab"
}
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"bool","name":"test","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"AccountCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bytes","name":"dataEncryptionKey","type":"bytes"}],"name":"AccountDataEncryptionKeySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"string","name":"metadataURL","type":"string"}],"name":"AccountMetadataURLSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"}],"name":"AccountNameSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"walletAddress","type":"address"}],"name":"AccountWalletAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"signer","type":"address"}],"name":"AttestationSignerAuthorized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"oldSigner","type":"address"}],"name":"AttestationSignerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"oldSigner","type":"address"},{"indexed":false,"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"DefaultSignerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"signer","type":"address"},{"indexed":false,"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"DefaultSignerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"oldSigner","type":"address"},{"indexed":false,"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"IndexedSignerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"signer","type":"address"},{"indexed":false,"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"IndexedSignerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"oldSigner","type":"address"},{"indexed":false,"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"LegacySignerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"signer","type":"address"},{"indexed":false,"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"LegacySignerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bytes","name":"url","type":"bytes"}],"name":"OffchainStorageRootAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bytes","name":"url","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"OffchainStorageRootRemoved","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":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"fraction","type":"uint256"}],"name":"PaymentDelegationSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"registryAddress","type":"address"}],"name":"RegistrySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"signer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"SignerAuthorizationCompleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"signer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"SignerAuthorizationStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"signer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"SignerAuthorized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"oldSigner","type":"address"},{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"SignerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"signer","type":"address"}],"name":"ValidatorSignerAuthorized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"oldSigner","type":"address"}],"name":"ValidatorSignerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"signer","type":"address"}],"name":"VoteSignerAuthorized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"oldSigner","type":"address"}],"name":"VoteSignerRemoved","type":"event"},{"constant":true,"inputs":[],"name":"EIP712_AUTHORIZE_SIGNER_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"url","type":"bytes"}],"name":"addStorageRoot","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"attestationSignerToAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"authorizeAttestationSigner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"authorizeSigner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"authorizeSignerWithSignature","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"authorizeValidatorSigner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"bytes","name":"ecdsaPublicKey","type":"bytes"},{"internalType":"bytes","name":"blsPublicKey","type":"bytes"},{"internalType":"bytes","name":"blsPop","type":"bytes"}],"name":"authorizeValidatorSignerWithKeys","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"bytes","name":"ecdsaPublicKey","type":"bytes"}],"name":"authorizeValidatorSignerWithPublicKey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"authorizeVoteSigner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"authorizedBy","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address[]","name":"accountsToQuery","type":"address[]"}],"name":"batchGetMetadataURL","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"completeSignerAuthorization","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"createAccount","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"deletePaymentDelegation","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"eip712DomainSeparator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getAttestationSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getDataEncryptionKey","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getDefaultSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getIndexedSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getLegacySigner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getMetadataURL","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getName","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getOffchainStorageRoots","outputs":[{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getPaymentDelegation","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"getRoleAuthorizationSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getValidatorSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getVersionNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getVoteSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getWalletAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"hasAuthorizedAttestationSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"string","name":"role","type":"string"}],"name":"hasAuthorizedSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"hasAuthorizedValidatorSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"hasAuthorizedVoteSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"hasDefaultSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"hasIndexedSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"hasLegacySigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"registryAddress","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isAccount","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isAuthorizedSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"isDefaultSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"isIndexedSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"isLegacyRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"isLegacySigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"isSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"offchainStorageRoots","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"registry","outputs":[{"internalType":"contract IRegistry","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"removeAttestationSigner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"removeDefaultSigner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"removeIndexedSigner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"removeSigner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"removeStorageRoot","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"removeValidatorSigner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"removeVoteSigner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"bytes","name":"dataEncryptionKey","type":"bytes"},{"internalType":"address","name":"walletAddress","type":"address"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"setAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"dataEncryptionKey","type":"bytes"}],"name":"setAccountDataEncryptionKey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"setEip712DomainSeparator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"setIndexedSigner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"metadataURL","type":"string"}],"name":"setMetadataURL","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"setName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"uint256","name":"fraction","type":"uint256"}],"name":"setPaymentDelegation","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"registryAddress","type":"address"}],"name":"setRegistry","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"walletAddress","type":"address"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"setWalletAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"signerToAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"validatorSignerToAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"voteSignerToAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b506040516200902738038062009027833981810160405260208110156200003757600080fd5b81019080805190602001909291905050508060006200005b6200012a60201b60201c565b9050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a350600180819055508062000122576001600260006101000a81548160ff0219169083151502179055505b505062000132565b600033905090565b618ee580620001426000396000f3fe608060405234801561001057600080fd5b506004361061041d5760003560e01c80637b2434cb1161022b578063ae32fa0e11610130578063c48830d9116100b8578063f0c5658411610087578063f0c56584146121d1578063f2fde38b146121ef578063f333d83614612233578063fbe3c37314612279578063ff836d93146122c75761041d565b8063c48830d9146120ab578063c4d66de814612131578063e7a16e6b14612175578063e8d787cb146121a35761041d565b8063ba40e4f6116100ff578063ba40e4f614611e74578063baf7ef0f14611f25578063bce2b8d614611f8a578063c2e0ee2014611f94578063c47f002714611ff05761041d565b8063ae32fa0e14611beb578063b062c84314611ca8578063b5a664c214611d21578063b6c6662514611da55761041d565b806392f90fbf116101b35780639f024f4b116101825780639f024f4b14611a075780639f68297614611a92578063a5ec94f914611ae0578063a8ae1a3d14611aea578063a91ee0dc14611ba75761041d565b806392f90fbf1461188d57806393c5c487146118fc5780639cafb2a1146119805780639dca362f146119e55761041d565b80638da5cb5b116101fa5780638da5cb5b1461163e5780638f32d59b146116885780638f9ae6dc146116aa57806390b12b47146116f857806391cd074b146118075761041d565b80637b2434cb1461136457806387affe68146113e85780638adaf96f146114765780638bceca58146115b05761041d565b806349045e161161033157806364439b43116102b9578063747daec511610288578063747daec51461116b57806376082c1f146111e4578063760fbbb2146112ab57806376afa04c146112b55780637b1039991461131a5761041d565b806364439b431461100b5780636642d5941461108f578063715018a614611113578063727d079c1461111d5761041d565b80635b07fdd8116103005780635b07fdd814610dc25780635b6d900414610de05780635fd4b08a14610e6e578063614ed49314610f2b57806361bab1ae14610f875761041d565b806349045e1614610c615780634ce38b5f14610cbd57806354255be014610d4157806358b81ea814610d745761041d565b80631465b923116103b4578063289a131811610383578063289a1318146109e35780633184b3c514610ae857806341ddd88014610af25780634282ee6d14610b76578063485a46d114610bdb5761041d565b80631465b9231461077d578063158ef93e146108e15780631fd9afa51461090357806325ca4c9c146109875761041d565b80630fa750d2116103f05780630fa750d2146105985780630fe7abab1461065257806310c504b51461070d5780631441ece7146107175761041d565b80630127dbed146104225780630185a2321461047e57806305be6229146104ac5780630b8e056214610512575b600080fd5b6104646004803603602081101561043857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061232d565b604051808215151515815260200191505060405180910390f35b6104aa6004803603602081101561049457600080fd5b8101908080359060200190929190505050612386565b005b6104f8600480360360408110156104c257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061243f565b604051808215151515815260200191505060405180910390f35b61057e6004803603606081101561052857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612482565b604051808215151515815260200191505060405180910390f35b610650600480360360a08110156105ae57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff16906020019092919080359060200190929190803590602001909291908035906020019064010000000081111561060c57600080fd5b82018360208201111561061e57600080fd5b8035906020019184600183028401116401000000008311171561064057600080fd5b909192939192939050505061252c565b005b61070b6004803603602081101561066857600080fd5b810190808035906020019064010000000081111561068557600080fd5b82018360208201111561069757600080fd5b803590602001918460018302840111640100000000831117156106b957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061285e565b005b6107156129e9565b005b6107636004803603604081101561072d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612b0a565b604051808215151515815260200191505060405180910390f35b6108df600480360360e081101561079357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff1690602001909291908035906020019092919080359060200190929190803590602001906401000000008111156107f157600080fd5b82018360208201111561080357600080fd5b8035906020019184600183028401116401000000008311171561082557600080fd5b90919293919293908035906020019064010000000081111561084657600080fd5b82018360208201111561085857600080fd5b8035906020019184600183028401116401000000008311171561087a57600080fd5b90919293919293908035906020019064010000000081111561089b57600080fd5b8201836020820111156108ad57600080fd5b803590602001918460018302840111640100000000831117156108cf57600080fd5b9091929391929390505050612b4d565b005b6108e9612f08565b604051808215151515815260200191505060405180910390f35b6109456004803603602081101561091957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f1b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6109c96004803603602081101561099d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f87565b604051808215151515815260200191505060405180910390f35b610a25600480360360208110156109f957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612fe0565b604051808060200180602001838103835285818151815260200191508051906020019080838360005b83811015610a69578082015181840152602081019050610a4e565b50505050905090810190601f168015610a965780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019060200280838360005b83811015610ad2578082015181840152602081019050610ab7565b5050505090500194505050505060405180910390f35b610af061333b565b005b610b3460048036036020811015610b0857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613345565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610bd960048036036080811015610b8c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff169060200190929190803590602001909291908035906020019092919050505061339e565b005b610c4760048036036060811015610bf157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613550565b604051808215151515815260200191505060405180910390f35b610ca360048036036020811015610c7757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506136a1565b604051808215151515815260200191505060405180910390f35b610cff60048036036020811015610cd357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613739565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610d49613792565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b610dc060048036036040811015610d8a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506137b9565b005b610dca6139f1565b6040518082815260200191505060405180910390f35b610e2c60048036036040811015610df657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506139f7565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610eb060048036036020811015610e8457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613ab2565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610ef0578082015181840152602081019050610ed5565b50505050905090810190601f168015610f1d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610f6d60048036036020811015610f4157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613b96565b604051808215151515815260200191505060405180910390f35b610fc960048036036020811015610f9d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613bef565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61104d6004803603602081101561102157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613c48565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6110d1600480360360208110156110a557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613ca1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61111b613cfa565b005b6111696004803603604081101561113357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613e33565b005b6111e26004803603602081101561118157600080fd5b810190808035906020019064010000000081111561119e57600080fd5b8201836020820111156111b057600080fd5b803590602001918460018302840111640100000000831117156111d257600080fd5b9091929391929390505050614405565b005b611230600480360360408110156111fa57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614556565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611270578082015181840152602081019050611255565b50505050905090810190601f16801561129d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6112b361461c565b005b611318600480360360808110156112cb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff169060200190929190803590602001909291908035906020019092919050505061473d565b005b611322614860565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6113a66004803603602081101561137a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614886565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b611434600480360360408110156113fe57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506148df565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6114ed6004803603602081101561148c57600080fd5b81019080803590602001906401000000008111156114a957600080fd5b8201836020820111156114bb57600080fd5b803590602001918460208302840111640100000000831117156114dd57600080fd5b9091929391929390505050614910565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015611534578082015181840152602081019050611519565b50505050905001838103825284818151815260200191508051906020019080838360005b83811015611573578082015181840152602081019050611558565b50505050905090810190601f1680156115a05780820380516001836020036101000a031916815260200191505b5094505050505060405180910390f35b6115fc600480360360408110156115c657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614c0f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b611646614e8c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b611690614eb5565b604051808215151515815260200191505060405180910390f35b6116f6600480360360408110156116c057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614f13565b005b611805600480360360c081101561170e57600080fd5b810190808035906020019064010000000081111561172b57600080fd5b82018360208201111561173d57600080fd5b8035906020019184600183028401116401000000008311171561175f57600080fd5b90919293919293908035906020019064010000000081111561178057600080fd5b82018360208201111561179257600080fd5b803590602001918460018302840111640100000000831117156117b457600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff1690602001909291908035906020019092919080359060200190929190505050615195565b005b6118736004803603606081101561181d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061525c565b604051808215151515815260200191505060405180910390f35b6118fa600480360360a08110156118a357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803560ff16906020019092919080359060200190929190803590602001909291905050506154cf565b005b61193e6004803603602081101561191257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050615649565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6119e36004803603608081101561199657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff1690602001909291908035906020019092919080359060200190929190505050615753565b005b6119ed615aba565b604051808215151515815260200191505060405180910390f35b611a4960048036036020811015611a1d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050615bd6565b604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390f35b611ade60048036036040811015611aa857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050615c6c565b005b611ae8615ff7565b005b611b2c60048036036020811015611b0057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050616118565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611b6c578082015181840152602081019050611b51565b50505050905090810190601f168015611b995780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b611be960048036036020811015611bbd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506161fc565b005b611c2d60048036036020811015611c0157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506163a0565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611c6d578082015181840152602081019050611c52565b50505050905090810190601f168015611c9a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b611d1f60048036036020811015611cbe57600080fd5b8101908080359060200190640100000000811115611cdb57600080fd5b820183602082011115611ced57600080fd5b80359060200191846001830284011164010000000083111715611d0f57600080fd5b9091929391929390505050616484565b005b611d6360048036036020811015611d3757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506165fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b611e32600480360360c0811015611dbb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803560ff169060200190929190803590602001909291908035906020019092919050505061662f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b611f0b60048036036040811015611e8a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115611ec757600080fd5b820183602082011115611ed957600080fd5b80359060200191846001830284011164010000000083111715611efb57600080fd5b90919293919293905050506167a2565b604051808215151515815260200191505060405180910390f35b611f8860048036036080811015611f3b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff16906020019092919080359060200190929190803590602001909291905050506167e6565b005b611f92616aad565b005b611fd660048036036020811015611faa57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050616c30565b604051808215151515815260200191505060405180910390f35b6120a96004803603602081101561200657600080fd5b810190808035906020019064010000000081111561202357600080fd5b82018360208201111561203557600080fd5b8035906020019184600183028401116401000000008311171561205757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050616c89565b005b612117600480360360608110156120c157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050616dfa565b604051808215151515815260200191505060405180910390f35b6121736004803603602081101561214757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050616e2e565b005b6121a16004803603602081101561218b57600080fd5b8101908080359060200190929190505050616ee9565b005b6121cf600480360360208110156121b957600080fd5b8101908080359060200190929190505050617074565b005b6121d96174bc565b6040518082815260200191505060405180910390f35b6122316004803603602081101561220557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506174d8565b005b61225f6004803603602081101561224957600080fd5b810190808035906020019092919050505061755e565b604051808215151515815260200191505060405180910390f35b6122c56004803603604081101561228f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050617650565b005b612313600480360360408110156122dd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506177a1565b604051808215151515815260200191505060405180910390f35b600061237f8260405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120612b0a565b9050919050565b600061239233836148df565b905061239d8261755e565b6123af576123aa82616ee9565b6123b9565b6123b8826177d2565b5b3373ffffffffffffffffffffffffffffffffffffffff167fccc97b55d227538f487c521e1218ba74768b73d088310238027c2ae3b43e9c918284604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a25050565b60008273ffffffffffffffffffffffffffffffffffffffff1661246284846139f7565b73ffffffffffffffffffffffffffffffffffffffff161415905092915050565b60008273ffffffffffffffffffffffffffffffffffffffff16600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161490509392505050565b60018060008282540192505081905550600060015490506125968760405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120888888617ae8565b6125e68760405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120613e33565b6125ee617c61565b73ffffffffffffffffffffffffffffffffffffffff16634e06fd8a338986866040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050602060405180830381600087803b1580156126d457600080fd5b505af11580156126e8573d6000803e3d6000fd5b505050506040513d60208110156126fe57600080fd5b8101908080519060200190929190505050612764576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180618e906021913960400191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f16e382723fb40543364faf68863212ba253a099607bf6d3a5b47e50a8bf9494388604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a26001548114612855576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f7265656e7472616e742063616c6c00000000000000000000000000000000000081525060200191505060405180910390fd5b50505050505050565b6021815110156128d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f6461746120656e6372797074696f6e206b6579206c656e677468203c3d20333281525060200191505060405180910390fd5b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050818160060190805190602001906129319291906187c7565b503373ffffffffffffffffffffffffffffffffffffffff167f43fdefe0a824cb0e3bbaf9c4bc97669187996136fe9282382baf10787f0d808d836040518080602001828103825283818151815260200191508051906020019080838360005b838110156129ab578082015181840152602081019050612990565b50505050905090810190601f1680156129d85780820380516001836020036101000a031916815260200191505b509250505060405180910390a25050565b6000612a3b3360405160200180807f63656c6f2e6f72672f636f72652f766f74650000000000000000000000000000815250601201905060405160208183030381529060405280519060200120614c0f565b9050612a8d8160405160200180807f63656c6f2e6f72672f636f72652f766f74650000000000000000000000000000815250601201905060405160208183030381529060405280519060200120617650565b3373ffffffffffffffffffffffffffffffffffffffff167fa197481f404d8a8082368ad7445380f01e75f27dea6b7aef234a4ce071127fae82604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a250565b60008273ffffffffffffffffffffffffffffffffffffffff16612b2d8484614c0f565b73ffffffffffffffffffffffffffffffffffffffff161415905092915050565b6001806000828254019250508190555060006001549050612bb78b60405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f720000000000000000008152506017019050604051602081830303815290604052805190602001208c8c8c617ae8565b612c078b60405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120613e33565b612c0f617c61565b73ffffffffffffffffffffffffffffffffffffffff1663713ea0f3338d8a8a8a8a8a8a6040518963ffffffff1660e01b8152600401808973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001806020018060200184810384528a8a82818152602001925080828437600081840152601f19601f8201169050808301925050508481038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508481038252868682818152602001925080828437600081840152601f19601f8201169050808301925050509b505050505050505050505050602060405180830381600087803b158015612d5d57600080fd5b505af1158015612d71573d6000803e3d6000fd5b505050506040513d6020811015612d8757600080fd5b8101908080519060200190929190505050612e0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4661696c656420746f207570646174652076616c696461746f72206b6579730081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f16e382723fb40543364faf68863212ba253a099607bf6d3a5b47e50a8bf949438c604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a26001548114612efb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f7265656e7472616e742063616c6c00000000000000000000000000000000000081525060200191505060405180910390fd5b5050505050505050505050565b600260009054906101000a900460ff1681565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff169050919050565b606080612fec83612f87565b61305e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f556e6b6e6f776e206163636f756e74000000000000000000000000000000000081525060200191505060405180910390fd5b6000600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050600080905060008090505b8281101561314257613133600860008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811061310557fe5b9060005260206000200180546001816001161561010002031660029004905083617d5c90919063ffffffff16565b915080806001019150506130b0565b506060816040519080825280601f01601f1916602001820160405280156131785781602001600182028038833980820191505090505b50905060008090506060846040519080825280602002602001820160405280156131b15781602001602082028038833980820191505090505b50905060008090505b8581101561332a576000600860008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811061320e57fe5b9060005260206000200190508080546001816001161561010002031660029004905083838151811061323c57fe5b60200260200101818152505060008090505b83838151811061325a57fe5b602002602001015181101561331b57818181546001816001161561010002031660029004811061328657fe5b8154600116156132a55790600052602060002090602091828204019190065b9054901a7f0100000000000000000000000000000000000000000000000000000000000000028686815181106132d757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508480600101955050808060010191505061324e565b505080806001019150506131ba565b508281965096505050505050915091565b613343617de4565b565b60006133978260405160200180807f63656c6f2e6f72672f636f72652f766f74650000000000000000000000000000815250601201905060405160208183030381529060405280519060200120614c0f565b9050919050565b60018060008282540192505081905550600060015490506134088560405160200180807f63656c6f2e6f72672f636f72652f766f74650000000000000000000000000000815250601201905060405160208183030381529060405280519060200120868686617ae8565b6134588560405160200180807f63656c6f2e6f72672f636f72652f766f74650000000000000000000000000000815250601201905060405160208183030381529060405280519060200120613e33565b3373ffffffffffffffffffffffffffffffffffffffff167faab5f8a189373aaa290f42ae65ea5d7971b732366ca5bf66556e76263944af2886604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a26001548114613549576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f7265656e7472616e742063616c6c00000000000000000000000000000000000081525060200191505060405180910390fd5b5050505050565b600061355d84848461525c565b806136985750600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160019054906101000a900460ff16801561369757508373ffffffffffffffffffffffffffffffffffffffff16600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b60008073ffffffffffffffffffffffffffffffffffffffff16600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600061378b8260405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120614c0f565b9050919050565b60008060008060018060046002839350829250819150809050935093509350935090919293565b6137c233612f87565b613817576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526035815260200180618de56035913960400191505060405180910390fd5b61382082617eee565b801561383257506138313383617f48565b5b613887576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180618e496022913960400191505060405180910390fd5b604051806040016040528060011515815260200160001515815250600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff021916908315150217905550905050803373ffffffffffffffffffffffffffffffffffffffff167f7a162218a1b7bec7fb15b4bb95220fbf423fa3a49718133f5c50361ff1c8537684604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a35050565b60075481565b600080600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613aa75780613aa9565b835b91505092915050565b6060600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015613b8a5780601f10613b5f57610100808354040283529160200191613b8a565b820191906000526020600020905b815481529060010190602001808311613b6d57829003601f168201915b50505050509050919050565b6000613be88260405160200180807f63656c6f2e6f72672f636f72652f766f74650000000000000000000000000000815250601201905060405160208183030381529060405280519060200120612b0a565b9050919050565b6000613c418260405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e00000000000000815250601901905060405160208183030381529060405280519060200120614c0f565b9050919050565b6000613c9a8260405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120618075565b9050919050565b6000613cf38260405160200180807f63656c6f2e6f72672f636f72652f766f74650000000000000000000000000000815250601201905060405160208183030381529060405280519060200120618075565b9050919050565b613d02614eb5565b613d74576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b613e3c33612f87565b613e91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180618b276036913960400191505060405180910390fd5b613e9a82617eee565b613eef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180618bfd6022913960400191505060405180910390fd5b613ef93383617f48565b613f6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f4e6f742061207369676e657220666f722074686973206163636f756e7400000081525060200191505060405180910390fd5b613f76338383613550565b613fcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180618e1a602f913960400191505060405180910390fd5b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506140178261755e565b1561426c5760405160200180807f63656c6f2e6f72672f636f72652f766f746500000000000000000000000000008152506012019050604051602081830303815290604052805190602001208214156140b557828160010160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506141e5565b60405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e0000000000000081525060190190506040516020818303038152906040528051906020012082141561414e57828160010160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506141e4565b60405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f720000000000000000008152506017019050604051602081830303815290604052805190602001208214156141e357828160010160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b5b3373ffffffffffffffffffffffffffffffffffffffff167fc5cd67202a8095484f559b338b2b6fee0dd81af9f70c4814c6517fcf9a09564c8484604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a261437e565b82600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff167f2613ed414d18d8152e86c896c04ccce344b75a2f06141f04d39ad069a38725238484604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a25b3373ffffffffffffffffffffffffffffffffffffffff167f8a00ae3e0722558391733230bfc96d425df2dd7b44f7ce506580785adcf171a28484604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a2505050565b61440e33612f87565b614480576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f556e6b6e6f776e206163636f756e74000000000000000000000000000000000081525060200191505060405180910390fd5b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905082828260070191906144d6929190618847565b503373ffffffffffffffffffffffffffffffffffffffff167f0b5629fec5b6b5a1c2cfe0de7495111627a8cf297dced72e0669527425d3f01b848460405180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405180910390a2505050565b6008602052816000526040600020818154811061456f57fe5b90600052602060002001600091509150508054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156146145780601f106145e957610100808354040283529160200191614614565b820191906000526020600020905b8154815290600101906020018083116145f757829003601f168201915b505050505081565b600061466e3360405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e00000000000000815250601901905060405160208183030381529060405280519060200120614c0f565b90506146c08160405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e00000000000000815250601901905060405160208183030381529060405280519060200120617650565b3373ffffffffffffffffffffffffffffffffffffffff167f14670729407debb6ed03d885f8ba57155de89ce39bf17127ae4900ec7c2ad10382604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a250565b6147908460405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e00000000000000815250601901905060405160208183030381529060405280519060200120858585617ae8565b6147e08460405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e00000000000000815250601901905060405160208183030381529060405280519060200120613e33565b3373ffffffffffffffffffffffffffffffffffffffff167f9dfbc5a621c3e2d0d83beee687a17dfc796bbce2118793e5e254409bb265ca0b85604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a250505050565b600260019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006148d88260405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e00000000000000815250601901905060405160208183030381529060405280519060200120618075565b9050919050565b60006148ea8261755e565b6148fd576148f883836139f7565b614908565b6149078383614c0f565b5b905092915050565b606080600080905060608585905060405190808252806020026020018201604052801561494c5781602001602082028038833980820191505090505b50905060008090505b86869050811015614a3a576003600088888481811061497057fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206007018054600181600116156101000203166002900490508282815181106149eb57fe5b602002602001018181525050614a1d828281518110614a0657fe5b602002602001015184617d5c90919063ffffffff16565b9250614a33600182617d5c90919063ffffffff16565b9050614955565b506060826040519080825280601f01601f191660200182016040528015614a705781602001600182028038833980820191505090505b509050600080905060008090505b88889050811015614bfd5760008090505b848281518110614a9b57fe5b6020026020010151811015614be157600360008b8b85818110614aba57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060070181815460018160011615610100020316600290048110614b3057fe5b815460011615614b4f5790600052602060002090602091828204019190065b9054901a7f010000000000000000000000000000000000000000000000000000000000000002848481518110614b8157fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350614bc4600184617d5c90919063ffffffff16565b9250614bda600182617d5c90919063ffffffff16565b9050614a8f565b50614bf6600182617d5c90919063ffffffff16565b9050614a7e565b50828295509550505050509250929050565b6000614c1a8261755e565b614c8c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f526f6c65206973206e6f742061206c6567616379207369676e6572000000000081525060200191505060405180910390fd5b6000600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600060405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120841415614d4e578160010160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050614e46565b60405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e00000000000000815250601901905060405160208183030381529060405280519060200120841415614dcb578160010160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050614e45565b60405160200180807f63656c6f2e6f72672f636f72652f766f74650000000000000000000000000000815250601201905060405160208183030381529060405280519060200120841415614e44578160010160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b5b5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614614e805780614e82565b845b9250505092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16614ef76181e0565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b614f1c33612f87565b614f71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180618b276036913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415614ff7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180618c1f6021913960400191505060405180910390fd5b614fff6188c7565b615008826181e8565b9050615024615015618206565b8261822c90919063ffffffff16565b615079576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180618cf96023913960400191505060405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff16815260200182815250600960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001016000820151816000015550509050508273ffffffffffffffffffffffffffffffffffffffff167f3bff8b126c8f283f709ae37dc0d3fc03cae85ca4772cfb25b601f4b0b49ca6df836040518082815260200191505060405180910390a2505050565b61519e33612f87565b6151ac576151aa615aba565b505b6151f988888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050616c89565b61524686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061285e565b61525284848484615753565b5050505050505050565b600080600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f720000000000000000008152506017019050604051602081830303815290604052805190602001208314801561534757508373ffffffffffffffffffffffffffffffffffffffff168160010160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b156153565760019150506154c8565b60405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e00000000000000815250601901905060405160208183030381529060405280519060200120831480156153fd57508373ffffffffffffffffffffffffffffffffffffffff168160010160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b1561540c5760019150506154c8565b60405160200180807f63656c6f2e6f72672f636f72652f766f74650000000000000000000000000000815250601201905060405160208183030381529060405280519060200120831480156154b357508373ffffffffffffffffffffffffffffffffffffffff168160010160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b156154c25760019150506154c8565b60009150505b9392505050565b6154dc8585858585618242565b604051806040016040528060011515815260200160011515815250600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600086815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff021916908315150217905550905050833373ffffffffffffffffffffffffffffffffffffffff167f6cc56bd06daacce5b10fdf5ad1dc781941e14d7a71d29d33e7001e2956d14e0787604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a35050505050565b600080600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146156eb578091505061574e565b6156f483612f87565b615749576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180618b276036913960400191505060405180910390fd5b829150505b919050565b61575c33612f87565b6157ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f556e6b6e6f776e206163636f756e74000000000000000000000000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806158345750600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16145b6159b35760007369baecd458e7c08b13a18e11887dbb078fb3cbb46396ef41a1338686866040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018460ff1660ff16815260200183815260200182815260200194505050505060206040518083038186803b1580156158d357600080fd5b505af41580156158e7573d6000803e3d6000fd5b505050506040513d60208110156158fd57600080fd5b810190808051906020019092919050505090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146159b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f496e76616c6964207369676e617475726500000000000000000000000000000081525060200191505060405180910390fd5b505b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050848160040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff167ff81d74398fd47e35c36b714019df15f200f623dde569b5b531d6a0b4da5c5f2686604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a25050505050565b6000615ac533617eee565b8015615ad65750615ad533618306565b5b615b2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604d815260200180618d69604d913960600191505060405180910390fd5b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060018160000160006101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff167f805996f252884581e2f74cf3d2b03564d5ec26ccc90850ae12653dc1b72d1fa260405160405180910390a2600191505090565b6000806000600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16615c628260010160405180602001604052908160008201548152505061839d565b9250925050915091565b615c7582612f87565b615cca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604d815260200180618d1c604d913960600191505060405180910390fd5b615cd333617eee565b8015615ce55750615ce48233617f48565b5b615d3a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180618e496022913960400191505060405180910390fd5b60011515600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16151514615e51576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5369676e657220617574686f72697a6174696f6e206e6f74207374617274656481525060200191505060405180910390fd5b81600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160016101000a81548160ff021916908315150217905550808273ffffffffffffffffffffffffffffffffffffffff167f9eeca140dda0bdb74fc9acfda0f1c0324e188a732bd48e078a96b16d97eb54e533604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a35050565b60006160493360405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120614c0f565b905061609b8160405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120617650565b3373ffffffffffffffffffffffffffffffffffffffff167fa54764c62865ff0cd3f271fb1d4635662bff10f0878694f1654fb7fbdecb830d82604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a250565b6060600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206007018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156161f05780601f106161c5576101008083540402835291602001916161f0565b820191906000526020600020905b8154815290600101906020018083116161d357829003601f168201915b50505050509050919050565b616204614eb5565b616276576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415616319576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f43616e6e6f7420726567697374657220746865206e756c6c206164647265737381525060200191505060405180910390fd5b80600260016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f27fe5f0c1c3b1ed427cc63d0f05759ffdecf9aec9e18d31ef366fc8a6cb5dc3b60405160405180910390a250565b6060600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206006018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156164785780601f1061644d57610100808354040283529160200191616478565b820191906000526020600020905b81548152906001019060200180831161645b57829003601f168201915b50505050509050919050565b61648d33612f87565b6164ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f556e6b6e6f776e206163636f756e74000000000000000000000000000000000081525060200191505060405180910390fd5b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082829091806001815401808255809150509060018203906000526020600020016000909192939091929390919290919250919061657c9291906188da565b50503373ffffffffffffffffffffffffffffffffffffffff167f15dfb3066a1bbbdaf9a7f62c47db990114058ae1739fd70a90361ea715bbf3c8838360405180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405180910390a25050565b60046020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000806040518080618bc1603c9139603c0190506040518091039020888888604051602001808581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019450505050506040516020818303038152906040528051906020012090507369baecd458e7c08b13a18e11887dbb078fb3cbb46334d1a233600754838888886040518663ffffffff1660e01b8152600401808681526020018581526020018460ff1660ff1681526020018381526020018281526020019550505050505060206040518083038186803b15801561675a57600080fd5b505af415801561676e573d6000803e3d6000fd5b505050506040513d602081101561678457600080fd5b81019080805190602001909291905050509150509695505050505050565b60006167dd848484604051602001808383808284378083019250505092505050604051602081830303815290604052805190602001206177a1565b90509392505050565b60018060008282540192505081905550600060015490506168508560405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120868686617ae8565b6168a08560405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120613e33565b6168a8617c61565b73ffffffffffffffffffffffffffffffffffffffff1663facd743b336040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561692457600080fd5b505afa158015616938573d6000803e3d6000fd5b505050506040513d602081101561694e57600080fd5b8101908080519060200190929190505050156169b5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180618c866021913960400191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f16e382723fb40543364faf68863212ba253a099607bf6d3a5b47e50a8bf9494386604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a26001548114616aa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f7265656e7472616e742063616c6c00000000000000000000000000000000000081525060200191505060405180910390fd5b5050505050565b616ab633612f87565b616b0b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180618b276036913960400191505060405180910390fd5b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001616b3d60006181e8565b815250600960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101600082015181600001555050905050600073ffffffffffffffffffffffffffffffffffffffff167f3bff8b126c8f283f709ae37dc0d3fc03cae85ca4772cfb25b601f4b0b49ca6df60006040518082815260200191505060405180910390a2565b6000616c828260405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e00000000000000815250601901905060405160208183030381529060405280519060200120612b0a565b9050919050565b616c9233612f87565b616ce7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180618db6602f913960400191505060405180910390fd5b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905081816005019080519060200190616d4292919061895a565b503373ffffffffffffffffffffffffffffffffffffffff167fa6e2c5a23bb917ba0a584c4b250257ddad698685829b66a8813c004b39934fe4836040518080602001828103825283818151815260200191508051906020019080838360005b83811015616dbc578082015181840152602081019050616da1565b50505050905090810190601f168015616de95780820380516001836020036101000a031916815260200191505b509250505060405180910390a25050565b6000616e058261755e565b616e1957616e14848484612482565b616e25565b616e2484848461525c565b5b90509392505050565b600260009054906101000a900460ff1615616eb1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f636f6e747261637420616c726561647920696e697469616c697a65640000000081525060200191505060405180910390fd5b6001600260006101000a81548160ff021916908315150217905550616ed5336183ab565b616ede816161fc565b616ee6617de4565b50565b6000600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff167fe553a3065d5a77d4ec2a0e0c31d49be4bf4d9f4c45883b2d67f61ba9c1b89c5d8284604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a25050565b61707d33612f87565b6170ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f556e6b6e6f776e206163636f756e74000000000000000000000000000000000081525060200191505060405180910390fd5b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905081106171a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f496e76616c69642073746f7261676520726f6f7420696e64657800000000000081525060200191505060405180910390fd5b60006001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490500390506060600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020838154811061723c57fe5b906000526020600020018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156172da5780601f106172af576101008083540402835291602001916172da565b820191906000526020600020905b8154815290600101906020018083116172bd57829003601f168201915b50505050509050600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811061732b57fe5b90600052602060002001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020848154811061737f57fe5b9060005260206000200190805460018160011615610100020316600290046173a89291906189da565b50600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054809190600190036173fb9190618a61565b503373ffffffffffffffffffffffffffffffffffffffff167fae0f2fa495a3eb65d46fe97b0baea8b6fd7edb243175c70f2455e6e83bc6fbaf82856040518080602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561747c578082015181840152602081019050617461565b50505050905090810190601f1680156174a95780820380516001836020036101000a031916815260200191505b50935050505060405180910390a2505050565b6040518080618bc1603c9139603c019050604051809103902081565b6174e0614eb5565b617552576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61755b816183ab565b50565b600060405160200180807f63656c6f2e6f72672f636f72652f766f746500000000000000000000000000008152506012019050604051602081830303815290604052805190602001208214806175f9575060405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f7200000000000000000081525060170190506040516020818303038152906040528051906020012082145b80617649575060405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e0000000000000081525060190190506040516020818303038152906040528051906020012082145b9050919050565b61765b338383616dfa565b1561766a5761766981612386565b5b600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080820160006101000a81549060ff02191690556000820160016101000a81549060ff02191690555050803373ffffffffffffffffffffffffffffffffffffffff167fde9ce22cf1f8631ae2b668300f0493971114f40edd305173bd099ce7100fbe0b84604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a35050565b60006177ac8261755e565b6177bf576177ba838361243f565b6177ca565b6177c98383612b0a565b5b905092915050565b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600060405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f720000000000000000008152506017019050604051602081830303815290604052805190602001208314156178db578160010160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008260010160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550617a61565b60405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e0000000000000081525060190190506040516020818303038152906040528051906020012083141561799f578160010160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008260010160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550617a60565b60405160200180807f63656c6f2e6f72672f636f72652f766f74650000000000000000000000000000815250601201905060405160208183030381529060405280519060200120831415617a5f578160010160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008260010160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b5b3373ffffffffffffffffffffffffffffffffffffffff167fdd0b0d959c29750e7bfabbb7543a56957699d07edc512d2523ffe7502901ac198285604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a2505050565b617af4858484846184ef565b604051806040016040528060011515815260200160011515815250600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600086815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff021916908315150217905550905050833373ffffffffffffffffffffffffffffffffffffffff167f6cc56bd06daacce5b10fdf5ad1dc781941e14d7a71d29d33e7001e2956d14e0787604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a35050505050565b6000600260019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dcf0aaed60405160200180807f56616c696461746f727300000000000000000000000000000000000000000000815250600a019050604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015617d1c57600080fd5b505afa158015617d30573d6000803e3d6000fd5b505050506040513d6020811015617d4657600080fd5b8101908080519060200190929190505050905090565b600080828401905083811015617dda576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60004690506040518080618ca760529139605201905060405180910390206040518060400160405280601381526020017f43656c6f20436f726520436f6e747261637473000000000000000000000000008152508051906020012060405180807f312e300000000000000000000000000000000000000000000000000000000000815250600301905060405180910390208330604051602001808681526020018581526020018481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001955050505050506040516020818303038152906040528051906020012060078190555050565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16159050919050565b60008073ffffffffffffffffffffffffffffffffffffffff16600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16148061806d57508273ffffffffffffffffffffffffffffffffffffffff16600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b905092915050565b600080600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461817757618119818585613550565b61816e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180618e6b6025913960400191505060405180910390fd5b809150506181da565b61818084612f87565b6181d5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180618b276036913960400191505060405180910390fd5b839150505b92915050565b600033905090565b6181f06188c7565b6040518060200160405280838152509050919050565b61820e6188c7565b604051806020016040528069d3c21bcecceda1000000815250905090565b6000816000015183600001511115905092915050565b600061825233878787878761662f565b90508573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146182f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f496e76616c6964207369676e617475726500000000000000000000000000000081525060200191505060405180910390fd5b6182fe86618678565b505050505050565b60008073ffffffffffffffffffffffffffffffffffffffff16600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16149050919050565b600081600001519050919050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415618431576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180618b9b6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60007369baecd458e7c08b13a18e11887dbb078fb3cbb46396ef41a1338686866040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018460ff1660ff16815260200183815260200182815260200194505050505060206040518083038186803b15801561858a57600080fd5b505af415801561859e573d6000803e3d6000fd5b505050506040513d60208110156185b457600080fd5b810190808051906020019092919050505090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614618668576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f496e76616c6964207369676e617475726500000000000000000000000000000081525060200191505060405180910390fd5b61867185618678565b5050505050565b61868133612f87565b6186d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603e815260200180618b5d603e913960400191505060405180910390fd5b6186df81617eee565b80156186f157506186f03382617f48565b5b618746576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526046815260200180618c406046913960600191505060405180910390fd5b33600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061880857805160ff1916838001178555618836565b82800160010185558215618836579182015b8281111561883557825182559160200191906001019061881a565b5b5090506188439190618a8d565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061888857803560ff19168380011785556188b6565b828001600101855582156188b6579182015b828111156188b557823582559160200191906001019061889a565b5b5090506188c39190618a8d565b5090565b6040518060200160405280600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061891b57803560ff1916838001178555618949565b82800160010185558215618949579182015b8281111561894857823582559160200191906001019061892d565b5b5090506189569190618a8d565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061899b57805160ff19168380011785556189c9565b828001600101855582156189c9579182015b828111156189c85782518255916020019190600101906189ad565b5b5090506189d69190618a8d565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10618a135780548555618a50565b82800160010185558215618a5057600052602060002091601f016020900482015b82811115618a4f578254825591600101919060010190618a34565b5b509050618a5d9190618a8d565b5090565b815481835581811115618a8857818360005260206000209182019101618a879190618ab2565b5b505050565b618aaf91905b80821115618aab576000816000905550600101618a93565b5090565b90565b618adb91905b80821115618ad75760008181618ace9190618ade565b50600101618ab8565b5090565b90565b50805460018160011615610100020316600290046000825580601f10618b045750618b23565b601f016020900490600052602060002090810190618b229190618a8d565b5b5056fe4d75737420666972737420726567697374657220616464726573732077697468204163636f756e742e6372656174654163636f756e74556e6b6e6f776e206163636f756e743a2073656e646572206d7573742072656769737465722077697468206372656174654163636f756e742066697273744f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373417574686f72697a655369676e65722861646472657373206163636f756e742c61646472657373207369676e65722c6279746573333220726f6c652943616e6e6f7420617574686f72697a65206163636f756e74206173207369676e657242656e65666963696172792063616e6e6f7420626520616464726573732030783043616e6e6f742072652d617574686f72697a652061646472657373206f72206c6f636b656420676f6c64206163636f756e7420666f7220616e6f74686572206163636f756e7443616e6e6f7420617574686f72697a652076616c696461746f72207369676e6572454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e7472616374294672616374696f6e206d757374206e6f742062652067726561746572207468616e2031556e6b6e6f776e204163636f756e743a2041646472657373207468617420617574686f72697a6564207369676e696e67206d75737420626520612072656769737465726564204163636f756e744163636f756e7420616c726561647920657869737473206f72206164647265737320697320616e20617574686f72697a6564207369676e657220666f7220616e6f74686572206163636f756e7452656769737465722077697468206372656174654163636f756e7420746f20736574206163636f756e74206e616d654d7573742066697273742072656769737465722073656e6465722077697468204163636f756e742e6372656174654163636f756e744d75737420617574686f72697a65207369676e6572206265666f72652073657474696e672061732064656661756c7443616e6e6f742072652d617574686f72697a652061646472657373207369676e65726e6f742061637469766520617574686f72697a6564207369676e657220666f7220726f6c654661696c656420746f20757064617465204543445341207075626c6963206b6579a265627a7a723158207c28a7af2b1123bc80eebe4a2a490d55f0b9361f3f692ad30c5d861d4245837764736f6c634300050d00320000000000000000000000000000000000000000000000000000000000000001
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061041d5760003560e01c80637b2434cb1161022b578063ae32fa0e11610130578063c48830d9116100b8578063f0c5658411610087578063f0c56584146121d1578063f2fde38b146121ef578063f333d83614612233578063fbe3c37314612279578063ff836d93146122c75761041d565b8063c48830d9146120ab578063c4d66de814612131578063e7a16e6b14612175578063e8d787cb146121a35761041d565b8063ba40e4f6116100ff578063ba40e4f614611e74578063baf7ef0f14611f25578063bce2b8d614611f8a578063c2e0ee2014611f94578063c47f002714611ff05761041d565b8063ae32fa0e14611beb578063b062c84314611ca8578063b5a664c214611d21578063b6c6662514611da55761041d565b806392f90fbf116101b35780639f024f4b116101825780639f024f4b14611a075780639f68297614611a92578063a5ec94f914611ae0578063a8ae1a3d14611aea578063a91ee0dc14611ba75761041d565b806392f90fbf1461188d57806393c5c487146118fc5780639cafb2a1146119805780639dca362f146119e55761041d565b80638da5cb5b116101fa5780638da5cb5b1461163e5780638f32d59b146116885780638f9ae6dc146116aa57806390b12b47146116f857806391cd074b146118075761041d565b80637b2434cb1461136457806387affe68146113e85780638adaf96f146114765780638bceca58146115b05761041d565b806349045e161161033157806364439b43116102b9578063747daec511610288578063747daec51461116b57806376082c1f146111e4578063760fbbb2146112ab57806376afa04c146112b55780637b1039991461131a5761041d565b806364439b431461100b5780636642d5941461108f578063715018a614611113578063727d079c1461111d5761041d565b80635b07fdd8116103005780635b07fdd814610dc25780635b6d900414610de05780635fd4b08a14610e6e578063614ed49314610f2b57806361bab1ae14610f875761041d565b806349045e1614610c615780634ce38b5f14610cbd57806354255be014610d4157806358b81ea814610d745761041d565b80631465b923116103b4578063289a131811610383578063289a1318146109e35780633184b3c514610ae857806341ddd88014610af25780634282ee6d14610b76578063485a46d114610bdb5761041d565b80631465b9231461077d578063158ef93e146108e15780631fd9afa51461090357806325ca4c9c146109875761041d565b80630fa750d2116103f05780630fa750d2146105985780630fe7abab1461065257806310c504b51461070d5780631441ece7146107175761041d565b80630127dbed146104225780630185a2321461047e57806305be6229146104ac5780630b8e056214610512575b600080fd5b6104646004803603602081101561043857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061232d565b604051808215151515815260200191505060405180910390f35b6104aa6004803603602081101561049457600080fd5b8101908080359060200190929190505050612386565b005b6104f8600480360360408110156104c257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061243f565b604051808215151515815260200191505060405180910390f35b61057e6004803603606081101561052857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612482565b604051808215151515815260200191505060405180910390f35b610650600480360360a08110156105ae57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff16906020019092919080359060200190929190803590602001909291908035906020019064010000000081111561060c57600080fd5b82018360208201111561061e57600080fd5b8035906020019184600183028401116401000000008311171561064057600080fd5b909192939192939050505061252c565b005b61070b6004803603602081101561066857600080fd5b810190808035906020019064010000000081111561068557600080fd5b82018360208201111561069757600080fd5b803590602001918460018302840111640100000000831117156106b957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061285e565b005b6107156129e9565b005b6107636004803603604081101561072d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612b0a565b604051808215151515815260200191505060405180910390f35b6108df600480360360e081101561079357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff1690602001909291908035906020019092919080359060200190929190803590602001906401000000008111156107f157600080fd5b82018360208201111561080357600080fd5b8035906020019184600183028401116401000000008311171561082557600080fd5b90919293919293908035906020019064010000000081111561084657600080fd5b82018360208201111561085857600080fd5b8035906020019184600183028401116401000000008311171561087a57600080fd5b90919293919293908035906020019064010000000081111561089b57600080fd5b8201836020820111156108ad57600080fd5b803590602001918460018302840111640100000000831117156108cf57600080fd5b9091929391929390505050612b4d565b005b6108e9612f08565b604051808215151515815260200191505060405180910390f35b6109456004803603602081101561091957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f1b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6109c96004803603602081101561099d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f87565b604051808215151515815260200191505060405180910390f35b610a25600480360360208110156109f957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612fe0565b604051808060200180602001838103835285818151815260200191508051906020019080838360005b83811015610a69578082015181840152602081019050610a4e565b50505050905090810190601f168015610a965780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019060200280838360005b83811015610ad2578082015181840152602081019050610ab7565b5050505090500194505050505060405180910390f35b610af061333b565b005b610b3460048036036020811015610b0857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613345565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610bd960048036036080811015610b8c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff169060200190929190803590602001909291908035906020019092919050505061339e565b005b610c4760048036036060811015610bf157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613550565b604051808215151515815260200191505060405180910390f35b610ca360048036036020811015610c7757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506136a1565b604051808215151515815260200191505060405180910390f35b610cff60048036036020811015610cd357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613739565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610d49613792565b6040518085815260200184815260200183815260200182815260200194505050505060405180910390f35b610dc060048036036040811015610d8a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506137b9565b005b610dca6139f1565b6040518082815260200191505060405180910390f35b610e2c60048036036040811015610df657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506139f7565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610eb060048036036020811015610e8457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613ab2565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610ef0578082015181840152602081019050610ed5565b50505050905090810190601f168015610f1d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610f6d60048036036020811015610f4157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613b96565b604051808215151515815260200191505060405180910390f35b610fc960048036036020811015610f9d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613bef565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61104d6004803603602081101561102157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613c48565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6110d1600480360360208110156110a557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613ca1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61111b613cfa565b005b6111696004803603604081101561113357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613e33565b005b6111e26004803603602081101561118157600080fd5b810190808035906020019064010000000081111561119e57600080fd5b8201836020820111156111b057600080fd5b803590602001918460018302840111640100000000831117156111d257600080fd5b9091929391929390505050614405565b005b611230600480360360408110156111fa57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614556565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611270578082015181840152602081019050611255565b50505050905090810190601f16801561129d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6112b361461c565b005b611318600480360360808110156112cb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff169060200190929190803590602001909291908035906020019092919050505061473d565b005b611322614860565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6113a66004803603602081101561137a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614886565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b611434600480360360408110156113fe57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506148df565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6114ed6004803603602081101561148c57600080fd5b81019080803590602001906401000000008111156114a957600080fd5b8201836020820111156114bb57600080fd5b803590602001918460208302840111640100000000831117156114dd57600080fd5b9091929391929390505050614910565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015611534578082015181840152602081019050611519565b50505050905001838103825284818151815260200191508051906020019080838360005b83811015611573578082015181840152602081019050611558565b50505050905090810190601f1680156115a05780820380516001836020036101000a031916815260200191505b5094505050505060405180910390f35b6115fc600480360360408110156115c657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614c0f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b611646614e8c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b611690614eb5565b604051808215151515815260200191505060405180910390f35b6116f6600480360360408110156116c057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614f13565b005b611805600480360360c081101561170e57600080fd5b810190808035906020019064010000000081111561172b57600080fd5b82018360208201111561173d57600080fd5b8035906020019184600183028401116401000000008311171561175f57600080fd5b90919293919293908035906020019064010000000081111561178057600080fd5b82018360208201111561179257600080fd5b803590602001918460018302840111640100000000831117156117b457600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff1690602001909291908035906020019092919080359060200190929190505050615195565b005b6118736004803603606081101561181d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061525c565b604051808215151515815260200191505060405180910390f35b6118fa600480360360a08110156118a357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803560ff16906020019092919080359060200190929190803590602001909291905050506154cf565b005b61193e6004803603602081101561191257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050615649565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6119e36004803603608081101561199657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff1690602001909291908035906020019092919080359060200190929190505050615753565b005b6119ed615aba565b604051808215151515815260200191505060405180910390f35b611a4960048036036020811015611a1d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050615bd6565b604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390f35b611ade60048036036040811015611aa857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050615c6c565b005b611ae8615ff7565b005b611b2c60048036036020811015611b0057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050616118565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611b6c578082015181840152602081019050611b51565b50505050905090810190601f168015611b995780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b611be960048036036020811015611bbd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506161fc565b005b611c2d60048036036020811015611c0157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506163a0565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611c6d578082015181840152602081019050611c52565b50505050905090810190601f168015611c9a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b611d1f60048036036020811015611cbe57600080fd5b8101908080359060200190640100000000811115611cdb57600080fd5b820183602082011115611ced57600080fd5b80359060200191846001830284011164010000000083111715611d0f57600080fd5b9091929391929390505050616484565b005b611d6360048036036020811015611d3757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506165fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b611e32600480360360c0811015611dbb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803560ff169060200190929190803590602001909291908035906020019092919050505061662f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b611f0b60048036036040811015611e8a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115611ec757600080fd5b820183602082011115611ed957600080fd5b80359060200191846001830284011164010000000083111715611efb57600080fd5b90919293919293905050506167a2565b604051808215151515815260200191505060405180910390f35b611f8860048036036080811015611f3b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff16906020019092919080359060200190929190803590602001909291905050506167e6565b005b611f92616aad565b005b611fd660048036036020811015611faa57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050616c30565b604051808215151515815260200191505060405180910390f35b6120a96004803603602081101561200657600080fd5b810190808035906020019064010000000081111561202357600080fd5b82018360208201111561203557600080fd5b8035906020019184600183028401116401000000008311171561205757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050616c89565b005b612117600480360360608110156120c157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050616dfa565b604051808215151515815260200191505060405180910390f35b6121736004803603602081101561214757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050616e2e565b005b6121a16004803603602081101561218b57600080fd5b8101908080359060200190929190505050616ee9565b005b6121cf600480360360208110156121b957600080fd5b8101908080359060200190929190505050617074565b005b6121d96174bc565b6040518082815260200191505060405180910390f35b6122316004803603602081101561220557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506174d8565b005b61225f6004803603602081101561224957600080fd5b810190808035906020019092919050505061755e565b604051808215151515815260200191505060405180910390f35b6122c56004803603604081101561228f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050617650565b005b612313600480360360408110156122dd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506177a1565b604051808215151515815260200191505060405180910390f35b600061237f8260405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120612b0a565b9050919050565b600061239233836148df565b905061239d8261755e565b6123af576123aa82616ee9565b6123b9565b6123b8826177d2565b5b3373ffffffffffffffffffffffffffffffffffffffff167fccc97b55d227538f487c521e1218ba74768b73d088310238027c2ae3b43e9c918284604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a25050565b60008273ffffffffffffffffffffffffffffffffffffffff1661246284846139f7565b73ffffffffffffffffffffffffffffffffffffffff161415905092915050565b60008273ffffffffffffffffffffffffffffffffffffffff16600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161490509392505050565b60018060008282540192505081905550600060015490506125968760405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120888888617ae8565b6125e68760405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120613e33565b6125ee617c61565b73ffffffffffffffffffffffffffffffffffffffff16634e06fd8a338986866040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050602060405180830381600087803b1580156126d457600080fd5b505af11580156126e8573d6000803e3d6000fd5b505050506040513d60208110156126fe57600080fd5b8101908080519060200190929190505050612764576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180618e906021913960400191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f16e382723fb40543364faf68863212ba253a099607bf6d3a5b47e50a8bf9494388604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a26001548114612855576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f7265656e7472616e742063616c6c00000000000000000000000000000000000081525060200191505060405180910390fd5b50505050505050565b6021815110156128d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f6461746120656e6372797074696f6e206b6579206c656e677468203c3d20333281525060200191505060405180910390fd5b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050818160060190805190602001906129319291906187c7565b503373ffffffffffffffffffffffffffffffffffffffff167f43fdefe0a824cb0e3bbaf9c4bc97669187996136fe9282382baf10787f0d808d836040518080602001828103825283818151815260200191508051906020019080838360005b838110156129ab578082015181840152602081019050612990565b50505050905090810190601f1680156129d85780820380516001836020036101000a031916815260200191505b509250505060405180910390a25050565b6000612a3b3360405160200180807f63656c6f2e6f72672f636f72652f766f74650000000000000000000000000000815250601201905060405160208183030381529060405280519060200120614c0f565b9050612a8d8160405160200180807f63656c6f2e6f72672f636f72652f766f74650000000000000000000000000000815250601201905060405160208183030381529060405280519060200120617650565b3373ffffffffffffffffffffffffffffffffffffffff167fa197481f404d8a8082368ad7445380f01e75f27dea6b7aef234a4ce071127fae82604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a250565b60008273ffffffffffffffffffffffffffffffffffffffff16612b2d8484614c0f565b73ffffffffffffffffffffffffffffffffffffffff161415905092915050565b6001806000828254019250508190555060006001549050612bb78b60405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f720000000000000000008152506017019050604051602081830303815290604052805190602001208c8c8c617ae8565b612c078b60405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120613e33565b612c0f617c61565b73ffffffffffffffffffffffffffffffffffffffff1663713ea0f3338d8a8a8a8a8a8a6040518963ffffffff1660e01b8152600401808973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001806020018060200184810384528a8a82818152602001925080828437600081840152601f19601f8201169050808301925050508481038352888882818152602001925080828437600081840152601f19601f8201169050808301925050508481038252868682818152602001925080828437600081840152601f19601f8201169050808301925050509b505050505050505050505050602060405180830381600087803b158015612d5d57600080fd5b505af1158015612d71573d6000803e3d6000fd5b505050506040513d6020811015612d8757600080fd5b8101908080519060200190929190505050612e0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4661696c656420746f207570646174652076616c696461746f72206b6579730081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f16e382723fb40543364faf68863212ba253a099607bf6d3a5b47e50a8bf949438c604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a26001548114612efb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f7265656e7472616e742063616c6c00000000000000000000000000000000000081525060200191505060405180910390fd5b5050505050505050505050565b600260009054906101000a900460ff1681565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff169050919050565b606080612fec83612f87565b61305e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f556e6b6e6f776e206163636f756e74000000000000000000000000000000000081525060200191505060405180910390fd5b6000600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050600080905060008090505b8281101561314257613133600860008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811061310557fe5b9060005260206000200180546001816001161561010002031660029004905083617d5c90919063ffffffff16565b915080806001019150506130b0565b506060816040519080825280601f01601f1916602001820160405280156131785781602001600182028038833980820191505090505b50905060008090506060846040519080825280602002602001820160405280156131b15781602001602082028038833980820191505090505b50905060008090505b8581101561332a576000600860008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811061320e57fe5b9060005260206000200190508080546001816001161561010002031660029004905083838151811061323c57fe5b60200260200101818152505060008090505b83838151811061325a57fe5b602002602001015181101561331b57818181546001816001161561010002031660029004811061328657fe5b8154600116156132a55790600052602060002090602091828204019190065b9054901a7f0100000000000000000000000000000000000000000000000000000000000000028686815181106132d757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508480600101955050808060010191505061324e565b505080806001019150506131ba565b508281965096505050505050915091565b613343617de4565b565b60006133978260405160200180807f63656c6f2e6f72672f636f72652f766f74650000000000000000000000000000815250601201905060405160208183030381529060405280519060200120614c0f565b9050919050565b60018060008282540192505081905550600060015490506134088560405160200180807f63656c6f2e6f72672f636f72652f766f74650000000000000000000000000000815250601201905060405160208183030381529060405280519060200120868686617ae8565b6134588560405160200180807f63656c6f2e6f72672f636f72652f766f74650000000000000000000000000000815250601201905060405160208183030381529060405280519060200120613e33565b3373ffffffffffffffffffffffffffffffffffffffff167faab5f8a189373aaa290f42ae65ea5d7971b732366ca5bf66556e76263944af2886604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a26001548114613549576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f7265656e7472616e742063616c6c00000000000000000000000000000000000081525060200191505060405180910390fd5b5050505050565b600061355d84848461525c565b806136985750600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160019054906101000a900460ff16801561369757508373ffffffffffffffffffffffffffffffffffffffff16600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b60008073ffffffffffffffffffffffffffffffffffffffff16600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b600061378b8260405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120614c0f565b9050919050565b60008060008060018060046002839350829250819150809050935093509350935090919293565b6137c233612f87565b613817576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526035815260200180618de56035913960400191505060405180910390fd5b61382082617eee565b801561383257506138313383617f48565b5b613887576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180618e496022913960400191505060405180910390fd5b604051806040016040528060011515815260200160001515815250600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff021916908315150217905550905050803373ffffffffffffffffffffffffffffffffffffffff167f7a162218a1b7bec7fb15b4bb95220fbf423fa3a49718133f5c50361ff1c8537684604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a35050565b60075481565b600080600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613aa75780613aa9565b835b91505092915050565b6060600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206005018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015613b8a5780601f10613b5f57610100808354040283529160200191613b8a565b820191906000526020600020905b815481529060010190602001808311613b6d57829003601f168201915b50505050509050919050565b6000613be88260405160200180807f63656c6f2e6f72672f636f72652f766f74650000000000000000000000000000815250601201905060405160208183030381529060405280519060200120612b0a565b9050919050565b6000613c418260405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e00000000000000815250601901905060405160208183030381529060405280519060200120614c0f565b9050919050565b6000613c9a8260405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120618075565b9050919050565b6000613cf38260405160200180807f63656c6f2e6f72672f636f72652f766f74650000000000000000000000000000815250601201905060405160208183030381529060405280519060200120618075565b9050919050565b613d02614eb5565b613d74576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b613e3c33612f87565b613e91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180618b276036913960400191505060405180910390fd5b613e9a82617eee565b613eef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180618bfd6022913960400191505060405180910390fd5b613ef93383617f48565b613f6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f4e6f742061207369676e657220666f722074686973206163636f756e7400000081525060200191505060405180910390fd5b613f76338383613550565b613fcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180618e1a602f913960400191505060405180910390fd5b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506140178261755e565b1561426c5760405160200180807f63656c6f2e6f72672f636f72652f766f746500000000000000000000000000008152506012019050604051602081830303815290604052805190602001208214156140b557828160010160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506141e5565b60405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e0000000000000081525060190190506040516020818303038152906040528051906020012082141561414e57828160010160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506141e4565b60405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f720000000000000000008152506017019050604051602081830303815290604052805190602001208214156141e357828160010160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b5b3373ffffffffffffffffffffffffffffffffffffffff167fc5cd67202a8095484f559b338b2b6fee0dd81af9f70c4814c6517fcf9a09564c8484604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a261437e565b82600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff167f2613ed414d18d8152e86c896c04ccce344b75a2f06141f04d39ad069a38725238484604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a25b3373ffffffffffffffffffffffffffffffffffffffff167f8a00ae3e0722558391733230bfc96d425df2dd7b44f7ce506580785adcf171a28484604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a2505050565b61440e33612f87565b614480576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f556e6b6e6f776e206163636f756e74000000000000000000000000000000000081525060200191505060405180910390fd5b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905082828260070191906144d6929190618847565b503373ffffffffffffffffffffffffffffffffffffffff167f0b5629fec5b6b5a1c2cfe0de7495111627a8cf297dced72e0669527425d3f01b848460405180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405180910390a2505050565b6008602052816000526040600020818154811061456f57fe5b90600052602060002001600091509150508054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156146145780601f106145e957610100808354040283529160200191614614565b820191906000526020600020905b8154815290600101906020018083116145f757829003601f168201915b505050505081565b600061466e3360405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e00000000000000815250601901905060405160208183030381529060405280519060200120614c0f565b90506146c08160405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e00000000000000815250601901905060405160208183030381529060405280519060200120617650565b3373ffffffffffffffffffffffffffffffffffffffff167f14670729407debb6ed03d885f8ba57155de89ce39bf17127ae4900ec7c2ad10382604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a250565b6147908460405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e00000000000000815250601901905060405160208183030381529060405280519060200120858585617ae8565b6147e08460405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e00000000000000815250601901905060405160208183030381529060405280519060200120613e33565b3373ffffffffffffffffffffffffffffffffffffffff167f9dfbc5a621c3e2d0d83beee687a17dfc796bbce2118793e5e254409bb265ca0b85604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a250505050565b600260019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006148d88260405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e00000000000000815250601901905060405160208183030381529060405280519060200120618075565b9050919050565b60006148ea8261755e565b6148fd576148f883836139f7565b614908565b6149078383614c0f565b5b905092915050565b606080600080905060608585905060405190808252806020026020018201604052801561494c5781602001602082028038833980820191505090505b50905060008090505b86869050811015614a3a576003600088888481811061497057fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206007018054600181600116156101000203166002900490508282815181106149eb57fe5b602002602001018181525050614a1d828281518110614a0657fe5b602002602001015184617d5c90919063ffffffff16565b9250614a33600182617d5c90919063ffffffff16565b9050614955565b506060826040519080825280601f01601f191660200182016040528015614a705781602001600182028038833980820191505090505b509050600080905060008090505b88889050811015614bfd5760008090505b848281518110614a9b57fe5b6020026020010151811015614be157600360008b8b85818110614aba57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060070181815460018160011615610100020316600290048110614b3057fe5b815460011615614b4f5790600052602060002090602091828204019190065b9054901a7f010000000000000000000000000000000000000000000000000000000000000002848481518110614b8157fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350614bc4600184617d5c90919063ffffffff16565b9250614bda600182617d5c90919063ffffffff16565b9050614a8f565b50614bf6600182617d5c90919063ffffffff16565b9050614a7e565b50828295509550505050509250929050565b6000614c1a8261755e565b614c8c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f526f6c65206973206e6f742061206c6567616379207369676e6572000000000081525060200191505060405180910390fd5b6000600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600060405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120841415614d4e578160010160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050614e46565b60405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e00000000000000815250601901905060405160208183030381529060405280519060200120841415614dcb578160010160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050614e45565b60405160200180807f63656c6f2e6f72672f636f72652f766f74650000000000000000000000000000815250601201905060405160208183030381529060405280519060200120841415614e44578160010160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b5b5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614614e805780614e82565b845b9250505092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16614ef76181e0565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b614f1c33612f87565b614f71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180618b276036913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415614ff7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180618c1f6021913960400191505060405180910390fd5b614fff6188c7565b615008826181e8565b9050615024615015618206565b8261822c90919063ffffffff16565b615079576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180618cf96023913960400191505060405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff16815260200182815250600960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001016000820151816000015550509050508273ffffffffffffffffffffffffffffffffffffffff167f3bff8b126c8f283f709ae37dc0d3fc03cae85ca4772cfb25b601f4b0b49ca6df836040518082815260200191505060405180910390a2505050565b61519e33612f87565b6151ac576151aa615aba565b505b6151f988888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050616c89565b61524686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061285e565b61525284848484615753565b5050505050505050565b600080600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f720000000000000000008152506017019050604051602081830303815290604052805190602001208314801561534757508373ffffffffffffffffffffffffffffffffffffffff168160010160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b156153565760019150506154c8565b60405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e00000000000000815250601901905060405160208183030381529060405280519060200120831480156153fd57508373ffffffffffffffffffffffffffffffffffffffff168160010160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b1561540c5760019150506154c8565b60405160200180807f63656c6f2e6f72672f636f72652f766f74650000000000000000000000000000815250601201905060405160208183030381529060405280519060200120831480156154b357508373ffffffffffffffffffffffffffffffffffffffff168160010160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b156154c25760019150506154c8565b60009150505b9392505050565b6154dc8585858585618242565b604051806040016040528060011515815260200160011515815250600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600086815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff021916908315150217905550905050833373ffffffffffffffffffffffffffffffffffffffff167f6cc56bd06daacce5b10fdf5ad1dc781941e14d7a71d29d33e7001e2956d14e0787604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a35050505050565b600080600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146156eb578091505061574e565b6156f483612f87565b615749576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180618b276036913960400191505060405180910390fd5b829150505b919050565b61575c33612f87565b6157ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f556e6b6e6f776e206163636f756e74000000000000000000000000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806158345750600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16145b6159b35760007369baecd458e7c08b13a18e11887dbb078fb3cbb46396ef41a1338686866040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018460ff1660ff16815260200183815260200182815260200194505050505060206040518083038186803b1580156158d357600080fd5b505af41580156158e7573d6000803e3d6000fd5b505050506040513d60208110156158fd57600080fd5b810190808051906020019092919050505090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146159b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f496e76616c6964207369676e617475726500000000000000000000000000000081525060200191505060405180910390fd5b505b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050848160040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff167ff81d74398fd47e35c36b714019df15f200f623dde569b5b531d6a0b4da5c5f2686604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a25050505050565b6000615ac533617eee565b8015615ad65750615ad533618306565b5b615b2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604d815260200180618d69604d913960600191505060405180910390fd5b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060018160000160006101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff167f805996f252884581e2f74cf3d2b03564d5ec26ccc90850ae12653dc1b72d1fa260405160405180910390a2600191505090565b6000806000600960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16615c628260010160405180602001604052908160008201548152505061839d565b9250925050915091565b615c7582612f87565b615cca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604d815260200180618d1c604d913960600191505060405180910390fd5b615cd333617eee565b8015615ce55750615ce48233617f48565b5b615d3a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180618e496022913960400191505060405180910390fd5b60011515600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16151514615e51576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5369676e657220617574686f72697a6174696f6e206e6f74207374617274656481525060200191505060405180910390fd5b81600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160016101000a81548160ff021916908315150217905550808273ffffffffffffffffffffffffffffffffffffffff167f9eeca140dda0bdb74fc9acfda0f1c0324e188a732bd48e078a96b16d97eb54e533604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a35050565b60006160493360405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120614c0f565b905061609b8160405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120617650565b3373ffffffffffffffffffffffffffffffffffffffff167fa54764c62865ff0cd3f271fb1d4635662bff10f0878694f1654fb7fbdecb830d82604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a250565b6060600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206007018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156161f05780601f106161c5576101008083540402835291602001916161f0565b820191906000526020600020905b8154815290600101906020018083116161d357829003601f168201915b50505050509050919050565b616204614eb5565b616276576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415616319576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f43616e6e6f7420726567697374657220746865206e756c6c206164647265737381525060200191505060405180910390fd5b80600260016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f27fe5f0c1c3b1ed427cc63d0f05759ffdecf9aec9e18d31ef366fc8a6cb5dc3b60405160405180910390a250565b6060600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206006018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156164785780601f1061644d57610100808354040283529160200191616478565b820191906000526020600020905b81548152906001019060200180831161645b57829003601f168201915b50505050509050919050565b61648d33612f87565b6164ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f556e6b6e6f776e206163636f756e74000000000000000000000000000000000081525060200191505060405180910390fd5b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082829091806001815401808255809150509060018203906000526020600020016000909192939091929390919290919250919061657c9291906188da565b50503373ffffffffffffffffffffffffffffffffffffffff167f15dfb3066a1bbbdaf9a7f62c47db990114058ae1739fd70a90361ea715bbf3c8838360405180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405180910390a25050565b60046020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000806040518080618bc1603c9139603c0190506040518091039020888888604051602001808581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019450505050506040516020818303038152906040528051906020012090507369baecd458e7c08b13a18e11887dbb078fb3cbb46334d1a233600754838888886040518663ffffffff1660e01b8152600401808681526020018581526020018460ff1660ff1681526020018381526020018281526020019550505050505060206040518083038186803b15801561675a57600080fd5b505af415801561676e573d6000803e3d6000fd5b505050506040513d602081101561678457600080fd5b81019080805190602001909291905050509150509695505050505050565b60006167dd848484604051602001808383808284378083019250505092505050604051602081830303815290604052805190602001206177a1565b90509392505050565b60018060008282540192505081905550600060015490506168508560405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120868686617ae8565b6168a08560405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f72000000000000000000815250601701905060405160208183030381529060405280519060200120613e33565b6168a8617c61565b73ffffffffffffffffffffffffffffffffffffffff1663facd743b336040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561692457600080fd5b505afa158015616938573d6000803e3d6000fd5b505050506040513d602081101561694e57600080fd5b8101908080519060200190929190505050156169b5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180618c866021913960400191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f16e382723fb40543364faf68863212ba253a099607bf6d3a5b47e50a8bf9494386604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a26001548114616aa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f7265656e7472616e742063616c6c00000000000000000000000000000000000081525060200191505060405180910390fd5b5050505050565b616ab633612f87565b616b0b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180618b276036913960400191505060405180910390fd5b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001616b3d60006181e8565b815250600960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101600082015181600001555050905050600073ffffffffffffffffffffffffffffffffffffffff167f3bff8b126c8f283f709ae37dc0d3fc03cae85ca4772cfb25b601f4b0b49ca6df60006040518082815260200191505060405180910390a2565b6000616c828260405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e00000000000000815250601901905060405160208183030381529060405280519060200120612b0a565b9050919050565b616c9233612f87565b616ce7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180618db6602f913960400191505060405180910390fd5b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905081816005019080519060200190616d4292919061895a565b503373ffffffffffffffffffffffffffffffffffffffff167fa6e2c5a23bb917ba0a584c4b250257ddad698685829b66a8813c004b39934fe4836040518080602001828103825283818151815260200191508051906020019080838360005b83811015616dbc578082015181840152602081019050616da1565b50505050905090810190601f168015616de95780820380516001836020036101000a031916815260200191505b509250505060405180910390a25050565b6000616e058261755e565b616e1957616e14848484612482565b616e25565b616e2484848461525c565b5b90509392505050565b600260009054906101000a900460ff1615616eb1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f636f6e747261637420616c726561647920696e697469616c697a65640000000081525060200191505060405180910390fd5b6001600260006101000a81548160ff021916908315150217905550616ed5336183ab565b616ede816161fc565b616ee6617de4565b50565b6000600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff167fe553a3065d5a77d4ec2a0e0c31d49be4bf4d9f4c45883b2d67f61ba9c1b89c5d8284604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a25050565b61707d33612f87565b6170ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f556e6b6e6f776e206163636f756e74000000000000000000000000000000000081525060200191505060405180910390fd5b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905081106171a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f496e76616c69642073746f7261676520726f6f7420696e64657800000000000081525060200191505060405180910390fd5b60006001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490500390506060600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020838154811061723c57fe5b906000526020600020018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156172da5780601f106172af576101008083540402835291602001916172da565b820191906000526020600020905b8154815290600101906020018083116172bd57829003601f168201915b50505050509050600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811061732b57fe5b90600052602060002001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020848154811061737f57fe5b9060005260206000200190805460018160011615610100020316600290046173a89291906189da565b50600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054809190600190036173fb9190618a61565b503373ffffffffffffffffffffffffffffffffffffffff167fae0f2fa495a3eb65d46fe97b0baea8b6fd7edb243175c70f2455e6e83bc6fbaf82856040518080602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561747c578082015181840152602081019050617461565b50505050905090810190601f1680156174a95780820380516001836020036101000a031916815260200191505b50935050505060405180910390a2505050565b6040518080618bc1603c9139603c019050604051809103902081565b6174e0614eb5565b617552576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61755b816183ab565b50565b600060405160200180807f63656c6f2e6f72672f636f72652f766f746500000000000000000000000000008152506012019050604051602081830303815290604052805190602001208214806175f9575060405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f7200000000000000000081525060170190506040516020818303038152906040528051906020012082145b80617649575060405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e0000000000000081525060190190506040516020818303038152906040528051906020012082145b9050919050565b61765b338383616dfa565b1561766a5761766981612386565b5b600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080820160006101000a81549060ff02191690556000820160016101000a81549060ff02191690555050803373ffffffffffffffffffffffffffffffffffffffff167fde9ce22cf1f8631ae2b668300f0493971114f40edd305173bd099ce7100fbe0b84604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a35050565b60006177ac8261755e565b6177bf576177ba838361243f565b6177ca565b6177c98383612b0a565b5b905092915050565b6000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600060405160200180807f63656c6f2e6f72672f636f72652f76616c696461746f720000000000000000008152506017019050604051602081830303815290604052805190602001208314156178db578160010160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008260010160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550617a61565b60405160200180807f63656c6f2e6f72672f636f72652f6174746573746174696f6e0000000000000081525060190190506040516020818303038152906040528051906020012083141561799f578160010160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008260010160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550617a60565b60405160200180807f63656c6f2e6f72672f636f72652f766f74650000000000000000000000000000815250601201905060405160208183030381529060405280519060200120831415617a5f578160010160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008260010160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b5b3373ffffffffffffffffffffffffffffffffffffffff167fdd0b0d959c29750e7bfabbb7543a56957699d07edc512d2523ffe7502901ac198285604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a2505050565b617af4858484846184ef565b604051806040016040528060011515815260200160011515815250600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600086815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff021916908315150217905550905050833373ffffffffffffffffffffffffffffffffffffffff167f6cc56bd06daacce5b10fdf5ad1dc781941e14d7a71d29d33e7001e2956d14e0787604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a35050505050565b6000600260019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dcf0aaed60405160200180807f56616c696461746f727300000000000000000000000000000000000000000000815250600a019050604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015617d1c57600080fd5b505afa158015617d30573d6000803e3d6000fd5b505050506040513d6020811015617d4657600080fd5b8101908080519060200190929190505050905090565b600080828401905083811015617dda576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60004690506040518080618ca760529139605201905060405180910390206040518060400160405280601381526020017f43656c6f20436f726520436f6e747261637473000000000000000000000000008152508051906020012060405180807f312e300000000000000000000000000000000000000000000000000000000000815250600301905060405180910390208330604051602001808681526020018581526020018481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001955050505050506040516020818303038152906040528051906020012060078190555050565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16159050919050565b60008073ffffffffffffffffffffffffffffffffffffffff16600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16148061806d57508273ffffffffffffffffffffffffffffffffffffffff16600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b905092915050565b600080600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461817757618119818585613550565b61816e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180618e6b6025913960400191505060405180910390fd5b809150506181da565b61818084612f87565b6181d5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180618b276036913960400191505060405180910390fd5b839150505b92915050565b600033905090565b6181f06188c7565b6040518060200160405280838152509050919050565b61820e6188c7565b604051806020016040528069d3c21bcecceda1000000815250905090565b6000816000015183600001511115905092915050565b600061825233878787878761662f565b90508573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146182f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f496e76616c6964207369676e617475726500000000000000000000000000000081525060200191505060405180910390fd5b6182fe86618678565b505050505050565b60008073ffffffffffffffffffffffffffffffffffffffff16600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16149050919050565b600081600001519050919050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415618431576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180618b9b6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60007369baecd458e7c08b13a18e11887dbb078fb3cbb46396ef41a1338686866040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018460ff1660ff16815260200183815260200182815260200194505050505060206040518083038186803b15801561858a57600080fd5b505af415801561859e573d6000803e3d6000fd5b505050506040513d60208110156185b457600080fd5b810190808051906020019092919050505090508473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614618668576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f496e76616c6964207369676e617475726500000000000000000000000000000081525060200191505060405180910390fd5b61867185618678565b5050505050565b61868133612f87565b6186d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603e815260200180618b5d603e913960400191505060405180910390fd5b6186df81617eee565b80156186f157506186f03382617f48565b5b618746576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526046815260200180618c406046913960600191505060405180910390fd5b33600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061880857805160ff1916838001178555618836565b82800160010185558215618836579182015b8281111561883557825182559160200191906001019061881a565b5b5090506188439190618a8d565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061888857803560ff19168380011785556188b6565b828001600101855582156188b6579182015b828111156188b557823582559160200191906001019061889a565b5b5090506188c39190618a8d565b5090565b6040518060200160405280600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061891b57803560ff1916838001178555618949565b82800160010185558215618949579182015b8281111561894857823582559160200191906001019061892d565b5b5090506189569190618a8d565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061899b57805160ff19168380011785556189c9565b828001600101855582156189c9579182015b828111156189c85782518255916020019190600101906189ad565b5b5090506189d69190618a8d565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10618a135780548555618a50565b82800160010185558215618a5057600052602060002091601f016020900482015b82811115618a4f578254825591600101919060010190618a34565b5b509050618a5d9190618a8d565b5090565b815481835581811115618a8857818360005260206000209182019101618a879190618ab2565b5b505050565b618aaf91905b80821115618aab576000816000905550600101618a93565b5090565b90565b618adb91905b80821115618ad75760008181618ace9190618ade565b50600101618ab8565b5090565b90565b50805460018160011615610100020316600290046000825580601f10618b045750618b23565b601f016020900490600052602060002090810190618b229190618a8d565b5b5056fe4d75737420666972737420726567697374657220616464726573732077697468204163636f756e742e6372656174654163636f756e74556e6b6e6f776e206163636f756e743a2073656e646572206d7573742072656769737465722077697468206372656174654163636f756e742066697273744f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373417574686f72697a655369676e65722861646472657373206163636f756e742c61646472657373207369676e65722c6279746573333220726f6c652943616e6e6f7420617574686f72697a65206163636f756e74206173207369676e657242656e65666963696172792063616e6e6f7420626520616464726573732030783043616e6e6f742072652d617574686f72697a652061646472657373206f72206c6f636b656420676f6c64206163636f756e7420666f7220616e6f74686572206163636f756e7443616e6e6f7420617574686f72697a652076616c696461746f72207369676e6572454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e7472616374294672616374696f6e206d757374206e6f742062652067726561746572207468616e2031556e6b6e6f776e204163636f756e743a2041646472657373207468617420617574686f72697a6564207369676e696e67206d75737420626520612072656769737465726564204163636f756e744163636f756e7420616c726561647920657869737473206f72206164647265737320697320616e20617574686f72697a6564207369676e657220666f7220616e6f74686572206163636f756e7452656769737465722077697468206372656174654163636f756e7420746f20736574206163636f756e74206e616d654d7573742066697273742072656769737465722073656e6465722077697468204163636f756e742e6372656174654163636f756e744d75737420617574686f72697a65207369676e6572206265666f72652073657474696e672061732064656661756c7443616e6e6f742072652d617574686f72697a652061646472657373207369676e65726e6f742061637469766520617574686f72697a6564207369676e657220666f7220726f6c654661696c656420746f20757064617465204543445341207075626c6963206b6579a265627a7a723158207c28a7af2b1123bc80eebe4a2a490d55f0b9361f3f692ad30c5d861d4245837764736f6c634300050d0032
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000001
-----Decoded View---------------
Arg [0] : test (bool): True
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000001
Deployed Bytecode Sourcemap
496:41566:1:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;496:41566:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17003:139;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;17003:139:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;27631:245;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;27631:245:1;;;;;;;;;;;;;;;;;:::i;:::-;;34922:140;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;34922:140:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;30403:158;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;30403:158:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;10587:454;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;10587:454:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;10587:454:1;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;10587:454:1;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;10587:454:1;;;;;;;;;;;;:::i;:::-;;21490:321;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;21490:321:1;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;21490:321:1;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;21490:321:1;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;21490:321:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;21490:321:1;;;;;;;;;;;;;;;:::i;:::-;;28518:178;;;:::i;:::-;;34680:138;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;34680:138:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;11757:519;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;11757:519:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;11757:519:1;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;11757:519:1;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;11757:519:1;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;11757:519:1;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;11757:519:1;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;11757:519:1;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;11757:519:1;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;11757:519:1;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;11757:519:1;;;;;;;;;;;;:::i;:::-;;302:23:3;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;18609:120:1;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;18609:120:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;35527:103;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;35527:103:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;13440:766;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;13440:766:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;13440:766:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;13440:766:1;;;;;;;;;;;;;;;;;;;6194:79;;;:::i;:::-;;33773:120;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;33773:120:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;9103:263;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;9103:263:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;31291:239;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;31291:239:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;18936:123;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;18936:123:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;34099:130;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;34099:130:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;19322:113;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25869:465;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;25869:465:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;3101:36;;;:::i;:::-;;;;;;;;;;;;;;;;;;;32954:210;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;32954:210:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;17661:108;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;17661:108:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;17661:108:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16667:129;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;16667:129:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;34425:134;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;34425:134:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;31844:142;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;31844:142:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;15421:134;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;15421:134:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;1531:120:29;;;:::i;:::-;;23266:935:1;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;23266:935:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;7300:257;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;7300:257:1;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;7300:257:1;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;7300:257:1;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;7300:257:1;;;;;;;;;;;;:::i;:::-;;3203:55;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;3203:55:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;3203:55:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29230:206;;;:::i;:::-;;25388:269;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;25388:269:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;3311:25:5;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;14965:148:1;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;14965:148:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;33405:186;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;33405:186:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;12510:698;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;12510:698:1;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;12510:698:1;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;12510:698:1;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;12510:698:1;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;12510:698:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;12510:698:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32227:486;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;32227:486:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;841:67:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;1137:82;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;22214:504:1;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;22214:504:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;6872:312;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;6872:312:1;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;6872:312:1;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;6872:312:1;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;6872:312:1;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;6872:312:1;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;6872:312:1;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;6872:312:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;29696:447;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;29696:447:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;24677:329;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;24677:329:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;15817:314;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;15817:314:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;20835:491;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;20835:491:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;19525:331;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;14412:225;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;14412:225:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26553:621;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;26553:621:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;28863:198;;;:::i;:::-;;17956:122;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;17956:122:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;17956:122:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3890:220:5;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;3890:220:5;;;;;;;;;;;;;;;;;;;:::i;:::-;;18307:133:1;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;18307:133:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;18307:133:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7671:203;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;7671:203:1;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;7671:203:1;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;7671:203:1;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;7671:203:1;;;;;;;;;;;;:::i;:::-;;2569:47;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;2569:47:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;36172:352;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;36172:352:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;16299:171;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;16299:171:1;;;;;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;16299:171:1;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;16299:171:1;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;16299:171:1;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;9754:372;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;9754:372:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;22826:270;;;:::i;:::-;;17353:143;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;17353:143:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;19946:243;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;19946:243:1;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;19946:243:1;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;19946:243:1;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;19946:243:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;19946:243:1;;;;;;;;;;;;;;;:::i;:::-;;30820:221;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;30820:221:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;5939:164;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;5939:164:1;;;;;;;;;;;;;;;;;;;:::i;:::-;;27286:208;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;27286:208:1;;;;;;;;;;;;;;;;;:::i;:::-;;8215:513;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;8215:513:1;;;;;;;;;;;;;;;;;:::i;:::-;;2965:133;;;:::i;:::-;;;;;;;;;;;;;;;;;;;1782:97:29;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;1782:97:29;;;;;;;;;;;;;;;;;;;:::i;:::-;;36645:151:1;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;36645:151:1;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;28107:248;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;28107:248:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;35168:183;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;35168:183:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;17003:139;17081:4;17097:41;17113:7;3443:43;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3443:43:1;;;3433:54;;;;;;17097:15;:41::i;:::-;17090:48;;17003:139;;;:::o;27631:245::-;27684:17;27704:34;27721:10;27733:4;27704:16;:34::i;:::-;27684:54;;27741:18;27754:4;27741:12;:18::i;:::-;:73;;27789:25;27809:4;27789:19;:25::i;:::-;27741:73;;;27762:24;27781:4;27762:18;:24::i;:::-;27741:73;27844:10;27823:49;;;27856:9;27867:4;27823:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;27631:245;;:::o;34922:140::-;35000:4;35051:7;35016:42;;:31;35033:7;35042:4;35016:16;:31::i;:::-;:42;;;;35009:49;;34922:140;;;;:::o;30403:158::-;30502:4;30551:6;30518:39;;:14;:23;30533:7;30518:23;;;;;;;;;;;;;;;:29;30542:4;30518:29;;;;;;;;;;;;;;;;;;;;;:39;;;30511:46;;30403:158;;;;;:::o;10587:454::-;816:1:13;799:13;;:18;;;;;;;;;;;820:20;843:13;;820:36;;10745:68:1;10780:6;3443:43;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3443:43:1;;;3433:54;;;;;;10805:1;10808;10811;10745:34;:68::i;:::-;10816:41;10833:6;3443:43;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3443:43:1;;;3433:54;;;;;;10816:16;:41::i;:::-;10871:15;:13;:15::i;:::-;:36;;;10908:10;10920:6;10928:14;;10871:72;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;10871:72:1;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;10871:72:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;10871:72:1;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;10871:72:1;;;;;;;;;;;;;;;;10861:123;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11018:10;10992:45;;;11030:6;10992:45;;;;;;;;;;;;;;;;;;;;;;887:13:13;;871:12;:29;863:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10587:454:1;;;;;;;:::o;21490:321::-;21605:2;21577:17;:24;:30;;21569:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21647:23;21673:8;:20;21682:10;21673:20;;;;;;;;;;;;;;;21647:46;;21724:17;21696:7;:25;;:45;;;;;;;;;;;;:::i;:::-;;21777:10;21749:58;;;21789:17;21749:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;21749:58:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21490:321;;:::o;28518:178::-;28556:14;28573:39;28589:10;3626:38;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3626:38:1;;;3616:49;;;;;;28573:15;:39::i;:::-;28556:56;;28615:32;28628:6;3626:38;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3626:38:1;;;3616:49;;;;;;28615:12;:32::i;:::-;28673:10;28655:37;;;28685:6;28655:37;;;;;;;;;;;;;;;;;;;;;;28518:178;:::o;34680:138::-;34757:4;34807:7;34773:41;;:30;34789:7;34798:4;34773:15;:30::i;:::-;:41;;;;34766:48;;34680:138;;;;:::o;11757:519::-;816:1:13;799:13;;:18;;;;;;;;;;;820:20;843:13;;820:36;;11964:68:1;11999:6;3443:43;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3443:43:1;;;3433:54;;;;;;12024:1;12027;12030;11964:34;:68::i;:::-;12035:41;12052:6;3443:43;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3443:43:1;;;3433:54;;;;;;12035:16;:41::i;:::-;12090:15;:13;:15::i;:::-;:32;;;12123:10;12135:6;12143:14;;12159:12;;12173:6;;12090:90;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;12090:90:1;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;12090:90:1;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;12090:90:1;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12090:90:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;12090:90:1;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;12090:90:1;;;;;;;;;;;;;;;;12080:139;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12253:10;12227:45;;;12265:6;12227:45;;;;;;;;;;;;;;;;;;;;;;887:13:13;;871:12;:29;863:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11757:519:1;;;;;;;;;;;:::o;302:23:3:-;;;;;;;;;;;;;:::o;18609:120:1:-;18675:7;18694:8;:17;18703:7;18694:17;;;;;;;;;;;;;;;:31;;;;;;;;;;;;18687:38;;18609:120;;;:::o;35527:103::-;35584:4;35601:8;:17;35610:7;35601:17;;;;;;;;;;;;;;;:24;;;;;;;;;;;;35593:33;;35527:103;;;:::o;13440:766::-;13517:12;13531:16;13560:18;13570:7;13560:9;:18::i;:::-;13552:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13601:19;13623:20;:29;13644:7;13623:29;;;;;;;;;;;;;;;:36;;;;13601:58;;13662:19;13684:1;13662:23;;13693:9;13705:1;13693:13;;13688:119;13712:11;13708:1;:15;13688:119;;;13747:56;13763:20;:29;13784:7;13763:29;;;;;;;;;;;;;;;13793:1;13763:32;;;;;;;;;;;;;;;:39;;;;;;;;;;;;;;;;13747:11;:15;;:56;;;;:::i;:::-;13733:70;;13725:3;;;;;;;13688:119;;;;13810:25;13848:11;13838:22;;;;;;;;;;;;;;;;;;;;;;;;;29:1:-1;21:6;17:14;116:4;104:10;96:6;87:34;147:4;139:6;135:17;125:27;;0:156;13838:22:1;;;;13810:50;;13863:17;13883:1;13863:21;;13887:24;13928:11;13914:26;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;148:4;140:6;136:17;126:27;;0:157;13914:26:1;;;;13887:53;;13948:9;13960:1;13948:13;;13943:226;13967:11;13963:1;:15;13943:226;;;13988:18;14009:20;:29;14030:7;14009:29;;;;;;;;;;;;;;;14039:1;14009:32;;;;;;;;;;;;;;;13988:53;;14057:4;:11;;;;;;;;;;;;;;;;14044:7;14052:1;14044:10;;;;;;;;;;;;;:24;;;;;14076:9;14088:1;14076:13;;14071:95;14095:7;14103:1;14095:10;;;;;;;;;;;;;;14091:1;:14;14071:95;;;14141:4;14146:1;14141:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14115:12;14128:9;14115:23;;;;;;;;;;;:33;;;;;;;;;;;14151:11;;;;;;;14107:3;;;;;;;14071:95;;;;13943:226;13980:3;;;;;;;13943:226;;;;14180:12;14194:7;14172:30;;;;;;;;;13440:766;;;:::o;6194:79::-;6242:27;:25;:27::i;:::-;6194:79::o;33773:120::-;33834:7;33853:36;33869:7;3626:38;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3626:38:1;;;3616:49;;;;;;33853:15;:36::i;:::-;33846:43;;33773:120;;;:::o;9103:263::-;816:1:13;799:13;;:18;;;;;;;;;;;820:20;843:13;;820:36;;9211:63:1;9246:6;3626:38;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3626:38:1;;;3616:49;;;;;;9266:1;9269;9272;9211:34;:63::i;:::-;9277:36;9294:6;3626:38;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3626:38:1;;;3616:49;;;;;;9277:16;:36::i;:::-;9343:10;9322:40;;;9355:6;9322:40;;;;;;;;;;;;;;;;;;;;;;887:13:13;;871:12;:29;863:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9103:263:1;;;;;:::o;31291:239::-;31377:4;31394:37;31409:7;31418:6;31426:4;31394:14;:37::i;:::-;:132;;;;31437:20;:29;31458:7;31437:29;;;;;;;;;;;;;;;:35;31467:4;31437:35;;;;;;;;;;;:43;31473:6;31437:43;;;;;;;;;;;;;;;:53;;;;;;;;;;;;:88;;;;;31518:7;31494:31;;:12;:20;31507:6;31494:20;;;;;;;;;;;;;;;;;;;;;;;;;:31;;;31437:88;31394:132;31386:140;;31291:239;;;;;:::o;18936:123::-;19003:4;19052:1;19020:34;;:12;:20;19033:6;19020:20;;;;;;;;;;;;;;;;;;;;;;;;;:34;;;;19012:43;;18936:123;;;:::o;34099:130::-;34165:7;34184:41;34200:7;3443:43;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3443:43:1;;;3433:54;;;;;;34184:15;:41::i;:::-;34177:48;;34099:130;;;:::o;19322:113::-;19373:7;19382;19391;19400;19420:1;19423;19426;19429;19412:19;;;;;;;;;;;;;;;;;;;;19322:113;;;;:::o;25869:465::-;25942:21;25952:10;25942:9;:21::i;:::-;25934:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26034:20;26047:6;26034:12;:20::i;:::-;:82;;;;;26058:58;26097:10;26109:6;26058:38;:58::i;:::-;26034:82;26024:134;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26211:59;;;;;;;;26243:4;26211:59;;;;;;26261:5;26211:59;;;;;26162:20;:32;26183:10;26162:32;;;;;;;;;;;;;;;:38;26195:4;26162:38;;;;;;;;;;;:46;26201:6;26162:46;;;;;;;;;;;;;;;:108;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26325:4;26305:10;26278:52;;;26317:6;26278:52;;;;;;;;;;;;;;;;;;;;;;25869:465;;:::o;3101:36::-;;;;:::o;32954:210::-;33032:7;33044:21;33068:14;:23;33083:7;33068:23;;;;;;;;;;;;;;;:29;33092:4;33068:29;;;;;;;;;;;;;;;;;;;;;33044:53;;33132:1;33107:27;;:13;:27;;;:53;;33147:13;33107:53;;;33137:7;33107:53;33100:60;;;32954:210;;;;:::o;17661:108::-;17718:13;17743:8;:17;17752:7;17743:17;;;;;;;;;;;;;;;:22;;17736:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17661:108;;;:::o;16667:129::-;16740:4;16756:36;16772:7;3626:38;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3626:38:1;;;3616:49;;;;;;16756:15;:36::i;:::-;16749:43;;16667:129;;;:::o;34425:134::-;34493:7;34512:43;34528:7;3537:45;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3537:45:1;;;3527:56;;;;;;34512:15;:43::i;:::-;34505:50;;34425:134;;;:::o;31844:142::-;31915:7;31934:48;31958:6;3443:43;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3443:43:1;;;3433:54;;;;;;31934:23;:48::i;:::-;31927:55;;31844:142;;;:::o;15421:134::-;15489:7;15508:43;15532:6;3626:38;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3626:38:1;;;3616:49;;;;;;15508:23;:43::i;:::-;15501:50;;15421:134;;;:::o;1531:120:29:-;1014:9;:7;:9::i;:::-;1006:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1622:1;1585:40;;1606:6;;;;;;;;;;;1585:40;;;;;;;;;;;;1645:1;1628:6;;:19;;;;;;;;;;;;;;;;;;1531:120::o;23266:935:1:-;23340:21;23350:10;23340:9;:21::i;:::-;23332:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23431:20;23444:6;23431:12;:20::i;:::-;23423:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23503:58;23542:10;23554:6;23503:38;:58::i;:::-;23493:105;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23609:34;23618:10;23630:6;23638:4;23609:8;:34::i;:::-;23601:94;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23699:23;23725:8;:20;23734:10;23725:20;;;;;;;;;;;;;;;23699:46;;23752:18;23765:4;23752:12;:18::i;:::-;23748:399;;;3626:38;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3626:38:1;;;3616:49;;;;;;23779:4;:18;23775:216;;;23825:6;23802:7;:15;;:20;;;:29;;;;;;;;;;;;;;;;;;23775:216;;;3537:45;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3537:45:1;;;3527:56;;;;;;23845:4;:25;23841:150;;;23905:6;23875:7;:15;;:27;;;:36;;;;;;;;;;;;;;;;;;23841:150;;;3443:43;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3443:43:1;;;3433:54;;;;;;23925:4;:23;23921:70;;;23981:6;23953:7;:15;;:25;;;:34;;;;;;;;;;;;;;;;;;23921:70;23841:150;23775:216;24014:10;23998:41;;;24026:6;24034:4;23998:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;23748:399;;;24087:6;24052:14;:26;24067:10;24052:26;;;;;;;;;;;;;;;:32;24079:4;24052:32;;;;;;;;;;;;:41;;;;;;;;;;;;;;;;;;24118:10;24101:42;;;24130:6;24138:4;24101:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;23748:399;24172:10;24155:42;;;24184:6;24192:4;24155:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;23266:935;;;:::o;7300:257::-;7373:21;7383:10;7373:9;:21::i;:::-;7365:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7417:23;7443:8;:20;7452:10;7443:20;;;;;;;;;;;;;;;7417:46;;7488:11;;7466:7;:19;;:33;;;;;;;:::i;:::-;;7529:10;7507:46;;;7541:11;;7507:46;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;7507:46:1;;;;;;;;;;;;;;7300:257;;;:::o;3203:55::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;29230:206::-;29275:14;29292:46;29308:10;3537:45;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3537:45:1;;;3527:56;;;;;;29292:15;:46::i;:::-;29275:63;;29341:39;29354:6;3537:45;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3537:45:1;;;3527:56;;;;;;29341:12;:39::i;:::-;29413:10;29388:44;;;29425:6;29388:44;;;;;;;;;;;;;;;;;;;;;;29230:206;:::o;25388:269::-;25481:70;25516:6;3537:45;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3537:45:1;;;3527:56;;;;;;25543:1;25546;25549;25481:34;:70::i;:::-;25554:43;25571:6;3537:45;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3537:45:1;;;3527:56;;;;;;25554:16;:43::i;:::-;25634:10;25606:47;;;25646:6;25606:47;;;;;;;;;;;;;;;;;;;;;;25388:269;;;;:::o;3311:25:5:-;;;;;;;;;;;;;:::o;14965:148:1:-;15040:7;15059:50;15083:6;3537:45;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3537:45:1;;;3527:56;;;;;;15059:23;:50::i;:::-;15052:57;;14965:148;;;:::o;33405:186::-;33483:7;33502:18;33515:4;33502:12;:18::i;:::-;:85;;33556:31;33573:7;33582:4;33556:16;:31::i;:::-;33502:85;;;33523:30;33539:7;33548:4;33523:15;:30::i;:::-;33502:85;33495:92;;33405:186;;;;:::o;12510:698::-;12602:16;12620:12;12637:17;12657:1;12637:21;;12661:22;12700:15;;:22;;12686:37;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;148:4;140:6;136:17;126:27;;0:157;12686:37:1;;;;12661:62;;12731:9;12743:1;12731:13;;12726:172;12750:15;;:22;;12746:1;:26;12726:172;;;12808:8;:28;12817:15;;12833:1;12817:18;;;;;;;;;;;;;;;12808:28;;;;;;;;;;;;;;;:40;;12802:54;;;;;;;;;;;;;;;;12791:5;12797:1;12791:8;;;;;;;;;;;;;:65;;;;;12871:23;12885:5;12891:1;12885:8;;;;;;;;;;;;;;12871:9;:13;;:23;;;;:::i;:::-;12859:35;;12778:8;12784:1;12778;:5;;:8;;;;:::i;:::-;12774:12;;12726:172;;;;12901:17;12931:9;12921:20;;;;;;;;;;;;;;;;;;;;;;;;;29:1:-1;21:6;17:14;116:4;104:10;96:6;87:34;147:4;139:6;135:17;125:27;;0:156;12921:20:1;;;;12901:40;;12944:15;12962:1;12944:19;;12971:9;12983:1;12971:13;;12966:216;12990:15;;:22;;12986:1;:26;12966:216;;;13036:9;13048:1;13036:13;;13031:148;13055:5;13061:1;13055:8;;;;;;;;;;;;;;13051:1;:12;13031:148;;;13104:8;:28;13113:15;;13129:1;13113:18;;;;;;;;;;;;;;;13104:28;;;;;;;;;;;;;;;:40;;13146:1;13098:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13082:4;13087:7;13082:13;;;;;;;;;;;:66;;;;;;;;;;;13161:14;13173:1;13161:7;:11;;:14;;;;:::i;:::-;13151:24;;13069:8;13075:1;13069;:5;;:8;;;;:::i;:::-;13065:12;;13031:148;;;;13018:8;13024:1;13018;:5;;:8;;;;:::i;:::-;13014:12;;12966:216;;;;13192:5;13199:4;13184:20;;;;;;;;12510:698;;;;;:::o;32227:486::-;32305:7;32325:18;32338:4;32325:12;:18::i;:::-;32317:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32379:23;32405:8;:18;32414:8;32405:18;;;;;;;;;;;;;;;32379:44;;32426:14;3443:43;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3443:43:1;;;3433:54;;;;;;32447:4;:23;32443:216;;;32484:7;:15;;:25;;;;;;;;;;;;32475:34;;32443:216;;;3537:45;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3537:45:1;;;3527:56;;;;;;32523:4;:25;32519:140;;;32562:7;:15;;:27;;;;;;;;;;;;32553:36;;32519:140;;;3626:38;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3626:38:1;;;3616:49;;;;;;32603:4;:18;32599:60;;;32635:7;:15;;:20;;;;;;;;;;;;32626:29;;32599:60;32519:140;32443:216;32687:1;32669:20;;:6;:20;;;:40;;32703:6;32669:40;;;32692:8;32669:40;32662:47;;;;32227:486;;;;:::o;841:67:29:-;879:7;898:6;;;;;;;;;;;891:13;;841:67;:::o;1137:82::-;1177:4;1209:6;;;;;;;;;;;1193:22;;:12;:10;:12::i;:::-;:22;;;1186:29;;1137:82;:::o;22214:504:1:-;22301:21;22311:10;22301:9;:21::i;:::-;22293:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22415:1;22392:25;;:11;:25;;;;22384:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22458:29;;:::i;:::-;22490:26;22507:8;22490:16;:26::i;:::-;22458:58;;22527:27;22533:20;:18;:20::i;:::-;22527:1;:5;;:27;;;;:::i;:::-;22519:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22630:33;;;;;;;;22648:11;22630:33;;;;;;22661:1;22630:33;;;22597:18;:30;22616:10;22597:30;;;;;;;;;;;;;;;:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22692:11;22671:43;;;22705:8;22671:43;;;;;;;;;;;;;;;;;;22214:504;;;:::o;6872:312::-;7028:21;7038:10;7028:9;:21::i;:::-;7023:50;;7054:15;:13;:15::i;:::-;;7023:50;7075:13;7083:4;;7075:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;7075:13:1;;;;;;:7;:13::i;:::-;7091:46;7119:17;;7091:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;7091:46:1;;;;;;:27;:46::i;:::-;7140:40;7157:13;7172:1;7175;7178;7140:16;:40::i;:::-;6872:312;;;;;;;;:::o;29696:447::-;29795:4;29804:23;29830:8;:18;29839:8;29830:18;;;;;;;;;;;;;;;29804:44;;3443:43;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3443:43:1;;;3433:54;;;;;;29855:4;:23;:62;;;;;29911:6;29882:35;;:7;:15;;:25;;;;;;;;;;;;:35;;;29855:62;29851:289;;;29929:4;29922:11;;;;;29851:289;3537:45;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3537:45:1;;;3527:56;;;;;;29947:4;:25;:66;;;;;30007:6;29976:37;;:7;:15;;:27;;;;;;;;;;;;:37;;;29947:66;29943:197;;;30025:4;30018:11;;;;;29943:197;3626:38;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3626:38:1;;;3616:49;;;;;;30043:4;:18;:52;;;;;30089:6;30065:30;;:7;:15;;:20;;;;;;;;;;;;:30;;;30043:52;30039:101;;;30107:4;30100:11;;;;;30039:101;30131:5;30124:12;;;29696:447;;;;;;:::o;24677:329::-;24794:47;24819:6;24827:4;24833:1;24836;24839;24794:24;:47::i;:::-;24893:58;;;;;;;;24925:4;24893:58;;;;;;24943:4;24893:58;;;;;24844:20;:32;24865:10;24844:32;;;;;;;;;;;;;;;:38;24877:4;24844:38;;;;;;;;;;;:46;24883:6;24844:46;;;;;;;;;;;;;;;:107;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24997:4;24977:10;24960:42;;;24989:6;24960:42;;;;;;;;;;;;;;;;;;;;;;24677:329;;;;;:::o;15817:314::-;15881:7;15893:26;15922:12;:20;15935:6;15922:20;;;;;;;;;;;;;;;;;;;;;;;;;15893:49;;15979:1;15949:32;;:18;:32;;;15945:183;;15993:18;15986:25;;;;;15945:183;16032:17;16042:6;16032:9;:17::i;:::-;16024:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16118:6;16111:13;;;15817:314;;;;:::o;20835:491::-;20933:21;20943:10;20933:9;:21::i;:::-;20925:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21000:10;20983:27;;:13;:27;;;:60;;;;21039:3;21014:29;;:13;:29;;;20983:60;20977:199;;21049:14;21066:10;:29;21096:10;21108:1;21111;21114;21066:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21066:50:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;21066:50:1;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;21066:50:1;;;;;;;;;;;;;;;;21049:67;;21137:13;21127:23;;:6;:23;;;21119:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20977:199;;21178:23;21204:8;:20;21213:10;21204:20;;;;;;;;;;;;;;;21178:46;;21251:13;21227:7;:21;;;:37;;;;;;;;;;;;;;;;;;21296:10;21272:50;;;21308:13;21272:50;;;;;;;;;;;;;;;;;;;;;;20835:491;;;;;:::o;19525:331::-;19566:4;19585:24;19598:10;19585:12;:24::i;:::-;:61;;;;;19613:33;19635:10;19613:21;:33::i;:::-;19585:61;19575:156;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19734:23;19760:8;:20;19769:10;19760:20;;;;;;;;;;;;;;;19734:46;;19800:4;19783:7;:14;;;:21;;;;;;;;;;;;;;;;;;19827:10;19812:26;;;;;;;;;;;;19848:4;19841:11;;;19525:331;:::o;14412:225::-;14482:7;14491;14503:36;14542:18;:27;14561:7;14542:27;;;;;;;;;;;;;;;14503:66;;14580:10;:22;;;;;;;;;;;;14604:28;:10;:19;;:26;;;;;;;;;;;;;;;;;;:28::i;:::-;14572:61;;;;;14412:225;;;:::o;26553:621::-;26641:18;26651:7;26641:9;:18::i;:::-;26631:113;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26757:24;26770:10;26757:12;:24::i;:::-;:87;;;;;26785:59;26824:7;26833:10;26785:38;:59::i;:::-;26757:87;26747:139;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26958:4;26899:63;;:20;:29;26920:7;26899:29;;;;;;;;;;;;;;;:35;26929:4;26899:35;;;;;;;;;;;:47;26935:10;26899:47;;;;;;;;;;;;;;;:55;;;;;;;;;;;;:63;;;26889:113;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27033:7;27006:12;:24;27019:10;27006:24;;;;;;;;;;;;;;;;:34;;;;;;;;;;;;;;;;;;27103:4;27043:20;:29;27064:7;27043:29;;;;;;;;;;;;;;;:35;27073:4;27043:35;;;;;;;;;;;:47;27079:10;27043:47;;;;;;;;;;;;;;;:57;;;:64;;;;;;;;;;;;;;;;;;27165:4;27144:7;27115:55;;;27153:10;27115:55;;;;;;;;;;;;;;;;;;;;;;26553:621;;:::o;28863:198::-;28906:14;28923:44;28939:10;3443:43;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3443:43:1;;;3433:54;;;;;;28923:15;:44::i;:::-;28906:61;;28970:37;28983:6;3443:43;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3443:43:1;;;3433:54;;;;;;28970:12;:37::i;:::-;29038:10;29015:42;;;29050:6;29015:42;;;;;;;;;;;;;;;;;;;;;;28863:198;:::o;17956:122::-;18020:13;18045:8;:17;18054:7;18045:17;;;;;;;;;;;;;;;:29;;18038:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17956:122;;;:::o;3890:220:5:-;1014:9:29;:7;:9::i;:::-;1006:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3991:1:5;3964:29;;:15;:29;;;;3956:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4054:15;4033:8;;:37;;;;;;;;;;;;;;;;;;4090:15;4078:28;;;;;;;;;;;;3890:220;:::o;18307:133:1:-;18377:12;18401:8;:17;18410:7;18401:17;;;;;;;;;;;;;;;:35;;18394:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18307:133;;;:::o;7671:203::-;7735:21;7745:10;7735:9;:21::i;:::-;7727:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7779:20;:32;7800:10;7779:32;;;;;;;;;;;;;;;7817:3;;7779:42;;;39:1:-1;33:3;27:10;23:18;57:10;52:3;45:23;79:10;72:17;;0:93;7779:42:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;7854:10;7829:41;;;7866:3;;7829:41;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;7829:41:1;;;;;;;;;;;;;;7671:203;;:::o;2569:47::-;;;;;;;;;;;;;;;;;;;;;;:::o;36172:352::-;36316:7;36328:18;3025:73;;;;;;;;;;;;;;;;;;;36406:7;36415:6;36423:4;36361:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;36361:67:1;;;36349:82;;;;;;36328:103;;36441:10;:35;36477:21;;36500:10;36512:1;36515;36518;36441:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36441:79:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;36441:79:1;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;36441:79:1;;;;;;;;;;;;;;;;36434:86;;;36172:352;;;;;;;;:::o;16299:171::-;16390:4;16406:60;16423:7;16459:4;;16442:22;;;;;;;30:3:-1;22:6;14;1:33;57:3;49:6;45:16;35:26;;16442:22:1;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;16442:22:1;;;16432:33;;;;;;16406:16;:60::i;:::-;16399:67;;16299:171;;;;;:::o;9754:372::-;816:1:13;799:13;;:18;;;;;;;;;;;820:20;843:13;;820:36;;9867:68:1;9902:6;3443:43;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3443:43:1;;;3433:54;;;;;;9927:1;9930;9933;9867:34;:68::i;:::-;9938:41;9955:6;3443:43;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3443:43:1;;;3433:54;;;;;;9938:16;:41::i;:::-;9992:15;:13;:15::i;:::-;:27;;;10020:10;9992:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9992:39:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;9992:39:1;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;9992:39:1;;;;;;;;;;;;;;;;9991:40;9983:86;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10103:10;10077:45;;;10115:6;10077:45;;;;;;;;;;;;;;;;;;;;;;887:13:13;;871:12;:29;863:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9754:372:1;;;;;:::o;22826:270::-;22879:21;22889:10;22879:9;:21::i;:::-;22871:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22995:52;;;;;;;;23021:3;22995:52;;;;;;23027:19;23044:1;23027:16;:19::i;:::-;22995:52;;;22962:18;:30;22981:10;22962:30;;;;;;;;;;;;;;;:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23084:3;23055:37;;;23090:1;23055:37;;;;;;;;;;;;;;;;;;22826:270::o;17353:143::-;17433:4;17449:43;17465:7;3537:45;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3537:45:1;;;3527:56;;;;;;17449:15;:43::i;:::-;17442:50;;17353:143;;;:::o;19946:243::-;20001:21;20011:10;20001:9;:21::i;:::-;19993:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20077:23;20103:8;:20;20112:10;20103:20;;;;;;;;;;;;;;;20077:46;;20141:4;20126:7;:12;;:19;;;;;;;;;;;;:::i;:::-;;20168:10;20153:32;;;20180:4;20153:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;20153:32:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19946:243;;:::o;30820:221::-;30919:4;30936:18;30949:4;30936:12;:18::i;:::-;:101;;30999:38;31015:7;31024:6;31032:4;30999:15;:38::i;:::-;30936:101;;;30958:37;30973:7;30982:6;30990:4;30958:14;:37::i;:::-;30936:101;30928:109;;30820:221;;;;;:::o;5939:164::-;450:11:3;;;;;;;;;;;449:12;441:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;511:4;497:11;;:18;;;;;;;;;;;;;;;;;;6008:30:1;6027:10;6008:18;:30::i;:::-;6041:28;6053:15;6041:11;:28::i;:::-;6072:27;:25;:27::i;:::-;5939:164;:::o;27286:208::-;27339:14;27356;:26;27371:10;27356:26;;;;;;;;;;;;;;;:32;27383:4;27356:32;;;;;;;;;;;;;;;;;;;;;27339:49;;27434:1;27391:14;:26;27406:10;27391:26;;;;;;;;;;;;;;;:32;27418:4;27391:32;;;;;;;;;;;;:45;;;;;;;;;;;;;;;;;;27465:10;27444:46;;;27477:6;27485:4;27444:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;27286:208;;:::o;8215:513::-;8277:21;8287:10;8277:9;:21::i;:::-;8269:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8337:20;:32;8358:10;8337:32;;;;;;;;;;;;;;;:39;;;;8329:5;:47;8321:86;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8410:17;8472:1;8430:20;:32;8451:10;8430:32;;;;;;;;;;;;;;;:39;;;;:43;8410:63;;8476:16;8495:20;:32;8516:10;8495:32;;;;;;;;;;;;;;;8528:5;8495:39;;;;;;;;;;;;;;;8476:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8579:20;:32;8600:10;8579:32;;;;;;;;;;;;;;;8612:9;8579:43;;;;;;;;;;;;;;;8537:20;:32;8558:10;8537:32;;;;;;;;;;;;;;;8570:5;8537:39;;;;;;;;;;;;;;;:85;;;;;;;;;;;;;;;;;;;;:::i;:::-;;8625:20;:32;8646:10;8625:32;;;;;;;;;;;;;;;:41;;;;;;;;;;;;:::i;:::-;;8701:10;8674:50;;;8713:3;8718:5;8674:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;8674:50:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8215:513;;;:::o;2965:133::-;3025:73;;;;;;;;;;;;;;;;;;;2965:133;:::o;1782:97:29:-;1014:9;:7;:9::i;:::-;1006:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1847:28;1866:8;1847:18;:28::i;:::-;1782:97;:::o;36645:151:1:-;36702:4;3626:38;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3626:38:1;;;3616:49;;;;;;36718:4;:18;:45;;;;3443:43;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3443:43:1;;;3433:54;;;;;;36740:4;:23;36718:45;:74;;;;3537:45;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3537:45:1;;;3527:56;;;;;;36767:4;:25;36718:74;36711:81;;36645:151;;;:::o;28107:248::-;28173:41;28189:10;28201:6;28209:4;28173:15;:41::i;:::-;28169:79;;;28219:25;28239:4;28219:19;:25::i;:::-;28169:79;28258:20;:32;28279:10;28258:32;;;;;;;;;;;;;;;:38;28291:4;28258:38;;;;;;;;;;;:46;28297:6;28258:46;;;;;;;;;;;;;;;;28251:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28346:4;28326:10;28312:39;;;28338:6;28312:39;;;;;;;;;;;;;;;;;;;;;;28107:248;;:::o;35168:183::-;35246:4;35262:18;35275:4;35262:12;:18::i;:::-;:85;;35316:31;35333:7;35342:4;35316:16;:31::i;:::-;35262:85;;;35283:30;35299:7;35308:4;35283:15;:30::i;:::-;35262:85;35255:92;;35168:183;;;;:::o;39307:512::-;39360:23;39386:8;:20;39395:10;39386:20;;;;;;;;;;;;;;;39360:46;;39410:14;3443:43;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3443:43:1;;;3433:54;;;;;;39431:4;:23;39427:336;;;39468:7;:15;;:25;;;;;;;;;;;;39459:34;;39532:1;39496:7;:15;;:25;;;:38;;;;;;;;;;;;;;;;;;39427:336;;;3537:45;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3537:45:1;;;3527:56;;;;;;39548:4;:25;39544:219;;;39587:7;:15;;:27;;;;;;;;;;;;39578:36;;39655:1;39617:7;:15;;:27;;;:40;;;;;;;;;;;;;;;;;;39544:219;;;3626:38;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3626:38:1;;;3616:49;;;;;;39671:4;:18;39667:96;;;39703:7;:15;;:20;;;;;;;;;;;;39694:29;;39757:1;39726:7;:15;;:20;;;:33;;;;;;;;;;;;;;;;;;39667:96;39544:219;39427:336;39790:10;39770:45;;;39802:6;39810:4;39770:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;39307:512;;;:::o;38757:322::-;38881:33;38898:6;38906:1;38909;38912;38881:16;:33::i;:::-;38966:58;;;;;;;;38998:4;38966:58;;;;;;39016:4;38966:58;;;;;38917:20;:32;38938:10;38917:32;;;;;;;;;;;;;;;:38;38950:4;38917:38;;;;;;;;;;;:46;38956:6;38917:46;;;;;;;;;;;;;;;:107;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39070:4;39050:10;39033:42;;;39062:6;39033:42;;;;;;;;;;;;;;;;;;;;;;38757:322;;;;;:::o;6233:139:5:-;6281:11;6316:8;;;;;;;;;;;:27;;;2665:30;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;2665:30:5;;;2655:41;;;;;;6316:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6316:51:5;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;6316:51:5;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;6316:51:5;;;;;;;;;;;;;;;;6297:71;;6233:139;:::o;796:152:28:-;854:7;866:9;882:1;878;:5;866:17;;899:1;894;:6;;886:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;943:1;936:8;;;796:152;;;;:::o;36887:348:1:-;36936:15;36977:7;36966:18;;37039:99;;;;;;;;;;;;;;;;;;;37151:28;;;;;;;;;;;;;;;;;37141:39;;;;;;37183:16;;;;;;;;;;;;;;;;;;;37202:7;37220:4;37026:202;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;37026:202:1;;;37014:217;;;;;;36990:21;:241;;;;36887:348;:::o;37411:109::-;37473:4;37491:8;:17;37500:7;37491:17;;;;;;;;;;;;;;;:24;;;;;;;;;;;;37490:25;37482:34;;37411:109;;;:::o;38173:200::-;38282:4;38331:1;38299:34;;:12;:20;38312:6;38299:20;;;;;;;;;;;;;;;;;;;;;;;;;:34;;;:69;;;;38361:7;38337:31;;:12;:20;38350:6;38337:20;;;;;;;;;;;;;;;;;;;;;;;;;:31;;;38299:69;38291:78;;38173:200;;;;:::o;38376:378::-;38462:7;38474:15;38492:12;:20;38505:6;38492:20;;;;;;;;;;;;;;;;;;;;;;;;;38474:38;;38538:1;38519:21;;:7;:21;;;38515:132;;38553:31;38562:7;38571:6;38579:4;38553:8;:31::i;:::-;38545:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38636:7;38629:14;;;;;38515:132;38658:17;38668:6;38658:9;:17::i;:::-;38650:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38744:6;38737:13;;;38376:378;;;;;:::o;773:86:26:-;818:15;845:10;838:17;;773:86;:::o;1510:90:2:-;1558:15;;:::i;:::-;1585:11;;;;;;;;1594:1;1585:11;;;1578:18;;1510:90;;;:::o;1204:93::-;1245:15;;:::i;:::-;1272:21;;;;;;;;883:25;1272:21;;;1265:28;;1204:93;:::o;9542:112::-;9616:4;9643:1;:7;;;9632:1;:7;;;:18;;9625:25;;9542:112;;;;:::o;41187:282:1:-;41305:14;41322:65;41349:10;41361;41373:4;41379:1;41382;41385;41322:26;:65::i;:::-;41305:82;;41408:10;41398:20;;:6;:20;;;41390:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41444:21;41454:10;41444:9;:21::i;:::-;41187:282;;;;;;:::o;37731:126::-;37801:4;37850:1;37818:34;;:12;:20;37831:6;37818:20;;;;;;;;;;;;;;;;;;;;;;;;;:34;;;37810:43;;37731:126;;;:::o;1672:88:2:-;1730:7;1749:1;:7;;;1742:14;;1672:88;;;:::o;1966:201:29:-;2052:1;2032:22;;:8;:22;;;;2024:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2134:8;2105:38;;2126:6;;;;;;;;;;;2105:38;;;;;;;;;;;;2155:8;2146:6;;:17;;;;;;;;;;;;;;;;;;1966:201;:::o;40366:237:1:-;40454:14;40471:10;:29;40501:10;40513:1;40516;40519;40471:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40471:50:1;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;40471:50:1;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;40471:50:1;;;;;;;;;;;;;;;;40454:67;;40542:10;40532:20;;:6;:20;;;40524:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40578:21;40588:10;40578:9;:21::i;:::-;40366:237;;;;;:::o;41683:377::-;41743:21;41753:10;41743:9;:21::i;:::-;41733:101;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41847:24;41860:10;41847:12;:24::i;:::-;:90;;;;;41875:62;41914:10;41926;41875:38;:62::i;:::-;41847:90;41837:178;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42046:10;42019:12;:24;42032:10;42019:24;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;41683:377;:::o;496:41566::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o
Swarm Source
bzzr://7c28a7af2b1123bc80eebe4a2a490d55f0b9361f3f692ad30c5d861d42458377
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.