Source Code
Overview
ETH Balance
0 ETH
Token Holdings
More Info
ContractCreator
Multichain Info
N/A
Latest 25 from a total of 134,039 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
Amount
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Submit Batch | 10096806 | 22 mins ago | IN | 0 ETH | 0.00012003 | ||||
| Submit Batch | 10096805 | 23 mins ago | IN | 0 ETH | 0.00013026 | ||||
| Submit Batch | 10096778 | 28 mins ago | IN | 0 ETH | 0.00011032 | ||||
| Submit Batch | 10096728 | 38 mins ago | IN | 0 ETH | 0.00013052 | ||||
| Send To Helios | 10096689 | 46 mins ago | IN | 0 ETH | 0.00026253 | ||||
| Send To Helios | 10096678 | 48 mins ago | IN | 0 ETH | 0.00027095 | ||||
| Send To Helios | 10096674 | 49 mins ago | IN | 0 ETH | 0.00026282 | ||||
| Send To Helios | 10096671 | 49 mins ago | IN | 0 ETH | 0.00009745 | ||||
| Submit Batch | 10096640 | 56 mins ago | IN | 0 ETH | 0.00011877 | ||||
| Submit Batch | 10096635 | 57 mins ago | IN | 0 ETH | 0.00012752 | ||||
| Submit Batch | 10096608 | 1 hr ago | IN | 0 ETH | 0.00011047 | ||||
| Submit Batch | 10096566 | 1 hr ago | IN | 0 ETH | 0.00011471 | ||||
| Submit Batch | 10096565 | 1 hr ago | IN | 0 ETH | 0.00013348 | ||||
| Submit Batch | 10096494 | 1 hr ago | IN | 0 ETH | 0.00012071 | ||||
| Submit Batch | 10096425 | 1 hr ago | IN | 0 ETH | 0.00012272 | ||||
| Submit Batch | 10096418 | 1 hr ago | IN | 0 ETH | 0.00012011 | ||||
| Submit Batch | 10096411 | 1 hr ago | IN | 0 ETH | 0.00010912 | ||||
| Submit Batch | 10096403 | 1 hr ago | IN | 0 ETH | 0.0001124 | ||||
| Submit Batch | 10096396 | 1 hr ago | IN | 0 ETH | 0.00012881 | ||||
| Submit Batch | 10096388 | 1 hr ago | IN | 0 ETH | 0.0001125 | ||||
| Submit Batch | 10096381 | 1 hr ago | IN | 0 ETH | 0.00012026 | ||||
| Submit Batch | 10096373 | 1 hr ago | IN | 0 ETH | 0.000112 | ||||
| Submit Batch | 10096366 | 1 hr ago | IN | 0 ETH | 0.0001295 | ||||
| Submit Batch | 10096359 | 1 hr ago | IN | 0 ETH | 0.00012045 | ||||
| Send To Helios | 10096324 | 2 hrs ago | IN | 0 ETH | 0.00028186 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
To
|
Amount
|
||
|---|---|---|---|---|---|---|---|
| 0x60a06040 | 9442573 | 95 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Loading...
Loading
Contract Name:
Hyperion
Compiler Version
v0.8.25+commit.b61c2a91
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
import "./@openzeppelin/contracts/ERC20.sol";
import "./@openzeppelin/contracts/Ownable.sol";
import "./@openzeppelin/contracts/IERC20.sol";
import "./@openzeppelin/contracts/IERC20Metadata.sol";
import "./@openzeppelin/contracts/SafeERC20.sol";
import "./@openzeppelin/contracts/utils/Address.sol";
import "./@openzeppelin/contracts/utils/Initializable.sol";
import "./@openzeppelin/contracts/utils/Pausable.sol";
import "./@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "./@openzeppelin/contracts/OwnableUpgradeableWithExpiry.sol";
contract HeliosERC20 is ERC20, Ownable {
uint8 private immutable _decimals;
constructor(
string memory name_,
string memory symbol_,
uint8 decimals_
) ERC20(name_, symbol_) {
_decimals = decimals_;
}
function decimals() public view virtual override returns (uint8) {
return _decimals;
}
function mint(address account, uint256 amount) public onlyOwner {
_mint(account, amount);
}
function burn(address account, uint256 amount) public onlyOwner {
_burn(account, amount);
}
}
// This is used purely to avoid stack too deep errors
// represents everything about a given validator set
struct ValsetArgs {
// the validators in this set, represented by an Ethereum address
address[] validators;
// the powers of the given validators in the same order as above
uint256[] powers;
// the nonce of this validator set
uint256 valsetNonce;
// the reward amount denominated in the below reward token, can be
// set to zero
uint256 rewardAmount;
// the reward token, should be set to the zero address if not being used
address rewardToken;
}
// Don't change the order of state for working upgrades.
// AND BE AWARE OF INHERITANCE VARIABLES!
// Inherited contracts contain storage slots and must be accounted for in any upgrades
// always test an exact upgrade on testnet and localhost before mainnet upgrades.
contract Hyperion is
Initializable,
OwnableUpgradeableWithExpiry,
Pausable,
ReentrancyGuard
{
using SafeERC20 for IERC20;
// ⚠️ ONLY APPEND TO STATE VARIABLES AND DON'T CHANGE VARIABLE ORDER/DEFINITIONS INCL NOT MAKING THEM IMMUTABLE ⚠️
// These are updated often
bytes32 public state_lastValsetCheckpoint;
mapping(address => uint256) public state_lastBatchNonces;
mapping(bytes32 => uint256) public state_invalidationMapping;
uint256 public state_lastValsetNonce = 0;
uint256 public state_lastValsetHeight = 0;
uint256 public state_lastEventNonce = 0;
uint256 public state_lastEventHeight = 0;
// These are set once at initialization
bytes32 public state_hyperionId;
uint256 public state_powerThreshold;
mapping(address => bool) public isHeliosNativeToken;
uint256 private constant MAX_NONCE_JUMP_LIMIT = 10_000_000_000_000;
// TransactionBatchExecutedEvent and SendToHeliosEvent both include the field _eventNonce.
// This is incremented every time one of these events is emitted. It is checked by the
// Helios module to ensure that all events are received in order, and that none are lost.
//
// ValsetUpdatedEvent does not include the field _eventNonce because it is never submitted to the Helios
// module. It is purely for the use of relayers to allow them to successfully submit batches.
event TransactionBatchExecutedEvent(
uint256 indexed _batchNonce,
address indexed _token,
uint256 _eventNonce
);
event SendToHeliosEvent(
address indexed _tokenContract,
address indexed _sender,
bytes32 indexed _destination,
uint256 _amount,
uint256 _eventNonce,
string _data
);
event ERC20DeployedEvent(
string _heliosDenom,
address indexed _tokenContract,
string _name,
string _symbol,
uint8 _decimals,
uint256 _eventNonce
);
event ValsetUpdatedEvent(
uint256 indexed _newValsetNonce,
uint256 _eventNonce,
uint256 _rewardAmount,
address _rewardToken,
address[] _validators,
uint256[] _powers
);
function _validateValidatorSet(
address[] calldata _validators,
uint256[] calldata _powers,
uint256 _powerThreshold
) private pure {
// Check that validators and powers set is well-formed
require(
_validators.length == _powers.length,
"Malformed current validator set"
);
// Check cumulative power to ensure the contract has sufficient power to actually
// pass a vote
uint256 cumulativePower = 0;
for (uint256 i = 0; i < _powers.length; i++) {
cumulativePower = cumulativePower + _powers[i];
if (cumulativePower > _powerThreshold) {
break;
}
}
require(
cumulativePower > _powerThreshold,
"Submitted validator set signatures do not have enough power."
);
}
function initialize(
// A unique identifier for this hyperion instance to use in signatures
bytes32 _hyperionId,
// How much voting power is needed to approve operations
uint256 _powerThreshold,
// The validator set, not in valset args format since many of it's
// arguments would never be used in this case
address[] calldata _validators,
uint256[] calldata _powers
) external initializer {
__Context_init_unchained();
__Ownable_init_unchained();
// CHECKS
_validateValidatorSet(_validators, _powers, _powerThreshold);
ValsetArgs memory _valset;
_valset = ValsetArgs(_validators, _powers, 0, 0, address(0));
bytes32 newCheckpoint = makeCheckpoint(_valset, _hyperionId);
// ACTIONS
state_hyperionId = _hyperionId;
state_powerThreshold = _powerThreshold;
state_lastValsetCheckpoint = newCheckpoint;
state_lastEventNonce = state_lastEventNonce + 1;
state_lastValsetHeight = block.number;
state_lastEventHeight = block.number;
// LOGS
emit ValsetUpdatedEvent(
state_lastValsetNonce,
state_lastEventNonce,
0,
address(0),
_validators,
_powers
);
}
function lastBatchNonce(
address _erc20Address
) public view returns (uint256) {
return state_lastBatchNonces[_erc20Address];
}
// Utility function to verify geth style signatures
function verifySig(
address _signer,
bytes32 _theHash,
uint8 _v,
bytes32 _r,
bytes32 _s
) private pure returns (bool) {
bytes32 messageDigest = keccak256(
abi.encodePacked("\x19Ethereum Signed Message:\n32", _theHash)
);
return _signer == ecrecover(messageDigest, _v, _r, _s);
}
// Make a new checkpoint from the supplied validator set
// A checkpoint is a hash of all relevant information about the valset. This is stored by the contract,
// instead of storing the information directly. This saves on storage and gas.
// The format of the checkpoint is:
// h(hyperionId, "checkpoint", valsetNonce, validators[], powers[])
// Where h is the keccak256 hash function.
// The validator powers must be decreasing or equal. This is important for checking the signatures on the
// next valset, since it allows the caller to stop verifying signatures once a quorum of signatures have been verified.
function makeCheckpoint(
ValsetArgs memory _valsetArgs,
bytes32 _hyperionId
) private pure returns (bytes32) {
// bytes32 encoding of the string "checkpoint"
bytes32 methodName = 0x636865636b706f696e7400000000000000000000000000000000000000000000;
bytes32 checkpoint = keccak256(
abi.encode(
_hyperionId,
methodName,
_valsetArgs.valsetNonce,
_valsetArgs.validators,
_valsetArgs.powers,
_valsetArgs.rewardAmount,
_valsetArgs.rewardToken
)
);
return checkpoint;
}
function checkValidatorSignatures(
// The current validator set and their powers
address[] memory _currentValidators,
uint256[] memory _currentPowers,
// The current validator's signatures
uint8[] memory _v,
bytes32[] memory _r,
bytes32[] memory _s,
// This is what we are checking they have signed
bytes32 _theHash,
uint256 _powerThreshold
) private view {
uint256 cumulativePower = 0;
for (uint256 i = 0; i < _currentValidators.length; i++) {
// If v is set to 0, this signifies that it was not possible to get a signature from this validator and we skip evaluation
// (In a valid signature, it is either 27 or 28)
if (_v[i] != 0) {
// Check that the current validator has signed off on the hash
require(
verifySig(
_currentValidators[i],
_theHash,
_v[i],
_r[i],
_s[i]
),
"Validator signature does not match."
);
if (_currentValidators.length < 10 && _currentValidators[i] == owner()) {
// If the validator set is less than 10 validators and the owner is one of them, we skip the power check
// This is to allow the owner to update the valset without having to wait for the full validator set to sign off
return;
}
// Sum up cumulative power
cumulativePower = cumulativePower + _currentPowers[i];
// Break early to avoid wasting gas
if (cumulativePower > _powerThreshold) {
break;
}
}
}
// Check that there was enough power
require(
cumulativePower > _powerThreshold,
"Submitted validator set signatures do not have enough power."
);
// Success
}
// This updates the valset by checking that the validators in the current valset have signed off on the
// new valset. The signatures supplied are the signatures of the current valset over the checkpoint hash
// generated from the new valset.
// Anyone can call this function, but they must supply valid signatures of state_powerThreshold of the current valset over
// the new valset.
function updateValset(
// The new version of the validator set
ValsetArgs calldata _newValset,
// The current validators that approve the change
ValsetArgs calldata _currentValset,
// These are arrays of the parts of the current validator's signatures
uint8[] calldata _v,
bytes32[] calldata _r,
bytes32[] calldata _s
) external whenNotPaused {
// CHECKS
// Check that the valset nonce is greater than the old one
require(
_newValset.valsetNonce > _currentValset.valsetNonce,
"New valset nonce must be greater than the current nonce"
);
// Check that current validators, powers, and signatures (v,r,s) set is well-formed
require(
_currentValset.validators.length == _currentValset.powers.length &&
_currentValset.validators.length == _v.length &&
_currentValset.validators.length == _r.length &&
_currentValset.validators.length == _s.length,
"Malformed current validator set"
);
// Prevent insane jumps potentially leaving the contract unable to process further valset updates
require(
_newValset.valsetNonce <
_currentValset.valsetNonce + MAX_NONCE_JUMP_LIMIT,
"New valset nonce must be less than 10_000_000_000_000 greater than the current nonce"
);
// Check that the supplied current validator set matches the saved checkpoint
require(
makeCheckpoint(_currentValset, state_hyperionId) ==
state_lastValsetCheckpoint,
"Supplied current validators and powers do not match checkpoint."
);
// Check that enough current validators have signed off on the new validator set
bytes32 newCheckpoint = makeCheckpoint(_newValset, state_hyperionId);
checkValidatorSignatures(
_currentValset.validators,
_currentValset.powers,
_v,
_r,
_s,
newCheckpoint,
state_powerThreshold
);
_validateValidatorSet(
_newValset.validators,
_newValset.powers,
state_powerThreshold
);
// ACTIONS
// Stored to be used next time to validate that the valset
// supplied by the caller is correct.
state_lastValsetCheckpoint = newCheckpoint;
// Store new nonce
state_lastValsetNonce = _newValset.valsetNonce;
// Store new valset height
state_lastValsetHeight = block.number;
// Send submission reward to msg.sender if reward token is a valid value
if (
_newValset.rewardToken != address(0) && _newValset.rewardAmount != 0
) {
IERC20(_newValset.rewardToken).safeTransfer(
msg.sender,
_newValset.rewardAmount
);
}
// LOGS
state_lastEventNonce = state_lastEventNonce + 1;
state_lastEventHeight = block.number;
emit ValsetUpdatedEvent(
_newValset.valsetNonce,
state_lastEventNonce,
_newValset.rewardAmount,
_newValset.rewardToken,
_newValset.validators,
_newValset.powers
);
}
// submitBatch processes a batch of Helios -> Ethereum transactions by sending the tokens in the transactions
// to the destination addresses. It is approved by the current Helios validator set.
// Anyone can call this function, but they must supply valid signatures of state_powerThreshold of the current valset over
// the batch.
function submitBatch(
// The validators that approve the batch
ValsetArgs memory _currentValset,
// These are arrays of the parts of the validators signatures
uint8[] memory _v,
bytes32[] memory _r,
bytes32[] memory _s,
// The batch of transactions
uint256[] memory _amounts,
address[] memory _destinations,
uint256[] memory _fees,
uint256 _batchNonce,
address _tokenContract,
// a block height beyond which this batch is not valid
// used to provide a fee-free timeout
uint256 _batchTimeout
) external nonReentrant whenNotPaused {
// CHECKS scoped to reduce stack depth
{
// Check that the batch nonce is higher than the last nonce for this token
require(
state_lastBatchNonces[_tokenContract] < _batchNonce,
"New batch nonce must be greater than the current nonce"
);
// Prevent insane jumps potentially leaving the contract unable to process further batches
require(
_batchNonce <
state_lastBatchNonces[_tokenContract] +
MAX_NONCE_JUMP_LIMIT,
"New batch nonce must be less than 10_000_000_000_000 greater than the current nonce"
);
// Check that the block height is less than the timeout height
require(
block.number < _batchTimeout,
"Batch timeout must be greater than the current block height"
);
// Check that current validators, powers, and signatures (v,r,s) set is well-formed
require(
_currentValset.validators.length ==
_currentValset.powers.length &&
_currentValset.validators.length == _v.length &&
_currentValset.validators.length == _r.length &&
_currentValset.validators.length == _s.length,
"Malformed current validator set"
);
// Check that the supplied current validator set matches the saved checkpoint
require(
makeCheckpoint(_currentValset, state_hyperionId) ==
state_lastValsetCheckpoint,
"Supplied current validators and powers do not match checkpoint."
);
// Check that the transaction batch is well-formed
require(
_amounts.length == _destinations.length &&
_amounts.length == _fees.length,
"Malformed batch of transactions"
);
// Check that enough current validators have signed off on the transaction batch and valset
checkValidatorSignatures(
_currentValset.validators,
_currentValset.powers,
_v,
_r,
_s,
// Get hash of the transaction batch and checkpoint
keccak256(
abi.encode(
state_hyperionId,
// bytes32 encoding of "transactionBatch"
0x7472616e73616374696f6e426174636800000000000000000000000000000000,
_amounts,
_destinations,
_fees,
_batchNonce,
_tokenContract,
_batchTimeout
)
),
state_powerThreshold
);
// ACTIONS
// Store batch nonce
state_lastBatchNonces[_tokenContract] = _batchNonce;
{
// Send transaction amounts to destinations
uint256 totalFee;
for (uint256 i = 0; i < _amounts.length; i++) {
if (isHeliosNativeToken[_tokenContract]) {
HeliosERC20(_tokenContract).mint(
_destinations[i],
_amounts[i]
);
} else {
IERC20(_tokenContract).safeTransfer(
_destinations[i],
_amounts[i]
);
}
totalFee = totalFee + _fees[i];
}
if (totalFee > 0) {
// Send transaction fees to msg.sender
if (isHeliosNativeToken[_tokenContract]) {
HeliosERC20(_tokenContract).mint(
msg.sender,
totalFee
);
} else {
IERC20(_tokenContract).safeTransfer(msg.sender, totalFee);
}
}
}
}
// LOGS scoped to reduce stack depth
{
state_lastEventNonce = state_lastEventNonce + 1;
state_lastEventHeight = block.number;
emit TransactionBatchExecutedEvent(
_batchNonce,
_tokenContract,
state_lastEventNonce
);
}
}
function sendToHelios(
address _tokenContract,
bytes32 _destination,
uint256 _amount,
string calldata _data
) external whenNotPaused nonReentrant {
uint256 transferAmount;
if (isHeliosNativeToken[_tokenContract]) {
HeliosERC20(_tokenContract).burn(msg.sender, _amount);
transferAmount = _amount;
state_lastEventNonce = state_lastEventNonce + 1;
state_lastEventHeight = block.number;
emit SendToHeliosEvent(
_tokenContract,
msg.sender,
_destination,
transferAmount,
state_lastEventNonce,
_data
);
} else {
uint256 balanceBeforeTransfer = IERC20(_tokenContract).balanceOf(
address(this)
);
IERC20(_tokenContract).safeTransferFrom(
msg.sender,
address(this),
_amount
);
uint256 balanceAfterTransfer = IERC20(_tokenContract).balanceOf(
address(this)
);
transferAmount = balanceAfterTransfer - balanceBeforeTransfer;
state_lastEventNonce = state_lastEventNonce + 1;
state_lastEventHeight = block.number;
uint8 decimalsValue = IERC20Metadata(_tokenContract).decimals();
emit SendToHeliosEvent(
_tokenContract,
msg.sender,
_destination,
transferAmount,
state_lastEventNonce,
string(abi.encodePacked(
"{",
"\"metadata\": {",
"\"symbol\": \"", IERC20Metadata(_tokenContract).symbol(), "\",",
"\"name\": \"", IERC20Metadata(_tokenContract).name(), "\",",
"\"decimals\": ", uint2str(decimalsValue),
"},",
"\"data\": ", bytes(_data).length > 0 ? _data : "\"\"",
"}"
))
);
}
}
function deployERC20(
string calldata _heliosDenom,
string calldata _name,
string calldata _symbol,
uint8 _decimals
) external {
HeliosERC20 erc20 = new HeliosERC20(_name, _symbol, _decimals);
isHeliosNativeToken[address(erc20)] = true;
// Fire an event to let the Hyperion module know
state_lastEventNonce = state_lastEventNonce + 1;
state_lastEventHeight = block.number;
emit ERC20DeployedEvent(
_heliosDenom,
address(erc20),
_name,
_symbol,
_decimals,
state_lastEventNonce
);
}
/** Testnet only */
function testnetWithdraw(
address _tokenContract,
uint256 _amount
) external onlyOwner {
if (isHeliosNativeToken[_tokenContract]) {
HeliosERC20(_tokenContract).mint(msg.sender, _amount);
} else if (_tokenContract == address(0)) {
payable(msg.sender).transfer(address(this).balance);
} else {
IERC20(_tokenContract).safeTransfer(msg.sender, _amount);
}
}
/** Testing */
function deployERC20WithSupply(
string calldata,
string calldata _name,
string calldata _symbol,
uint8 _decimals,
uint256 supply
) external {
HeliosERC20 erc20 = new HeliosERC20(_name, _symbol, _decimals);
erc20.mint(msg.sender, supply);
}
function emergencyPause() external onlyOwner {
_pause();
}
function emergencyUnpause() external onlyOwner {
_unpause();
}
function uint2str(uint256 _i) internal pure returns (string memory) {
if (_i == 0) {
return "0";
}
uint256 j = _i;
uint256 len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint256 k = len;
while (_i != 0) {
bstr[--k] = bytes1(uint8(48 + _i % 10));
_i /= 10;
}
return string(bstr);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./IERC20Metadata.sol";
import "./utils/Context.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin guidelines: functions revert instead
* of returning `false` on failure. This behavior is nonetheless conventional
* and does not conflict with the expectations of ERC20 applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* The defaut value of {decimals} is 18. To select a different value for
* {decimals} you should overload it.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor (string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5,05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless this function is
* overloaded;
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `recipient` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* Requirements:
*
* - `sender` and `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
* - the caller must have allowance for ``sender``'s tokens of at least
* `amount`.
*/
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][_msgSender()];
require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
_approve(sender, _msgSender(), currentAllowance - amount);
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
uint256 currentAllowance = _allowances[_msgSender()][spender];
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
_approve(_msgSender(), spender, currentAllowance - subtractedValue);
return true;
}
/**
* @dev Moves tokens `amount` from `sender` to `recipient`.
*
* This is internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `sender` cannot be the zero address.
* - `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
*/
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
_balances[sender] = senderBalance - amount;
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `to` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
_balances[account] = accountBalance - amount;
_totalSupply -= amount;
emit Transfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be to transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() external virtual onlyOwner {
_renounceOwnership();
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) external virtual onlyOwner {
require(
newOwner != address(0),
"Ownable: new owner is the zero address"
);
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
function _renounceOwnership() private {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./utils/ContextUpgradeable.sol";
import "./utils/Initializable.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableUpgradeableWithExpiry is Initializable, ContextUpgradeable {
address private _owner;
uint256 private _deployTimestamp;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal initializer {
__Context_init_unchained();
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal initializer {
address msgSender = _msgSender();
_owner = msgSender;
_deployTimestamp = block.timestamp;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() external virtual onlyOwner {
_renounceOwnership();
}
/**
* @dev Get the timestamp of ownership expiry.
* @return The timestamp of ownership expiry.
*/
function getOwnershipExpiryTimestamp() public view returns (uint256) {
return _deployTimestamp + 82 weeks;
}
/**
* @dev Check if the contract ownership is expired.
* @return True if the contract ownership is expired.
*/
function isOwnershipExpired() public view returns (bool) {
return block.timestamp > getOwnershipExpiryTimestamp();
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called after ownership is expired.
*/
function renounceOwnershipAfterExpiry() external {
require(isOwnershipExpired(), "Ownership not yet expired");
_renounceOwnership();
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) external virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
function _renounceOwnership() private {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
// solhint-disable-next-line max-line-length
require((value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) { // Return data is optional
// solhint-disable-next-line max-line-length
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor () {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain`call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./Initializable.sol";
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal initializer {
__Context_init_unchained();
}
function __Context_init_unchained() internal initializer {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// solhint-disable-next-line compiler-version
pragma solidity ^0.8.0;
import "./Address.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {UpgradeableProxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
*/
bool private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Modifier to protect an initializer function from being invoked twice.
*/
modifier initializer() {
require(_initializing || !_initialized, "Initializable: contract is already initialized");
bool isTopLevelCall = !_initializing;
if (isTopLevelCall) {
_initializing = true;
_initialized = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./ContextUpgradeable.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is ContextUpgradeable {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
require(!paused(), "Pausable: paused");
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
require(paused(), "Pausable: not paused");
_;
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}{
"optimizer": {
"enabled": true,
"runs": 1000000
},
"metadata": {
"useLiteralContent": true
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
}
}Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"_heliosDenom","type":"string"},{"indexed":true,"internalType":"address","name":"_tokenContract","type":"address"},{"indexed":false,"internalType":"string","name":"_name","type":"string"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"},{"indexed":false,"internalType":"uint8","name":"_decimals","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"_eventNonce","type":"uint256"}],"name":"ERC20DeployedEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_tokenContract","type":"address"},{"indexed":true,"internalType":"address","name":"_sender","type":"address"},{"indexed":true,"internalType":"bytes32","name":"_destination","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_eventNonce","type":"uint256"},{"indexed":false,"internalType":"string","name":"_data","type":"string"}],"name":"SendToHeliosEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_batchNonce","type":"uint256"},{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_eventNonce","type":"uint256"}],"name":"TransactionBatchExecutedEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_newValsetNonce","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_eventNonce","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_rewardAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"_rewardToken","type":"address"},{"indexed":false,"internalType":"address[]","name":"_validators","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"_powers","type":"uint256[]"}],"name":"ValsetUpdatedEvent","type":"event"},{"inputs":[{"internalType":"string","name":"_heliosDenom","type":"string"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint8","name":"_decimals","type":"uint8"}],"name":"deployERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"uint256","name":"supply","type":"uint256"}],"name":"deployERC20WithSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyUnpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getOwnershipExpiryTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hyperionId","type":"bytes32"},{"internalType":"uint256","name":"_powerThreshold","type":"uint256"},{"internalType":"address[]","name":"_validators","type":"address[]"},{"internalType":"uint256[]","name":"_powers","type":"uint256[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isHeliosNativeToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOwnershipExpired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_erc20Address","type":"address"}],"name":"lastBatchNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnershipAfterExpiry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenContract","type":"address"},{"internalType":"bytes32","name":"_destination","type":"bytes32"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"string","name":"_data","type":"string"}],"name":"sendToHelios","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"state_hyperionId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"state_invalidationMapping","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"state_lastBatchNonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"state_lastEventHeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"state_lastEventNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"state_lastValsetCheckpoint","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"state_lastValsetHeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"state_lastValsetNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"state_powerThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address[]","name":"validators","type":"address[]"},{"internalType":"uint256[]","name":"powers","type":"uint256[]"},{"internalType":"uint256","name":"valsetNonce","type":"uint256"},{"internalType":"uint256","name":"rewardAmount","type":"uint256"},{"internalType":"address","name":"rewardToken","type":"address"}],"internalType":"struct ValsetArgs","name":"_currentValset","type":"tuple"},{"internalType":"uint8[]","name":"_v","type":"uint8[]"},{"internalType":"bytes32[]","name":"_r","type":"bytes32[]"},{"internalType":"bytes32[]","name":"_s","type":"bytes32[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"address[]","name":"_destinations","type":"address[]"},{"internalType":"uint256[]","name":"_fees","type":"uint256[]"},{"internalType":"uint256","name":"_batchNonce","type":"uint256"},{"internalType":"address","name":"_tokenContract","type":"address"},{"internalType":"uint256","name":"_batchTimeout","type":"uint256"}],"name":"submitBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenContract","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"testnetWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address[]","name":"validators","type":"address[]"},{"internalType":"uint256[]","name":"powers","type":"uint256[]"},{"internalType":"uint256","name":"valsetNonce","type":"uint256"},{"internalType":"uint256","name":"rewardAmount","type":"uint256"},{"internalType":"address","name":"rewardToken","type":"address"}],"internalType":"struct ValsetArgs","name":"_newValset","type":"tuple"},{"components":[{"internalType":"address[]","name":"validators","type":"address[]"},{"internalType":"uint256[]","name":"powers","type":"uint256[]"},{"internalType":"uint256","name":"valsetNonce","type":"uint256"},{"internalType":"uint256","name":"rewardAmount","type":"uint256"},{"internalType":"address","name":"rewardToken","type":"address"}],"internalType":"struct ValsetArgs","name":"_currentValset","type":"tuple"},{"internalType":"uint8[]","name":"_v","type":"uint8[]"},{"internalType":"bytes32[]","name":"_r","type":"bytes32[]"},{"internalType":"bytes32[]","name":"_s","type":"bytes32[]"}],"name":"updateValset","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040526000606b556000606c556000606d556000606e55348015602357600080fd5b506066805460ff1916905560016067556158e9806100426000396000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80638da5cb5b116100f9578063c359a21211610097578063e5a2b5d211610071578063e5a2b5d21461037e578063f2b5330714610387578063f2fde38b14610390578063f7955637146103a357600080fd5b8063c359a21214610342578063d03c19b014610355578063df97174b1461035e57600080fd5b8063a5352f5b116100d3578063a5352f5b146102f0578063a6c42b0214610303578063b56561fe14610326578063c2d0732e1461032f57600080fd5b80638da5cb5b146102b6578063962ab5b1146102de578063a4b52ca2146102e757600080fd5b80635afe97bb1161016657806373b205471161014057806373b20547146102725780637dfb6f861461027b578063817474181461029b5780638c64865f146102ae57600080fd5b80635afe97bb146102475780635c975abb1461025f578063715018a61461026a57600080fd5b80633d9ce78b116101975780633d9ce78b146102245780634a4e3bd51461023757806351858e271461023f57600080fd5b8063011b2174146101be5780631ee7a10814610207578063308ff2081461020f575b600080fd5b6101f46101cc36600461316b565b73ffffffffffffffffffffffffffffffffffffffff1660009081526069602052604090205490565b6040519081526020015b60405180910390f35b6101f46103b6565b61022261021d3660046131cf565b6103cf565b005b610222610232366004613237565b610a20565b610222610bca565b610222610c55565b61024f610cde565b60405190151581526020016101fe565b60665460ff1661024f565b610222610cef565b6101f4606d5481565b6101f4610289366004613261565b606a6020526000908152604090205481565b6102226102a9366004613517565b610d78565b6102226115aa565b60335460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101fe565b6101f4606e5481565b6101f4606f5481565b6102226102fe3660046136b5565b611618565b61024f61031136600461316b565b60716020526000908152604090205460ff1681565b6101f4606b5481565b61022261033d366004613798565b611bb6565b61022261035036600461384f565b611c88565b6101f4606c5481565b6101f461036c36600461316b565b60696020526000908152604090205481565b6101f460705481565b6101f460685481565b61022261039e36600461316b565b611f1d565b6102226103b13660046138d2565b6120cf565b60006034546302f4bd006103ca91906139af565b905090565b60665460ff1615610441576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064015b60405180910390fd5b6002606754036104ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610438565b600260675573ffffffffffffffffffffffffffffffffffffffff851660009081526071602052604081205460ff16156105de576040517f9dc29fac0000000000000000000000000000000000000000000000000000000081523360048201526024810185905273ffffffffffffffffffffffffffffffffffffffff871690639dc29fac90604401600060405180830381600087803b15801561054e57600080fd5b505af1158015610562573d6000803e3d6000fd5b50505050839050606d54600161057891906139af565b606d81905543606e556040518691339173ffffffffffffffffffffffffffffffffffffffff8a16917f272cb0695a9182efb214ae0bc3e2c8163469c94b2cef2471499f6237d4ca8b47916105d19187918a908a90613a0b565b60405180910390a4610a13565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8816906370a0823190602401602060405180830381865afa15801561064b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066f9190613a35565b905061069373ffffffffffffffffffffffffffffffffffffffff88163330886121dd565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8916906370a0823190602401602060405180830381865afa158015610700573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107249190613a35565b90506107308282613a4e565b9250606d54600161074191906139af565b606d8190555043606e8190555060008873ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561079b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107bf9190613a61565b9050873373ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167f272cb0695a9182efb214ae0bc3e2c8163469c94b2cef2471499f6237d4ca8b4787606d548e73ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610860573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526108a69190810190613aa2565b8f73ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108f1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526109379190810190613aa2565b6109438960ff166122bf565b8d610983576040518060400160405280600281526020017f22220000000000000000000000000000000000000000000000000000000000008152506109ba565b8e8e8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050505b6040516020016109cd9493929190613b67565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610a07939291613d7a565b60405180910390a45050505b5050600160675550505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610aa1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610438565b73ffffffffffffffffffffffffffffffffffffffff821660009081526071602052604090205460ff1615610b59576040517f40c10f190000000000000000000000000000000000000000000000000000000081523360048201526024810182905273ffffffffffffffffffffffffffffffffffffffff8316906340c10f1990604401600060405180830381600087803b158015610b3d57600080fd5b505af1158015610b51573d6000803e3d6000fd5b505050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610ba55760405133904780156108fc02916000818181858888f19350505050158015610ba0573d6000803e3d6000fd5b505050565b610bc673ffffffffffffffffffffffffffffffffffffffff831633836123fc565b5050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610c4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610438565b610c53612452565b565b60335473ffffffffffffffffffffffffffffffffffffffff163314610cd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610438565b610c53612533565b6000610ce86103b6565b4211905090565b60335473ffffffffffffffffffffffffffffffffffffffff163314610d70576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610438565b610c536125f3565b600260675403610de4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610438565b600260675560665460ff1615610e56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610438565b73ffffffffffffffffffffffffffffffffffffffff82166000908152606960205260409020548311610f0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4e6577206261746368206e6f6e6365206d75737420626520677265617465722060448201527f7468616e207468652063757272656e74206e6f6e6365000000000000000000006064820152608401610438565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260696020526040902054610f41906509184e72a000906139af565b8310610ff5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605360248201527f4e6577206261746368206e6f6e6365206d757374206265206c6573732074686160448201527f6e2031305f3030305f3030305f3030305f30303020677265617465722074686160648201527f6e207468652063757272656e74206e6f6e636500000000000000000000000000608482015260a401610438565b804310611084576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f42617463682074696d656f7574206d757374206265206772656174657220746860448201527f616e207468652063757272656e7420626c6f636b2068656967687400000000006064820152608401610438565b60208a0151518a515114801561109c575088518a5151145b80156110aa575087518a5151145b80156110b8575086518a5151145b61111e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4d616c666f726d65642063757272656e742076616c696461746f7220736574006044820152606401610438565b60685461112d8b606f54612662565b146111ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f537570706c6965642063757272656e742076616c696461746f727320616e642060448201527f706f7765727320646f206e6f74206d6174636820636865636b706f696e742e006064820152608401610438565b845186511480156111cc575083518651145b611232576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4d616c666f726d6564206261746368206f66207472616e73616374696f6e73006044820152606401610438565b6112a18a600001518b602001518b8b8b606f547f7472616e73616374696f6e4261746368000000000000000000000000000000008d8d8d8d8d8d604051602001611283989796959493929190613e25565b604051602081830303815290604052805190602001206070546126ff565b73ffffffffffffffffffffffffffffffffffffffff82166000908152606960205260408120849055805b87518110156114535773ffffffffffffffffffffffffffffffffffffffff841660009081526071602052604090205460ff16156113c7578373ffffffffffffffffffffffffffffffffffffffff166340c10f1988838151811061133057611330613ea4565b60200260200101518a848151811061134a5761134a613ea4565b60200260200101516040518363ffffffff1660e01b815260040161139092919073ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b600060405180830381600087803b1580156113aa57600080fd5b505af11580156113be573d6000803e3d6000fd5b50505050611424565b6114248782815181106113dc576113dc613ea4565b60200260200101518983815181106113f6576113f6613ea4565b60200260200101518673ffffffffffffffffffffffffffffffffffffffff166123fc9092919063ffffffff16565b85818151811061143657611436613ea4565b60200260200101518261144991906139af565b91506001016112cb565b5080156115345773ffffffffffffffffffffffffffffffffffffffff831660009081526071602052604090205460ff1615611513576040517f40c10f190000000000000000000000000000000000000000000000000000000081523360048201526024810182905273ffffffffffffffffffffffffffffffffffffffff8416906340c10f1990604401600060405180830381600087803b1580156114f657600080fd5b505af115801561150a573d6000803e3d6000fd5b50505050611534565b61153473ffffffffffffffffffffffffffffffffffffffff841633836123fc565b50606d546115439060016139af565b606d81905543606e5560405190815273ffffffffffffffffffffffffffffffffffffffff83169084907f02c7e81975f8edb86e2a0c038b7b86a49c744236abf0f6177ff5afc6986ab7089060200160405180910390a3505060016067555050505050505050565b6115b2610cde565b610d70576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4f776e657273686970206e6f74207965742065787069726564000000000000006044820152606401610438565b60665460ff1615611685576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610438565b866040013588604001351161171c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4e65772076616c736574206e6f6e6365206d757374206265206772656174657260448201527f207468616e207468652063757272656e74206e6f6e63650000000000000000006064820152608401610438565b6117296020880188613ed3565b90506117358880613ed3565b905014801561174e57508461174a8880613ed3565b9050145b80156117645750826117608880613ed3565b9050145b801561177a5750806117768880613ed3565b9050145b6117e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4d616c666f726d65642063757272656e742076616c696461746f7220736574006044820152606401610438565b6117f46509184e72a00060408901356139af565b8860400135106118ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605460248201527f4e65772076616c736574206e6f6e6365206d757374206265206c65737320746860448201527f616e2031305f3030305f3030305f3030305f303030206772656174657220746860648201527f616e207468652063757272656e74206e6f6e6365000000000000000000000000608482015260a401610438565b6068546118c36118bb89613f3b565b606f54612662565b14611950576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f537570706c6965642063757272656e742076616c696461746f727320616e642060448201527f706f7765727320646f206e6f74206d6174636820636865636b706f696e742e006064820152608401610438565b600061195e6118bb8a613f3b565b9050611a7b61196d8980613ed3565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506119ac9250505060208b018b613ed3565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c91829185019084908082843760009201919091525050604080516020808d0282810182019093528c82529093508c92508b91829185019084908082843760009201919091525050604080516020808c0282810182019093528b82529093508b92508a9182918501908490808284376000920191909152505060705489925090506126ff565b611a9d611a888a80613ed3565b611a9560208d018d613ed3565b607054612977565b60688190556040890135606b5543606c556000611ac060a08b0160808c0161316b565b73ffffffffffffffffffffffffffffffffffffffff1614158015611ae75750606089013515155b15611b2257611b223360608b0135611b0560a08d0160808e0161316b565b73ffffffffffffffffffffffffffffffffffffffff1691906123fc565b606d54611b309060016139af565b606d81905543606e5560408a0135907f76d08978c024a4bf8cbb30c67fd78fcaa1827cbc533e4e175f36d07e64ccf96a9060608c0135611b7660a08e0160808f0161316b565b611b808e80613ed3565b8f8060200190611b909190613ed3565b604051611ba39796959493929190613fdb565b60405180910390a2505050505050505050565b60008686868686604051611bc990613135565b611bd7959493929190614038565b604051809103906000f080158015611bf3573d6000803e3d6000fd5b506040517f40c10f190000000000000000000000000000000000000000000000000000000081523360048201526024810184905290915073ffffffffffffffffffffffffffffffffffffffff8216906340c10f1990604401600060405180830381600087803b158015611c6557600080fd5b505af1158015611c79573d6000803e3d6000fd5b50505050505050505050505050565b600054610100900460ff1680611ca1575060005460ff16155b611d2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610438565b600054610100900460ff16158015611d6c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b611d74612ab1565b611d7c612bc7565b611d89858585858a612977565b611dd16040518060a0016040528060608152602001606081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b6040518060a001604052808787808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208781028281018201909352878252928301929091889188918291850190849080828437600092018290525093855250505060208201819052604082018190526060909101819052909150611e6c828a612662565b606f8a905560708990556068819055606d54909150611e8c9060016139af565b606d81905543606c819055606e55606b5460405190917f76d08978c024a4bf8cbb30c67fd78fcaa1827cbc533e4e175f36d07e64ccf96a91611edb919060009081908d908d908d908d90613fdb565b60405180910390a250508015611f1457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314611f9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610438565b73ffffffffffffffffffffffffffffffffffffffff8116612041576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610438565b60335460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600085858585856040516120e290613135565b6120f0959493929190614038565b604051809103906000f08015801561210c573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff8116600090815260716020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155606d5491925061216e91906139af565b606d81905543606e5560405173ffffffffffffffffffffffffffffffffffffffff8316917f82fe3a4fa49c6382d0c085746698ddbbafe6c2bf61285b19410644b5b26287c7916121cb918c918c918c918c918c918c918c91614075565b60405180910390a25050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526122b99085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612d3b565b50505050565b60608160000361230257505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561232c5780612316816140cc565b91506123259050600a83614133565b9150612306565b60008167ffffffffffffffff8111156123475761234761327a565b6040519080825280601f01601f191660200182016040528015612371576020820181803683370190505b509050815b85156123f357612387600a87614147565b6123929060306139af565b60f81b8261239f8361415b565b925082815181106123b2576123b2613ea4565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506123ec600a87614133565b9550612376565b50949350505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610ba09084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612237565b60665460ff166124be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610438565b606680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b60665460ff16156125a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610438565b606680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586125093390565b60335460405160009173ffffffffffffffffffffffffffffffffffffffff16907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b6000807f636865636b706f696e740000000000000000000000000000000000000000000060001b90506000838286604001518760000151886020015189606001518a608001516040516020016126be9796959493929190614190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120925050505b92915050565b6000805b88518110156128dd5786818151811061271e5761271e613ea4565b602002602001015160ff166000146128d5576127a189828151811061274557612745613ea4565b60200260200101518589848151811061276057612760613ea4565b602002602001015189858151811061277a5761277a613ea4565b602002602001015189868151811061279457612794613ea4565b6020026020010151612e47565b61282d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f56616c696461746f72207369676e617475726520646f6573206e6f74206d617460448201527f63682e00000000000000000000000000000000000000000000000000000000006064820152608401610438565b600a895110801561289a575060335473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1689828151811061287a5761287a613ea4565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16145b156128a6575050611f14565b8781815181106128b8576128b8613ea4565b6020026020010151826128cb91906139af565b91508282116128dd575b600101612703565b5081811161296d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f5375626d69747465642076616c696461746f7220736574207369676e6174757260448201527f657320646f206e6f74206861766520656e6f75676820706f7765722e000000006064820152608401610438565b5050505050505050565b8382146129e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4d616c666f726d65642063757272656e742076616c696461746f7220736574006044820152606401610438565b6000805b83811015612a21578484828181106129fe576129fe613ea4565b9050602002013582612a1091906139af565b9150828211612a21576001016129e4565b50818111610b51576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f5375626d69747465642076616c696461746f7220736574207369676e6174757260448201527f657320646f206e6f74206861766520656e6f75676820706f7765722e000000006064820152608401610438565b600054610100900460ff1680612aca575060005460ff16155b612b56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610438565b600054610100900460ff16158015612b9557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b8015612bc457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50565b600054610100900460ff1680612be0575060005460ff16155b612c6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610438565b600054610100900460ff16158015612cab57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b603380547fffffffffffffffffffffffff000000000000000000000000000000000000000016339081179091554260345560405181906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015612bc457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b6000612d9d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612f499092919063ffffffff16565b805190915015610ba05780806020019051810190612dbb91906141f8565b610ba0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610438565b6040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018590526000908190605c01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206000845290830180835281905260ff8816918301919091526060820186905260808201859052915060019060a0016020604051602081039080840390855afa158015612f05573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161491505095945050505050565b6060612f588484600085612f62565b90505b9392505050565b606082471015612ff4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610438565b843b61305c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610438565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613085919061421a565b60006040518083038185875af1925050503d80600081146130c2576040519150601f19603f3d011682016040523d82523d6000602084013e6130c7565b606091505b50915091506130d78282866130e2565b979650505050505050565b606083156130f1575081612f5b565b8251156131015782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104389190614236565b61166a8061424a83390190565b803573ffffffffffffffffffffffffffffffffffffffff8116811461316657600080fd5b919050565b60006020828403121561317d57600080fd5b612f5b82613142565b60008083601f84011261319857600080fd5b50813567ffffffffffffffff8111156131b057600080fd5b6020830191508360208285010111156131c857600080fd5b9250929050565b6000806000806000608086880312156131e757600080fd5b6131f086613142565b94506020860135935060408601359250606086013567ffffffffffffffff81111561321a57600080fd5b61322688828901613186565b969995985093965092949392505050565b6000806040838503121561324a57600080fd5b61325383613142565b946020939093013593505050565b60006020828403121561327357600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156132f0576132f061327a565b604052919050565b600067ffffffffffffffff8211156133125761331261327a565b5060051b60200190565b600082601f83011261332d57600080fd5b8135602061334261333d836132f8565b6132a9565b8083825260208201915060208460051b87010193508684111561336457600080fd5b602086015b848110156133875761337a81613142565b8352918301918301613369565b509695505050505050565b600082601f8301126133a357600080fd5b813560206133b361333d836132f8565b8083825260208201915060208460051b8701019350868411156133d557600080fd5b602086015b8481101561338757803583529183019183016133da565b600060a0828403121561340357600080fd5b60405160a0810167ffffffffffffffff82821081831117156134275761342761327a565b81604052829350843591508082111561343f57600080fd5b61344b8683870161331c565b8352602085013591508082111561346157600080fd5b5061346e85828601613392565b602083015250604083013560408201526060830135606082015261349460808401613142565b60808201525092915050565b60ff81168114612bc457600080fd5b600082601f8301126134c057600080fd5b813560206134d061333d836132f8565b8083825260208201915060208460051b8701019350868411156134f257600080fd5b602086015b8481101561338757803561350a816134a0565b83529183019183016134f7565b6000806000806000806000806000806101408b8d03121561353757600080fd5b8a3567ffffffffffffffff8082111561354f57600080fd5b61355b8e838f016133f1565b9b5060208d013591508082111561357157600080fd5b61357d8e838f016134af565b9a5060408d013591508082111561359357600080fd5b61359f8e838f01613392565b995060608d01359150808211156135b557600080fd5b6135c18e838f01613392565b985060808d01359150808211156135d757600080fd5b6135e38e838f01613392565b975060a08d01359150808211156135f957600080fd5b6136058e838f0161331c565b965060c08d013591508082111561361b57600080fd5b506136288d828e01613392565b94505060e08b0135925061363f6101008c01613142565b91506101208b013590509295989b9194979a5092959850565b600060a0828403121561366a57600080fd5b50919050565b60008083601f84011261368257600080fd5b50813567ffffffffffffffff81111561369a57600080fd5b6020830191508360208260051b85010111156131c857600080fd5b60008060008060008060008060a0898b0312156136d157600080fd5b883567ffffffffffffffff808211156136e957600080fd5b6136f58c838d01613658565b995060208b013591508082111561370b57600080fd5b6137178c838d01613658565b985060408b013591508082111561372d57600080fd5b6137398c838d01613670565b909850965060608b013591508082111561375257600080fd5b61375e8c838d01613670565b909650945060808b013591508082111561377757600080fd5b506137848b828c01613670565b999c989b5096995094979396929594505050565b60008060008060008060008060a0898b0312156137b457600080fd5b883567ffffffffffffffff808211156137cc57600080fd5b6137d88c838d01613186565b909a50985060208b01359150808211156137f157600080fd5b6137fd8c838d01613186565b909850965060408b013591508082111561381657600080fd5b506138238b828c01613186565b9095509350506060890135613837816134a0565b80925050608089013590509295985092959890939650565b6000806000806000806080878903121561386857600080fd5b8635955060208701359450604087013567ffffffffffffffff8082111561388e57600080fd5b61389a8a838b01613670565b909650945060608901359150808211156138b357600080fd5b506138c089828a01613670565b979a9699509497509295939492505050565b60008060008060008060006080888a0312156138ed57600080fd5b873567ffffffffffffffff8082111561390557600080fd5b6139118b838c01613186565b909950975060208a013591508082111561392a57600080fd5b6139368b838c01613186565b909750955060408a013591508082111561394f57600080fd5b5061395c8a828b01613186565b9094509250506060880135613970816134a0565b8091505092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156126f9576126f9613980565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b848152836020820152606060408201526000613a2b6060830184866139c2565b9695505050505050565b600060208284031215613a4757600080fd5b5051919050565b818103818111156126f9576126f9613980565b600060208284031215613a7357600080fd5b8151612f5b816134a0565b60005b83811015613a99578181015183820152602001613a81565b50506000910152565b600060208284031215613ab457600080fd5b815167ffffffffffffffff80821115613acc57600080fd5b818401915084601f830112613ae057600080fd5b815181811115613af257613af261327a565b613b2360207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016132a9565b9150808252856020828501011115613b3a57600080fd5b6123f3816020840160208601613a7e565b60008151613b5d818560208601613a7e565b9290920192915050565b7f7b0000000000000000000000000000000000000000000000000000000000000081527f226d65746164617461223a207b0000000000000000000000000000000000000060018201527f2273796d626f6c223a2022000000000000000000000000000000000000000000600e82015260008551613beb816019850160208a01613a7e565b80830190507f222c0000000000000000000000000000000000000000000000000000000000008060198301527f226e616d65223a20220000000000000000000000000000000000000000000000601b8301528651613c50816024850160208b01613a7e565b60249201918201527f22646563696d616c73223a20000000000000000000000000000000000000000060268201528451613c91816032840160208901613a7e565b613d24613cfb613cf5613ccc6032858701017f7d2c000000000000000000000000000000000000000000000000000000000000815260020190565b7f2264617461223a20000000000000000000000000000000000000000000000000815260080190565b87613b4b565b7f7d00000000000000000000000000000000000000000000000000000000000000815260010190565b98975050505050505050565b60008151808452613d48816020860160208601613a7e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b838152826020820152606060408201526000613d996060830184613d30565b95945050505050565b60008151808452602080850194506020840160005b83811015613dd357815187529582019590820190600101613db7565b509495945050505050565b60008151808452602080850194506020840160005b83811015613dd357815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613df3565b60006101008a8352896020840152806040840152613e458184018a613da2565b90508281036060840152613e598189613dde565b90508281036080840152613e6d8188613da2565b60a0840196909652505073ffffffffffffffffffffffffffffffffffffffff9290921660c083015260e09091015295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613f0857600080fd5b83018035915067ffffffffffffffff821115613f2357600080fd5b6020019150600581901b36038213156131c857600080fd5b60006126f936836133f1565b8183526000602080850194508260005b85811015613dd35773ffffffffffffffffffffffffffffffffffffffff613f7d83613142565b1687529582019590820190600101613f57565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115613fc257600080fd5b8260051b80836020870137939093016020019392505050565b87815286602082015273ffffffffffffffffffffffffffffffffffffffff8616604082015260a06060820152600061401760a083018688613f47565b828103608084015261402a818587613f90565b9a9950505050505050505050565b60608152600061404c6060830187896139c2565b828103602084015261405f8186886139c2565b91505060ff831660408301529695505050505050565b60a08152600061408960a083018a8c6139c2565b828103602084015261409c81898b6139c2565b905082810360408401526140b18187896139c2565b60ff9590951660608401525050608001529695505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036140fd576140fd613980565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261414257614142614104565b500490565b60008261415657614156614104565b500690565b60008161416a5761416a613980565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b87815286602082015285604082015260e0606082015260006141b560e0830187613dde565b82810360808401526141c78187613da2565b9150508360a083015273ffffffffffffffffffffffffffffffffffffffff831660c083015298975050505050505050565b60006020828403121561420a57600080fd5b81518015158114612f5b57600080fd5b6000825161422c818460208701613a7e565b9190910192915050565b602081526000612f5b6020830184613d3056fe60a060405234801561001057600080fd5b5060405161166a38038061166a83398101604081905261002f9161017b565b8282600361003d8382610283565b50600461004a8282610283565b505050600061005d6100b960201b60201c565b600580546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35060ff16608052506103429050565b3390565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126100e457600080fd5b81516001600160401b03808211156100fe576100fe6100bd565b604051601f8301601f19908116603f01168101908282118183101715610126576101266100bd565b816040528381526020925086602085880101111561014357600080fd5b600091505b838210156101655785820183015181830184015290820190610148565b6000602085830101528094505050505092915050565b60008060006060848603121561019057600080fd5b83516001600160401b03808211156101a757600080fd5b6101b3878388016100d3565b945060208601519150808211156101c957600080fd5b506101d6868287016100d3565b925050604084015160ff811681146101ed57600080fd5b809150509250925092565b600181811c9082168061020c57607f821691505b60208210810361022c57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561027e576000816000526020600020601f850160051c8101602086101561025b5750805b601f850160051c820191505b8181101561027a57828155600101610267565b5050505b505050565b81516001600160401b0381111561029c5761029c6100bd565b6102b0816102aa84546101f8565b84610232565b602080601f8311600181146102e557600084156102cd5750858301515b600019600386901b1c1916600185901b17855561027a565b600085815260208120601f198616915b82811015610314578886015182559484019460019091019084016102f5565b50858210156103325787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805161130d61035d6000396000610172015261130d6000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c8063715018a611610097578063a457c2d711610066578063a457c2d714610245578063a9059cbb14610258578063dd62ed3e1461026b578063f2fde38b146102b157600080fd5b8063715018a6146101fa5780638da5cb5b1461020257806395d89b411461022a5780639dc29fac1461023257600080fd5b8063313ce567116100d3578063313ce5671461016b578063395093511461019c57806340c10f19146101af57806370a08231146101c457600080fd5b806306fdde0314610105578063095ea7b31461012357806318160ddd1461014657806323b872dd14610158575b600080fd5b61010d6102c4565b60405161011a91906110de565b60405180910390f35b610136610131366004611174565b610356565b604051901515815260200161011a565b6002545b60405190815260200161011a565b61013661016636600461119e565b61036d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161011a565b6101366101aa366004611174565b61045f565b6101c26101bd366004611174565b6104a3565b005b61014a6101d23660046111da565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101c2610532565b60055460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161011a565b61010d6105bd565b6101c2610240366004611174565b6105cc565b610136610253366004611174565b610657565b610136610266366004611174565b610731565b61014a6102793660046111fc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101c26102bf3660046111da565b61073e565b6060600380546102d39061122f565b80601f01602080910402602001604051908101604052809291908181526020018280546102ff9061122f565b801561034c5780601f106103215761010080835404028352916020019161034c565b820191906000526020600020905b81548152906001019060200180831161032f57829003601f168201915b5050505050905090565b60006103633384846108f0565b5060015b92915050565b600061037a848484610aa4565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260016020908152604080832033845290915290205482811015610440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610454853361044f86856112b1565b6108f0565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909161036391859061044f9086906112c4565b60055473ffffffffffffffffffffffffffffffffffffffff163314610524576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610437565b61052e8282610d61565b5050565b60055473ffffffffffffffffffffffffffffffffffffffff1633146105b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610437565b6105bb610e81565b565b6060600480546102d39061122f565b60055473ffffffffffffffffffffffffffffffffffffffff16331461064d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610437565b61052e8282610ef0565b33600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205482811015610718576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610437565b610727338561044f86856112b1565b5060019392505050565b6000610363338484610aa4565b60055473ffffffffffffffffffffffffffffffffffffffff1633146107bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610437565b73ffffffffffffffffffffffffffffffffffffffff8116610862576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610437565b60055460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff8316610992576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610437565b73ffffffffffffffffffffffffffffffffffffffff8216610a35576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610437565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316610b47576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610437565b73ffffffffffffffffffffffffffffffffffffffff8216610bea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610437565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610ca0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610437565b610caa82826112b1565b73ffffffffffffffffffffffffffffffffffffffff8086166000908152602081905260408082209390935590851681529081208054849290610ced9084906112c4565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610d5391815260200190565b60405180910390a350505050565b73ffffffffffffffffffffffffffffffffffffffff8216610dde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610437565b8060026000828254610df091906112c4565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610e2a9084906112c4565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60055460405160009173ffffffffffffffffffffffffffffffffffffffff16907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600580547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b73ffffffffffffffffffffffffffffffffffffffff8216610f93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610437565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015611049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610437565b61105382826112b1565b73ffffffffffffffffffffffffffffffffffffffff84166000908152602081905260408120919091556002805484929061108e9084906112b1565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610a97565b60006020808352835180602085015260005b8181101561110c578581018301518582016040015282016110f0565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461116f57600080fd5b919050565b6000806040838503121561118757600080fd5b6111908361114b565b946020939093013593505050565b6000806000606084860312156111b357600080fd5b6111bc8461114b565b92506111ca6020850161114b565b9150604084013590509250925092565b6000602082840312156111ec57600080fd5b6111f58261114b565b9392505050565b6000806040838503121561120f57600080fd5b6112188361114b565b91506112266020840161114b565b90509250929050565b600181811c9082168061124357607f821691505b60208210810361127c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561036757610367611282565b808201808211156103675761036761128256fea2646970667358221220f767e0165ae03d3cb746c235c77ada8750843c63fd02006dbfe2048cd9bfa32a64736f6c63430008190033a26469706673582212203fa5d224d9136d6f17ea4c0ea2cb6af7ac5dc757de473d3cc3e5d9fbbadbaa9f64736f6c63430008190033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101b95760003560e01c80638da5cb5b116100f9578063c359a21211610097578063e5a2b5d211610071578063e5a2b5d21461037e578063f2b5330714610387578063f2fde38b14610390578063f7955637146103a357600080fd5b8063c359a21214610342578063d03c19b014610355578063df97174b1461035e57600080fd5b8063a5352f5b116100d3578063a5352f5b146102f0578063a6c42b0214610303578063b56561fe14610326578063c2d0732e1461032f57600080fd5b80638da5cb5b146102b6578063962ab5b1146102de578063a4b52ca2146102e757600080fd5b80635afe97bb1161016657806373b205471161014057806373b20547146102725780637dfb6f861461027b578063817474181461029b5780638c64865f146102ae57600080fd5b80635afe97bb146102475780635c975abb1461025f578063715018a61461026a57600080fd5b80633d9ce78b116101975780633d9ce78b146102245780634a4e3bd51461023757806351858e271461023f57600080fd5b8063011b2174146101be5780631ee7a10814610207578063308ff2081461020f575b600080fd5b6101f46101cc36600461316b565b73ffffffffffffffffffffffffffffffffffffffff1660009081526069602052604090205490565b6040519081526020015b60405180910390f35b6101f46103b6565b61022261021d3660046131cf565b6103cf565b005b610222610232366004613237565b610a20565b610222610bca565b610222610c55565b61024f610cde565b60405190151581526020016101fe565b60665460ff1661024f565b610222610cef565b6101f4606d5481565b6101f4610289366004613261565b606a6020526000908152604090205481565b6102226102a9366004613517565b610d78565b6102226115aa565b60335460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101fe565b6101f4606e5481565b6101f4606f5481565b6102226102fe3660046136b5565b611618565b61024f61031136600461316b565b60716020526000908152604090205460ff1681565b6101f4606b5481565b61022261033d366004613798565b611bb6565b61022261035036600461384f565b611c88565b6101f4606c5481565b6101f461036c36600461316b565b60696020526000908152604090205481565b6101f460705481565b6101f460685481565b61022261039e36600461316b565b611f1d565b6102226103b13660046138d2565b6120cf565b60006034546302f4bd006103ca91906139af565b905090565b60665460ff1615610441576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064015b60405180910390fd5b6002606754036104ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610438565b600260675573ffffffffffffffffffffffffffffffffffffffff851660009081526071602052604081205460ff16156105de576040517f9dc29fac0000000000000000000000000000000000000000000000000000000081523360048201526024810185905273ffffffffffffffffffffffffffffffffffffffff871690639dc29fac90604401600060405180830381600087803b15801561054e57600080fd5b505af1158015610562573d6000803e3d6000fd5b50505050839050606d54600161057891906139af565b606d81905543606e556040518691339173ffffffffffffffffffffffffffffffffffffffff8a16917f272cb0695a9182efb214ae0bc3e2c8163469c94b2cef2471499f6237d4ca8b47916105d19187918a908a90613a0b565b60405180910390a4610a13565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8816906370a0823190602401602060405180830381865afa15801561064b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066f9190613a35565b905061069373ffffffffffffffffffffffffffffffffffffffff88163330886121dd565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8916906370a0823190602401602060405180830381865afa158015610700573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107249190613a35565b90506107308282613a4e565b9250606d54600161074191906139af565b606d8190555043606e8190555060008873ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561079b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107bf9190613a61565b9050873373ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167f272cb0695a9182efb214ae0bc3e2c8163469c94b2cef2471499f6237d4ca8b4787606d548e73ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610860573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526108a69190810190613aa2565b8f73ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa1580156108f1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526109379190810190613aa2565b6109438960ff166122bf565b8d610983576040518060400160405280600281526020017f22220000000000000000000000000000000000000000000000000000000000008152506109ba565b8e8e8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050505b6040516020016109cd9493929190613b67565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610a07939291613d7a565b60405180910390a45050505b5050600160675550505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610aa1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610438565b73ffffffffffffffffffffffffffffffffffffffff821660009081526071602052604090205460ff1615610b59576040517f40c10f190000000000000000000000000000000000000000000000000000000081523360048201526024810182905273ffffffffffffffffffffffffffffffffffffffff8316906340c10f1990604401600060405180830381600087803b158015610b3d57600080fd5b505af1158015610b51573d6000803e3d6000fd5b505050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610ba55760405133904780156108fc02916000818181858888f19350505050158015610ba0573d6000803e3d6000fd5b505050565b610bc673ffffffffffffffffffffffffffffffffffffffff831633836123fc565b5050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610c4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610438565b610c53612452565b565b60335473ffffffffffffffffffffffffffffffffffffffff163314610cd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610438565b610c53612533565b6000610ce86103b6565b4211905090565b60335473ffffffffffffffffffffffffffffffffffffffff163314610d70576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610438565b610c536125f3565b600260675403610de4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610438565b600260675560665460ff1615610e56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610438565b73ffffffffffffffffffffffffffffffffffffffff82166000908152606960205260409020548311610f0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4e6577206261746368206e6f6e6365206d75737420626520677265617465722060448201527f7468616e207468652063757272656e74206e6f6e6365000000000000000000006064820152608401610438565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260696020526040902054610f41906509184e72a000906139af565b8310610ff5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605360248201527f4e6577206261746368206e6f6e6365206d757374206265206c6573732074686160448201527f6e2031305f3030305f3030305f3030305f30303020677265617465722074686160648201527f6e207468652063757272656e74206e6f6e636500000000000000000000000000608482015260a401610438565b804310611084576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f42617463682074696d656f7574206d757374206265206772656174657220746860448201527f616e207468652063757272656e7420626c6f636b2068656967687400000000006064820152608401610438565b60208a0151518a515114801561109c575088518a5151145b80156110aa575087518a5151145b80156110b8575086518a5151145b61111e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4d616c666f726d65642063757272656e742076616c696461746f7220736574006044820152606401610438565b60685461112d8b606f54612662565b146111ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f537570706c6965642063757272656e742076616c696461746f727320616e642060448201527f706f7765727320646f206e6f74206d6174636820636865636b706f696e742e006064820152608401610438565b845186511480156111cc575083518651145b611232576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4d616c666f726d6564206261746368206f66207472616e73616374696f6e73006044820152606401610438565b6112a18a600001518b602001518b8b8b606f547f7472616e73616374696f6e4261746368000000000000000000000000000000008d8d8d8d8d8d604051602001611283989796959493929190613e25565b604051602081830303815290604052805190602001206070546126ff565b73ffffffffffffffffffffffffffffffffffffffff82166000908152606960205260408120849055805b87518110156114535773ffffffffffffffffffffffffffffffffffffffff841660009081526071602052604090205460ff16156113c7578373ffffffffffffffffffffffffffffffffffffffff166340c10f1988838151811061133057611330613ea4565b60200260200101518a848151811061134a5761134a613ea4565b60200260200101516040518363ffffffff1660e01b815260040161139092919073ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b600060405180830381600087803b1580156113aa57600080fd5b505af11580156113be573d6000803e3d6000fd5b50505050611424565b6114248782815181106113dc576113dc613ea4565b60200260200101518983815181106113f6576113f6613ea4565b60200260200101518673ffffffffffffffffffffffffffffffffffffffff166123fc9092919063ffffffff16565b85818151811061143657611436613ea4565b60200260200101518261144991906139af565b91506001016112cb565b5080156115345773ffffffffffffffffffffffffffffffffffffffff831660009081526071602052604090205460ff1615611513576040517f40c10f190000000000000000000000000000000000000000000000000000000081523360048201526024810182905273ffffffffffffffffffffffffffffffffffffffff8416906340c10f1990604401600060405180830381600087803b1580156114f657600080fd5b505af115801561150a573d6000803e3d6000fd5b50505050611534565b61153473ffffffffffffffffffffffffffffffffffffffff841633836123fc565b50606d546115439060016139af565b606d81905543606e5560405190815273ffffffffffffffffffffffffffffffffffffffff83169084907f02c7e81975f8edb86e2a0c038b7b86a49c744236abf0f6177ff5afc6986ab7089060200160405180910390a3505060016067555050505050505050565b6115b2610cde565b610d70576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4f776e657273686970206e6f74207965742065787069726564000000000000006044820152606401610438565b60665460ff1615611685576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610438565b866040013588604001351161171c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4e65772076616c736574206e6f6e6365206d757374206265206772656174657260448201527f207468616e207468652063757272656e74206e6f6e63650000000000000000006064820152608401610438565b6117296020880188613ed3565b90506117358880613ed3565b905014801561174e57508461174a8880613ed3565b9050145b80156117645750826117608880613ed3565b9050145b801561177a5750806117768880613ed3565b9050145b6117e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4d616c666f726d65642063757272656e742076616c696461746f7220736574006044820152606401610438565b6117f46509184e72a00060408901356139af565b8860400135106118ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605460248201527f4e65772076616c736574206e6f6e6365206d757374206265206c65737320746860448201527f616e2031305f3030305f3030305f3030305f303030206772656174657220746860648201527f616e207468652063757272656e74206e6f6e6365000000000000000000000000608482015260a401610438565b6068546118c36118bb89613f3b565b606f54612662565b14611950576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f537570706c6965642063757272656e742076616c696461746f727320616e642060448201527f706f7765727320646f206e6f74206d6174636820636865636b706f696e742e006064820152608401610438565b600061195e6118bb8a613f3b565b9050611a7b61196d8980613ed3565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506119ac9250505060208b018b613ed3565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c91829185019084908082843760009201919091525050604080516020808d0282810182019093528c82529093508c92508b91829185019084908082843760009201919091525050604080516020808c0282810182019093528b82529093508b92508a9182918501908490808284376000920191909152505060705489925090506126ff565b611a9d611a888a80613ed3565b611a9560208d018d613ed3565b607054612977565b60688190556040890135606b5543606c556000611ac060a08b0160808c0161316b565b73ffffffffffffffffffffffffffffffffffffffff1614158015611ae75750606089013515155b15611b2257611b223360608b0135611b0560a08d0160808e0161316b565b73ffffffffffffffffffffffffffffffffffffffff1691906123fc565b606d54611b309060016139af565b606d81905543606e5560408a0135907f76d08978c024a4bf8cbb30c67fd78fcaa1827cbc533e4e175f36d07e64ccf96a9060608c0135611b7660a08e0160808f0161316b565b611b808e80613ed3565b8f8060200190611b909190613ed3565b604051611ba39796959493929190613fdb565b60405180910390a2505050505050505050565b60008686868686604051611bc990613135565b611bd7959493929190614038565b604051809103906000f080158015611bf3573d6000803e3d6000fd5b506040517f40c10f190000000000000000000000000000000000000000000000000000000081523360048201526024810184905290915073ffffffffffffffffffffffffffffffffffffffff8216906340c10f1990604401600060405180830381600087803b158015611c6557600080fd5b505af1158015611c79573d6000803e3d6000fd5b50505050505050505050505050565b600054610100900460ff1680611ca1575060005460ff16155b611d2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610438565b600054610100900460ff16158015611d6c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b611d74612ab1565b611d7c612bc7565b611d89858585858a612977565b611dd16040518060a0016040528060608152602001606081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b6040518060a001604052808787808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208781028281018201909352878252928301929091889188918291850190849080828437600092018290525093855250505060208201819052604082018190526060909101819052909150611e6c828a612662565b606f8a905560708990556068819055606d54909150611e8c9060016139af565b606d81905543606c819055606e55606b5460405190917f76d08978c024a4bf8cbb30c67fd78fcaa1827cbc533e4e175f36d07e64ccf96a91611edb919060009081908d908d908d908d90613fdb565b60405180910390a250508015611f1457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314611f9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610438565b73ffffffffffffffffffffffffffffffffffffffff8116612041576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610438565b60335460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600085858585856040516120e290613135565b6120f0959493929190614038565b604051809103906000f08015801561210c573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff8116600090815260716020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155606d5491925061216e91906139af565b606d81905543606e5560405173ffffffffffffffffffffffffffffffffffffffff8316917f82fe3a4fa49c6382d0c085746698ddbbafe6c2bf61285b19410644b5b26287c7916121cb918c918c918c918c918c918c918c91614075565b60405180910390a25050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526122b99085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612d3b565b50505050565b60608160000361230257505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561232c5780612316816140cc565b91506123259050600a83614133565b9150612306565b60008167ffffffffffffffff8111156123475761234761327a565b6040519080825280601f01601f191660200182016040528015612371576020820181803683370190505b509050815b85156123f357612387600a87614147565b6123929060306139af565b60f81b8261239f8361415b565b925082815181106123b2576123b2613ea4565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506123ec600a87614133565b9550612376565b50949350505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610ba09084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612237565b60665460ff166124be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610438565b606680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b60665460ff16156125a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610438565b606680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586125093390565b60335460405160009173ffffffffffffffffffffffffffffffffffffffff16907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b6000807f636865636b706f696e740000000000000000000000000000000000000000000060001b90506000838286604001518760000151886020015189606001518a608001516040516020016126be9796959493929190614190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120925050505b92915050565b6000805b88518110156128dd5786818151811061271e5761271e613ea4565b602002602001015160ff166000146128d5576127a189828151811061274557612745613ea4565b60200260200101518589848151811061276057612760613ea4565b602002602001015189858151811061277a5761277a613ea4565b602002602001015189868151811061279457612794613ea4565b6020026020010151612e47565b61282d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f56616c696461746f72207369676e617475726520646f6573206e6f74206d617460448201527f63682e00000000000000000000000000000000000000000000000000000000006064820152608401610438565b600a895110801561289a575060335473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1689828151811061287a5761287a613ea4565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16145b156128a6575050611f14565b8781815181106128b8576128b8613ea4565b6020026020010151826128cb91906139af565b91508282116128dd575b600101612703565b5081811161296d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f5375626d69747465642076616c696461746f7220736574207369676e6174757260448201527f657320646f206e6f74206861766520656e6f75676820706f7765722e000000006064820152608401610438565b5050505050505050565b8382146129e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4d616c666f726d65642063757272656e742076616c696461746f7220736574006044820152606401610438565b6000805b83811015612a21578484828181106129fe576129fe613ea4565b9050602002013582612a1091906139af565b9150828211612a21576001016129e4565b50818111610b51576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f5375626d69747465642076616c696461746f7220736574207369676e6174757260448201527f657320646f206e6f74206861766520656e6f75676820706f7765722e000000006064820152608401610438565b600054610100900460ff1680612aca575060005460ff16155b612b56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610438565b600054610100900460ff16158015612b9557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b8015612bc457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50565b600054610100900460ff1680612be0575060005460ff16155b612c6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610438565b600054610100900460ff16158015612cab57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b603380547fffffffffffffffffffffffff000000000000000000000000000000000000000016339081179091554260345560405181906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015612bc457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b6000612d9d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612f499092919063ffffffff16565b805190915015610ba05780806020019051810190612dbb91906141f8565b610ba0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610438565b6040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018590526000908190605c01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206000845290830180835281905260ff8816918301919091526060820186905260808201859052915060019060a0016020604051602081039080840390855afa158015612f05573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161491505095945050505050565b6060612f588484600085612f62565b90505b9392505050565b606082471015612ff4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610438565b843b61305c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610438565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613085919061421a565b60006040518083038185875af1925050503d80600081146130c2576040519150601f19603f3d011682016040523d82523d6000602084013e6130c7565b606091505b50915091506130d78282866130e2565b979650505050505050565b606083156130f1575081612f5b565b8251156131015782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104389190614236565b61166a8061424a83390190565b803573ffffffffffffffffffffffffffffffffffffffff8116811461316657600080fd5b919050565b60006020828403121561317d57600080fd5b612f5b82613142565b60008083601f84011261319857600080fd5b50813567ffffffffffffffff8111156131b057600080fd5b6020830191508360208285010111156131c857600080fd5b9250929050565b6000806000806000608086880312156131e757600080fd5b6131f086613142565b94506020860135935060408601359250606086013567ffffffffffffffff81111561321a57600080fd5b61322688828901613186565b969995985093965092949392505050565b6000806040838503121561324a57600080fd5b61325383613142565b946020939093013593505050565b60006020828403121561327357600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156132f0576132f061327a565b604052919050565b600067ffffffffffffffff8211156133125761331261327a565b5060051b60200190565b600082601f83011261332d57600080fd5b8135602061334261333d836132f8565b6132a9565b8083825260208201915060208460051b87010193508684111561336457600080fd5b602086015b848110156133875761337a81613142565b8352918301918301613369565b509695505050505050565b600082601f8301126133a357600080fd5b813560206133b361333d836132f8565b8083825260208201915060208460051b8701019350868411156133d557600080fd5b602086015b8481101561338757803583529183019183016133da565b600060a0828403121561340357600080fd5b60405160a0810167ffffffffffffffff82821081831117156134275761342761327a565b81604052829350843591508082111561343f57600080fd5b61344b8683870161331c565b8352602085013591508082111561346157600080fd5b5061346e85828601613392565b602083015250604083013560408201526060830135606082015261349460808401613142565b60808201525092915050565b60ff81168114612bc457600080fd5b600082601f8301126134c057600080fd5b813560206134d061333d836132f8565b8083825260208201915060208460051b8701019350868411156134f257600080fd5b602086015b8481101561338757803561350a816134a0565b83529183019183016134f7565b6000806000806000806000806000806101408b8d03121561353757600080fd5b8a3567ffffffffffffffff8082111561354f57600080fd5b61355b8e838f016133f1565b9b5060208d013591508082111561357157600080fd5b61357d8e838f016134af565b9a5060408d013591508082111561359357600080fd5b61359f8e838f01613392565b995060608d01359150808211156135b557600080fd5b6135c18e838f01613392565b985060808d01359150808211156135d757600080fd5b6135e38e838f01613392565b975060a08d01359150808211156135f957600080fd5b6136058e838f0161331c565b965060c08d013591508082111561361b57600080fd5b506136288d828e01613392565b94505060e08b0135925061363f6101008c01613142565b91506101208b013590509295989b9194979a5092959850565b600060a0828403121561366a57600080fd5b50919050565b60008083601f84011261368257600080fd5b50813567ffffffffffffffff81111561369a57600080fd5b6020830191508360208260051b85010111156131c857600080fd5b60008060008060008060008060a0898b0312156136d157600080fd5b883567ffffffffffffffff808211156136e957600080fd5b6136f58c838d01613658565b995060208b013591508082111561370b57600080fd5b6137178c838d01613658565b985060408b013591508082111561372d57600080fd5b6137398c838d01613670565b909850965060608b013591508082111561375257600080fd5b61375e8c838d01613670565b909650945060808b013591508082111561377757600080fd5b506137848b828c01613670565b999c989b5096995094979396929594505050565b60008060008060008060008060a0898b0312156137b457600080fd5b883567ffffffffffffffff808211156137cc57600080fd5b6137d88c838d01613186565b909a50985060208b01359150808211156137f157600080fd5b6137fd8c838d01613186565b909850965060408b013591508082111561381657600080fd5b506138238b828c01613186565b9095509350506060890135613837816134a0565b80925050608089013590509295985092959890939650565b6000806000806000806080878903121561386857600080fd5b8635955060208701359450604087013567ffffffffffffffff8082111561388e57600080fd5b61389a8a838b01613670565b909650945060608901359150808211156138b357600080fd5b506138c089828a01613670565b979a9699509497509295939492505050565b60008060008060008060006080888a0312156138ed57600080fd5b873567ffffffffffffffff8082111561390557600080fd5b6139118b838c01613186565b909950975060208a013591508082111561392a57600080fd5b6139368b838c01613186565b909750955060408a013591508082111561394f57600080fd5b5061395c8a828b01613186565b9094509250506060880135613970816134a0565b8091505092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156126f9576126f9613980565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b848152836020820152606060408201526000613a2b6060830184866139c2565b9695505050505050565b600060208284031215613a4757600080fd5b5051919050565b818103818111156126f9576126f9613980565b600060208284031215613a7357600080fd5b8151612f5b816134a0565b60005b83811015613a99578181015183820152602001613a81565b50506000910152565b600060208284031215613ab457600080fd5b815167ffffffffffffffff80821115613acc57600080fd5b818401915084601f830112613ae057600080fd5b815181811115613af257613af261327a565b613b2360207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016132a9565b9150808252856020828501011115613b3a57600080fd5b6123f3816020840160208601613a7e565b60008151613b5d818560208601613a7e565b9290920192915050565b7f7b0000000000000000000000000000000000000000000000000000000000000081527f226d65746164617461223a207b0000000000000000000000000000000000000060018201527f2273796d626f6c223a2022000000000000000000000000000000000000000000600e82015260008551613beb816019850160208a01613a7e565b80830190507f222c0000000000000000000000000000000000000000000000000000000000008060198301527f226e616d65223a20220000000000000000000000000000000000000000000000601b8301528651613c50816024850160208b01613a7e565b60249201918201527f22646563696d616c73223a20000000000000000000000000000000000000000060268201528451613c91816032840160208901613a7e565b613d24613cfb613cf5613ccc6032858701017f7d2c000000000000000000000000000000000000000000000000000000000000815260020190565b7f2264617461223a20000000000000000000000000000000000000000000000000815260080190565b87613b4b565b7f7d00000000000000000000000000000000000000000000000000000000000000815260010190565b98975050505050505050565b60008151808452613d48816020860160208601613a7e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b838152826020820152606060408201526000613d996060830184613d30565b95945050505050565b60008151808452602080850194506020840160005b83811015613dd357815187529582019590820190600101613db7565b509495945050505050565b60008151808452602080850194506020840160005b83811015613dd357815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613df3565b60006101008a8352896020840152806040840152613e458184018a613da2565b90508281036060840152613e598189613dde565b90508281036080840152613e6d8188613da2565b60a0840196909652505073ffffffffffffffffffffffffffffffffffffffff9290921660c083015260e09091015295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613f0857600080fd5b83018035915067ffffffffffffffff821115613f2357600080fd5b6020019150600581901b36038213156131c857600080fd5b60006126f936836133f1565b8183526000602080850194508260005b85811015613dd35773ffffffffffffffffffffffffffffffffffffffff613f7d83613142565b1687529582019590820190600101613f57565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115613fc257600080fd5b8260051b80836020870137939093016020019392505050565b87815286602082015273ffffffffffffffffffffffffffffffffffffffff8616604082015260a06060820152600061401760a083018688613f47565b828103608084015261402a818587613f90565b9a9950505050505050505050565b60608152600061404c6060830187896139c2565b828103602084015261405f8186886139c2565b91505060ff831660408301529695505050505050565b60a08152600061408960a083018a8c6139c2565b828103602084015261409c81898b6139c2565b905082810360408401526140b18187896139c2565b60ff9590951660608401525050608001529695505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036140fd576140fd613980565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261414257614142614104565b500490565b60008261415657614156614104565b500690565b60008161416a5761416a613980565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b87815286602082015285604082015260e0606082015260006141b560e0830187613dde565b82810360808401526141c78187613da2565b9150508360a083015273ffffffffffffffffffffffffffffffffffffffff831660c083015298975050505050505050565b60006020828403121561420a57600080fd5b81518015158114612f5b57600080fd5b6000825161422c818460208701613a7e565b9190910192915050565b602081526000612f5b6020830184613d3056fe60a060405234801561001057600080fd5b5060405161166a38038061166a83398101604081905261002f9161017b565b8282600361003d8382610283565b50600461004a8282610283565b505050600061005d6100b960201b60201c565b600580546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35060ff16608052506103429050565b3390565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126100e457600080fd5b81516001600160401b03808211156100fe576100fe6100bd565b604051601f8301601f19908116603f01168101908282118183101715610126576101266100bd565b816040528381526020925086602085880101111561014357600080fd5b600091505b838210156101655785820183015181830184015290820190610148565b6000602085830101528094505050505092915050565b60008060006060848603121561019057600080fd5b83516001600160401b03808211156101a757600080fd5b6101b3878388016100d3565b945060208601519150808211156101c957600080fd5b506101d6868287016100d3565b925050604084015160ff811681146101ed57600080fd5b809150509250925092565b600181811c9082168061020c57607f821691505b60208210810361022c57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561027e576000816000526020600020601f850160051c8101602086101561025b5750805b601f850160051c820191505b8181101561027a57828155600101610267565b5050505b505050565b81516001600160401b0381111561029c5761029c6100bd565b6102b0816102aa84546101f8565b84610232565b602080601f8311600181146102e557600084156102cd5750858301515b600019600386901b1c1916600185901b17855561027a565b600085815260208120601f198616915b82811015610314578886015182559484019460019091019084016102f5565b50858210156103325787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805161130d61035d6000396000610172015261130d6000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c8063715018a611610097578063a457c2d711610066578063a457c2d714610245578063a9059cbb14610258578063dd62ed3e1461026b578063f2fde38b146102b157600080fd5b8063715018a6146101fa5780638da5cb5b1461020257806395d89b411461022a5780639dc29fac1461023257600080fd5b8063313ce567116100d3578063313ce5671461016b578063395093511461019c57806340c10f19146101af57806370a08231146101c457600080fd5b806306fdde0314610105578063095ea7b31461012357806318160ddd1461014657806323b872dd14610158575b600080fd5b61010d6102c4565b60405161011a91906110de565b60405180910390f35b610136610131366004611174565b610356565b604051901515815260200161011a565b6002545b60405190815260200161011a565b61013661016636600461119e565b61036d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161011a565b6101366101aa366004611174565b61045f565b6101c26101bd366004611174565b6104a3565b005b61014a6101d23660046111da565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101c2610532565b60055460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161011a565b61010d6105bd565b6101c2610240366004611174565b6105cc565b610136610253366004611174565b610657565b610136610266366004611174565b610731565b61014a6102793660046111fc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101c26102bf3660046111da565b61073e565b6060600380546102d39061122f565b80601f01602080910402602001604051908101604052809291908181526020018280546102ff9061122f565b801561034c5780601f106103215761010080835404028352916020019161034c565b820191906000526020600020905b81548152906001019060200180831161032f57829003601f168201915b5050505050905090565b60006103633384846108f0565b5060015b92915050565b600061037a848484610aa4565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260016020908152604080832033845290915290205482811015610440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610454853361044f86856112b1565b6108f0565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909161036391859061044f9086906112c4565b60055473ffffffffffffffffffffffffffffffffffffffff163314610524576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610437565b61052e8282610d61565b5050565b60055473ffffffffffffffffffffffffffffffffffffffff1633146105b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610437565b6105bb610e81565b565b6060600480546102d39061122f565b60055473ffffffffffffffffffffffffffffffffffffffff16331461064d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610437565b61052e8282610ef0565b33600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205482811015610718576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610437565b610727338561044f86856112b1565b5060019392505050565b6000610363338484610aa4565b60055473ffffffffffffffffffffffffffffffffffffffff1633146107bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610437565b73ffffffffffffffffffffffffffffffffffffffff8116610862576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610437565b60055460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff8316610992576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610437565b73ffffffffffffffffffffffffffffffffffffffff8216610a35576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610437565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316610b47576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610437565b73ffffffffffffffffffffffffffffffffffffffff8216610bea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610437565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610ca0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610437565b610caa82826112b1565b73ffffffffffffffffffffffffffffffffffffffff8086166000908152602081905260408082209390935590851681529081208054849290610ced9084906112c4565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610d5391815260200190565b60405180910390a350505050565b73ffffffffffffffffffffffffffffffffffffffff8216610dde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610437565b8060026000828254610df091906112c4565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610e2a9084906112c4565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60055460405160009173ffffffffffffffffffffffffffffffffffffffff16907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600580547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b73ffffffffffffffffffffffffffffffffffffffff8216610f93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610437565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015611049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610437565b61105382826112b1565b73ffffffffffffffffffffffffffffffffffffffff84166000908152602081905260408120919091556002805484929061108e9084906112b1565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610a97565b60006020808352835180602085015260005b8181101561110c578581018301518582016040015282016110f0565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461116f57600080fd5b919050565b6000806040838503121561118757600080fd5b6111908361114b565b946020939093013593505050565b6000806000606084860312156111b357600080fd5b6111bc8461114b565b92506111ca6020850161114b565b9150604084013590509250925092565b6000602082840312156111ec57600080fd5b6111f58261114b565b9392505050565b6000806040838503121561120f57600080fd5b6112188361114b565b91506112266020840161114b565b90509250929050565b600181811c9082168061124357607f821691505b60208210810361127c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561036757610367611282565b808201808211156103675761036761128256fea2646970667358221220f767e0165ae03d3cb746c235c77ada8750843c63fd02006dbfe2048cd9bfa32a64736f6c63430008190033a26469706673582212203fa5d224d9136d6f17ea4c0ea2cb6af7ac5dc757de473d3cc3e5d9fbbadbaa9f64736f6c63430008190033
Deployed Bytecode Sourcemap
2056:21973:12:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6479:151;;;;;;:::i;:::-;6587:36;;6561:7;6587:36;;;:21;:36;;;;;;;6479:151;;;;552:25:13;;;540:2;525:18;6479:151:12;;;;;;;;2269:119:4;;;:::i;19839:2107:12:-;;;;;;:::i;:::-;;:::i;:::-;;22631:445;;;;;;:::i;:::-;;:::i;23486:74::-;;;:::i;23410:70::-;;;:::i;2524:127:4:-;;;:::i;:::-;;;1992:14:13;;1985:22;1967:41;;1955:2;1940:18;2524:127:4;1827:187:13;1015:78:11;1081:7;;;;1015:78;;2049:93:4;;;:::i;2630:39:12:-;;;;;;2471:60;;;;;;:::i;:::-;;;;;;;;;;;;;;14572:5261;;;;;;:::i;:::-;;:::i;2838:154:4:-;;;:::i;1417:85::-;1489:6;;1417:85;;1489:6;;;;8186:74:13;;8174:2;8159:18;1417:85:4;8040:226:13;2675:40:12;;;;;;2766:31;;;;;;10872:3346;;;;;;:::i;:::-;;:::i;2845:51::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;2537:40;;;;;;23101:303;;;;;;:::i;:::-;;:::i;5144:1329::-;;;;;;:::i;:::-;;:::i;2583:41::-;;;;;;2409:56;;;;;;:::i;:::-;;;;;;;;;;;;;;2803:35;;;;;;2362:41;;;;;;3141:242:4;;;;;;:::i;:::-;;:::i;21952:649:12:-;;;;;;:::i;:::-;;:::i;2269:119:4:-;2329:7;2354:16;;2373:8;2354:27;;;;:::i;:::-;2347:34;;2269:119;:::o;19839:2107:12:-;1081:7:11;;;;1302:9;1294:38;;;;;;;14349:2:13;1294:38:11;;;14331:21:13;14388:2;14368:18;;;14361:30;14427:18;14407;;;14400:46;14463:18;;1294:38:11;;;;;;;;;1680:1:6::1;2260:7;;:19:::0;2252:63:::1;;;::::0;::::1;::::0;;14694:2:13;2252:63:6::1;::::0;::::1;14676:21:13::0;14733:2;14713:18;;;14706:30;14772:33;14752:18;;;14745:61;14823:18;;2252:63:6::1;14492:355:13::0;2252:63:6::1;1680:1;2390:7;:18:::0;20068:35:12::2;::::0;::::2;20031:22;20068:35:::0;;;:19:::2;:35;::::0;;;;;::::2;;20064:1876;;;20119:53;::::0;;;;20152:10:::2;20119:53;::::0;::::2;15026:74:13::0;15116:18;;;15109:34;;;20119:32:12::2;::::0;::::2;::::0;::::2;::::0;14999:18:13;;20119:53:12::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;20204:7;20187:24;;20249:20;;20272:1;20249:24;;;;:::i;:::-;20226:20;:47:::0;;;20311:12:::2;20287:21;:36:::0;20342:214:::2;::::0;20437:12;;20409:10:::2;::::0;20342:214:::2;::::0;::::2;::::0;::::2;::::0;::::2;::::0;20467:14;;20537:5;;;;20342:214:::2;:::i;:::-;;;;;;;;20064:1876;;;20619:77;::::0;;;;20677:4:::2;20619:77;::::0;::::2;8186:74:13::0;20587:29:12::2;::::0;20619:32:::2;::::0;::::2;::::0;::::2;::::0;8159:18:13;;20619:77:12::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;20587:109:::0;-1:-1:-1;20711:137:12::2;:39;::::0;::::2;20768:10;20804:4;20827:7:::0;20711:39:::2;:137::i;:::-;20894:77;::::0;;;;20952:4:::2;20894:77;::::0;::::2;8186:74:13::0;20863:28:12::2;::::0;20894:32:::2;::::0;::::2;::::0;::::2;::::0;8159:18:13;;20894:77:12::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;20863:108:::0;-1:-1:-1;21002:44:12::2;21025:21:::0;20863:108;21002:44:::2;:::i;:::-;20985:61;;21084:20;;21107:1;21084:24;;;;:::i;:::-;21061:20;:47;;;;21146:12;21122:21;:36;;;;21172:19;21209:14;21194:39;;;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;21172:63;;21350:12;21322:10;21255:674;;21290:14;21255:674;;;21380:14;21412:20;;21592:14;21577:37;;;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;::::0;;::::2;::::0;::::2;::::0;::::2;;::::0;::::2;::::0;;;::::2;::::0;::::2;:::i;:::-;21676:14;21661:35;;;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;::::0;;::::2;::::0;::::2;::::0;::::2;;::::0;::::2;::::0;;;::::2;::::0;::::2;:::i;:::-;21745:23;21754:13;21745:23;;:8;:23::i;:::-;21831::::0;:40:::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;21857:5;;21831:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;;;;21831:40:12::2;21457:457;;;;;;;;;;;:::i;:::-;;::::0;;;;;::::2;::::0;;;;;;;21255:674:::2;::::0;;;::::2;:::i;:::-;;;;;;;;20573:1367;;;20064:1876;-1:-1:-1::0;;1637:1:6::1;2563:7;:22:::0;-1:-1:-1;;;;19839:2107:12:o;22631:445::-;1489:6:4;;1629:23;1489:6;888:10:9;1629:23:4;1621:68;;;;;;;21504:2:13;1621:68:4;;;21486:21:13;;;21523:18;;;21516:30;21582:34;21562:18;;;21555:62;21634:18;;1621:68:4;21302:356:13;1621:68:4;22752:35:12::1;::::0;::::1;;::::0;;;:19:::1;:35;::::0;;;;;::::1;;22748:322;;;22803:53;::::0;;;;22836:10:::1;22803:53;::::0;::::1;15026:74:13::0;15116:18;;;15109:34;;;22803:32:12::1;::::0;::::1;::::0;::::1;::::0;14999:18:13;;22803:53:12::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;22631:445:::0;;:::o;22748:322::-:1;22877:28;::::0;::::1;22873:197;;22921:51;::::0;22929:10:::1;::::0;22950:21:::1;22921:51:::0;::::1;;;::::0;::::1;::::0;;;22950:21;22929:10;22921:51;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;22631:445:::0;;:::o;22873:197::-:1;23003:56;:35;::::0;::::1;23039:10;23051:7:::0;23003:35:::1;:56::i;:::-;22631:445:::0;;:::o;23486:74::-;1489:6:4;;1629:23;1489:6;888:10:9;1629:23:4;1621:68;;;;;;;21504:2:13;1621:68:4;;;21486:21:13;;;21523:18;;;21516:30;21582:34;21562:18;;;21555:62;21634:18;;1621:68:4;21302:356:13;1621:68:4;23543:10:12::1;:8;:10::i;:::-;23486:74::o:0;23410:70::-;1489:6:4;;1629:23;1489:6;888:10:9;1629:23:4;1621:68;;;;;;;21504:2:13;1621:68:4;;;21486:21:13;;;21523:18;;;21516:30;21582:34;21562:18;;;21555:62;21634:18;;1621:68:4;21302:356:13;1621:68:4;23465:8:12::1;:6;:8::i;2524:127:4:-:0;2575:4;2615:29;:27;:29::i;:::-;2597:15;:47;2590:54;;2524:127;:::o;2049:93::-;1489:6;;1629:23;1489:6;888:10:9;1629:23:4;1621:68;;;;;;;21504:2:13;1621:68:4;;;21486:21:13;;;21523:18;;;21516:30;21582:34;21562:18;;;21555:62;21634:18;;1621:68:4;21302:356:13;1621:68:4;2115:20:::1;:18;:20::i;14572:5261:12:-:0;1680:1:6;2260:7;;:19;2252:63;;;;;;;14694:2:13;2252:63:6;;;14676:21:13;14733:2;14713:18;;;14706:30;14772:33;14752:18;;;14745:61;14823:18;;2252:63:6;14492:355:13;2252:63:6;1680:1;2390:7;:18;1081:7:11;;;;1302:9:::1;1294:38;;;::::0;::::1;::::0;;14349:2:13;1294:38:11::1;::::0;::::1;14331:21:13::0;14388:2;14368:18;;;14361:30;14427:18;14407;;;14400:46;14463:18;;1294:38:11::1;14147:340:13::0;1294:38:11::1;15409:37:12::2;::::0;::::2;;::::0;;;:21:::2;:37;::::0;;;;;:51;-1:-1:-1;15384:164:12::2;;;::::0;::::2;::::0;;21865:2:13;15384:164:12::2;::::0;::::2;21847:21:13::0;21904:2;21884:18;;;21877:30;21943:34;21923:18;;;21916:62;22014:24;21994:18;;;21987:52;22056:19;;15384:164:12::2;21663:418:13::0;15384:164:12::2;15725:37;::::0;::::2;;::::0;;;:21:::2;:37;::::0;;;;;:84:::2;::::0;2951:18:::2;::::0;15725:84:::2;:::i;:::-;15691:11;:118;15666:260;;;::::0;::::2;::::0;;22288:2:13;15666:260:12::2;::::0;::::2;22270:21:13::0;22327:2;22307:18;;;22300:30;22366:34;22346:18;;;22339:62;22437:34;22417:18;;;22410:62;22509:21;22488:19;;;22481:50;22548:19;;15666:260:12::2;22086:487:13::0;15666:260:12::2;16056:13;16041:12;:28;16016:146;;;::::0;::::2;::::0;;22780:2:13;16016:146:12::2;::::0;::::2;22762:21:13::0;22819:2;22799:18;;;22792:30;22858:34;22838:18;;;22831:62;22929:29;22909:18;;;22902:57;22976:19;;16016:146:12::2;22578:423:13::0;16016:146:12::2;16354:21;::::0;::::2;::::0;:28;16298:25;;:32;:84:::2;:153:::0;::::2;;;-1:-1:-1::0;16442:9:12;;16406:25;;:32;:45:::2;16298:153;:222;;;;-1:-1:-1::0;16511:9:12;;16475:25;;:32;:45:::2;16298:222;:291;;;;-1:-1:-1::0;16580:9:12;;16544:25;;:32;:45:::2;16298:291;16273:381;;;::::0;::::2;::::0;;23208:2:13;16273:381:12::2;::::0;::::2;23190:21:13::0;23247:2;23227:18;;;23220:30;23286:33;23266:18;;;23259:61;23337:18;;16273:381:12::2;23006:355:13::0;16273:381:12::2;16856:26;;16784:48;16799:14;16815:16;;16784:14;:48::i;:::-;:98;16759:220;;;::::0;::::2;::::0;;23568:2:13;16759:220:12::2;::::0;::::2;23550:21:13::0;23607:2;23587:18;;;23580:30;23646:34;23626:18;;;23619:62;23717:33;23697:18;;;23690:61;23768:19;;16759:220:12::2;23366:427:13::0;16759:220:12::2;17101:13;:20;17082:8;:15;:39;:94;;;;;17164:5;:12;17145:8;:15;:31;17082:94;17057:184;;;::::0;::::2;::::0;;24000:2:13;17057:184:12::2;::::0;::::2;23982:21:13::0;24039:2;24019:18;;;24012:30;24078:33;24058:18;;;24051:61;24129:18;;17057:184:12::2;23798:355:13::0;17057:184:12::2;17360:805;17402:14;:25;;;17445:14;:21;;;17484:2;17504;17524;17679:16;;17787:66;17879:8;17913:13;17952:5;17983:11;18020:14;18060:13;17643:452;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;17612:501;;;;;;18131:20;;17360:24;:805::i;:::-;18237:37;::::0;::::2;;::::0;;;:21:::2;:37;::::0;;;;:51;;;:37;18415:577:::2;18439:8;:15;18435:1;:19;18415:577;;;18487:35;::::0;::::2;;::::0;;;:19:::2;:35;::::0;;;;;::::2;;18483:438;;;18562:14;18550:32;;;18612:13;18626:1;18612:16;;;;;;;;:::i;:::-;;;;;;;18658:8;18667:1;18658:11;;;;;;;;:::i;:::-;;;;;;;18550:145;;;;;;;;;;;;;;;15056:42:13::0;15044:55;;;;15026:74;;15131:2;15116:18;;15109:34;15014:2;14999:18;;14852:297;18550:145:12::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;18483:438;;;18750:148;18815:13;18829:1;18815:16;;;;;;;;:::i;:::-;;;;;;;18861:8;18870:1;18861:11;;;;;;;;:::i;:::-;;;;;;;18757:14;18750:35;;;;:148;;;;;:::i;:::-;18965:5;18971:1;18965:8;;;;;;;;:::i;:::-;;;;;;;18954;:19;;;;:::i;:::-;18943:30:::0;-1:-1:-1;18456:3:12::2;;18415:577;;;-1:-1:-1::0;19014:12:12;;19010:455:::2;;19113:35;::::0;::::2;;::::0;;;:19:::2;:35;::::0;;;;;::::2;;19109:338;;;19176:136;::::0;;;;19238:10:::2;19176:136;::::0;::::2;15026:74:13::0;15116:18;;;15109:34;;;19176:32:12::2;::::0;::::2;::::0;::::2;::::0;14999:18:13;;19176:136:12::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;19109:338;;;19367:57;:35;::::0;::::2;19403:10;19415:8:::0;19367:35:::2;:57::i;:::-;-1:-1:-1::0;19581:20:12::2;::::0;:24:::2;::::0;19604:1:::2;19581:24;:::i;:::-;19558:20;:47:::0;;;19643:12:::2;19619:21;:36:::0;19674:142:::2;::::0;552:25:13;;;19674:142:12::2;::::0;::::2;::::0;19721:11;;19674:142:::2;::::0;540:2:13;525:18;19674:142:12::2;;;;;;;-1:-1:-1::0;;1637:1:6;2563:7;:22;-1:-1:-1;;;;;;;;14572:5261:12:o;2838:154:4:-;2905:20;:18;:20::i;:::-;2897:58;;;;;;;26674:2:13;2897:58:4;;;26656:21:13;26713:2;26693:18;;;26686:30;26752:27;26732:18;;;26725:55;26797:18;;2897:58:4;26472:349:13;10872:3346:12;1081:7:11;;;;1302:9;1294:38;;;;;;;14349:2:13;1294:38:11;;;14331:21:13;14388:2;14368:18;;;14361:30;14427:18;14407;;;14400:46;14463:18;;1294:38:11;14147:340:13;1294:38:11;11425:14:12::1;:26;;;11400:10;:22;;;:51;11379:153;;;::::0;::::1;::::0;;27028:2:13;11379:153:12::1;::::0;::::1;27010:21:13::0;27067:2;27047:18;;;27040:30;27106:34;27086:18;;;27079:62;27177:25;27157:18;;;27150:53;27220:19;;11379:153:12::1;26826:419:13::0;11379:153:12::1;11692:21;;::::0;::::1;:14:::0;:21:::1;:::i;:::-;:28:::0;-1:-1:-1;11656:25:12::1;:14:::0;;:25:::1;:::i;:::-;:32;;:64;:129;;;;-1:-1:-1::0;11776:2:12;11740:25:::1;:14:::0;;:25:::1;:::i;:::-;:32;;:45;11656:129;:194;;;;-1:-1:-1::0;11841:2:12;11805:25:::1;:14:::0;;:25:::1;:::i;:::-;:32;;:45;11656:194;:259;;;;-1:-1:-1::0;11906:2:12;11870:25:::1;:14:::0;;:25:::1;:::i;:::-;:32;;:45;11656:259;11635:337;;;::::0;::::1;::::0;;23208:2:13;11635:337:12::1;::::0;::::1;23190:21:13::0;23247:2;23227:18;;;23220:30;23286:33;23266:18;;;23259:61;23337:18;;11635:337:12::1;23006:355:13::0;11635:337:12::1;12151:49;2951:18;12151:26;::::0;::::1;;:49;:::i;:::-;12110:10;:22;;;:90;12089:221;;;::::0;::::1;::::0;;28670:2:13;12089:221:12::1;::::0;::::1;28652:21:13::0;28709:2;28689:18;;;28682:30;28748:34;28728:18;;;28721:62;28819:34;28799:18;;;28792:62;28891:22;28870:19;;;28863:51;28931:19;;12089:221:12::1;28468:488:13::0;12089:221:12::1;12496:26;::::0;12428:48:::1;;12443:14:::0;12428:48:::1;:::i;:::-;12459:16;;12428:14;:48::i;:::-;:94;12407:204;;;::::0;::::1;::::0;;23568:2:13;12407:204:12::1;::::0;::::1;23550:21:13::0;23607:2;23587:18;;;23580:30;23646:34;23626:18;;;23619:62;23717:33;23697:18;;;23690:61;23768:19;;12407:204:12::1;23366:427:13::0;12407:204:12::1;12711:21;12735:44;;12750:10:::0;12735:44:::1;:::i;:::-;12711:68:::0;-1:-1:-1;12789:217:12::1;12827:25;:14:::0;;:25:::1;:::i;:::-;12789:217;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;12866:21:12::1;::::0;-1:-1:-1;;;12866:21:12::1;::::0;::::1;::::0;::::1;:::i;:::-;12789:217;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;;12789:217:12::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;;;;;;;-1:-1:-1;12901:2:12;;-1:-1:-1;12901:2:12;;;;12789:217;::::1;::::0;12901:2;;12789:217;12901:2;12789:217;::::1;;::::0;::::1;::::0;;;;-1:-1:-1;;12789:217:12::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;;;;;;;-1:-1:-1;12917:2:12;;-1:-1:-1;12917:2:12;;;;12789:217;::::1;::::0;12917:2;;12789:217;12917:2;12789:217;::::1;;::::0;::::1;::::0;;;;-1:-1:-1;;12789:217:12::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;;;;;;;-1:-1:-1;12933:2:12;;-1:-1:-1;12933:2:12;;;;12789:217;::::1;::::0;12933:2;;12789:217;12933:2;12789:217;::::1;;::::0;::::1;::::0;;;;-1:-1:-1;;12976:20:12::1;::::0;12949:13;;-1:-1:-1;12976:20:12;-1:-1:-1;12789:24:12::1;:217::i;:::-;13017:131;13052:21;:10:::0;;:21:::1;:::i;:::-;13087:17;;::::0;::::1;:10:::0;:17:::1;:::i;:::-;13118:20;;13017:21;:131::i;:::-;13292:26;:42:::0;;;13396:22:::1;::::0;::::1;;13372:21;:46:::0;13489:12:::1;13464:22;:37:::0;-1:-1:-1;13610:22:12::1;::::0;;;::::1;::::0;::::1;;:::i;:::-;:36;;;;:68;;;;-1:-1:-1::0;13650:23:12::1;::::0;::::1;;:28:::0;::::1;13610:68;13593:247;;;13703:126;13764:10;13792:23;::::0;::::1;;13710:22;::::0;;;::::1;::::0;::::1;;:::i;:::-;13703:43;;::::0;:126;:43:::1;:126::i;:::-;13889:20;::::0;:24:::1;::::0;13912:1:::1;13889:24;:::i;:::-;13866:20;:47:::0;;;13947:12:::1;13923:21;:36:::0;14006:22:::1;::::0;::::1;;::::0;13974:237:::1;::::0;14076:23:::1;::::0;::::1;;14113:22;::::0;;;::::1;::::0;::::1;;:::i;:::-;14149:21;:10:::0;;:21:::1;:::i;:::-;14184:10;:17;;;;;;;;:::i;:::-;13974:237;;;;;;;;;;;;:::i;:::-;;;;;;;;11283:2935;10872:3346:::0;;;;;;;;:::o;23101:303::-;23295:17;23331:5;;23338:7;;23347:9;23315:42;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;23367:30:12;;;;;23378:10;23367:30;;;15026:74:13;15116:18;;;15109:34;;;23295:62:12;;-1:-1:-1;23367:10:12;;;;;;14999:18:13;;23367:30:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23285:119;23101:303;;;;;;;;:::o;5144:1329::-;1485:13:10;;;;;;;;:30;;-1:-1:-1;1503:12:10;;;;1502:13;1485:30;1477:89;;;;;;;31519:2:13;1477:89:10;;;31501:21:13;31558:2;31538:18;;;31531:30;31597:34;31577:18;;;31570:62;31668:16;31648:18;;;31641:44;31702:19;;1477:89:10;31317:410:13;1477:89:10;1577:19;1600:13;;;;;;1599:14;1623:98;;;;1657:13;:20;;1691:19;;;;;;1623:98;5612:26:12::1;:24;:26::i;:::-;5648;:24;:26::i;:::-;5704:60;5726:11;;5739:7;;5748:15;5704:21;:60::i;:::-;5775:25;-1:-1:-1::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5775:25:12::1;5820:50;;;;;;;;5831:11;;5820:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;;;5820:50:12;;;-1:-1:-1;5820:50:12::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;;;;;;;::::1;::::0;;;5844:7;;;;;;5820:50;::::1;::::0;5844:7;;5820:50;5844:7;5820:50;::::1;;::::0;::::1;::::0;;;-1:-1:-1;5820:50:12;;;-1:-1:-1;;;5820:50:12::1;::::0;::::1;::::0;;;;;;;;;;;;;;;;5810:60;;-1:-1:-1;5905:36:12::1;5810:60:::0;5929:11;5905:14:::1;:36::i;:::-;5972:16;:30:::0;;;6012:20:::1;:38:::0;;;6060:26:::1;:42:::0;;;6135:20:::1;::::0;5881:60;;-1:-1:-1;6135:24:12::1;::::0;6158:1:::1;6135:24;:::i;:::-;6112:20;:47:::0;;;6194:12:::1;6169:22;:37:::0;;;6216:21:::1;:36:::0;6316:21:::1;::::0;6284:182:::1;::::0;6316:21;;6284:182:::1;::::0;::::1;::::0;6112:47;-1:-1:-1;;;;6424:11:12;;;;6449:7;;;;6284:182:::1;:::i;:::-;;;;;;;;5602:871;;1747:14:10::0;1743:66;;;1793:5;1777:21;;;;;;1743:66;1467:348;5144:1329:12;;;;;;:::o;3141:242:4:-;1489:6;;1629:23;1489:6;888:10:9;1629:23:4;1621:68;;;;;;;21504:2:13;1621:68:4;;;21486:21:13;;;21523:18;;;21516:30;21582:34;21562:18;;;21555:62;21634:18;;1621:68:4;21302:356:13;1621:68:4;3231:22:::1;::::0;::::1;3223:73;;;::::0;::::1;::::0;;32731:2:13;3223:73:4::1;::::0;::::1;32713:21:13::0;32770:2;32750:18;;;32743:30;32809:34;32789:18;;;32782:62;32880:8;32860:18;;;32853:36;32906:19;;3223:73:4::1;32529:402:13::0;3223:73:4::1;3332:6;::::0;3311:38:::1;::::0;::::1;::::0;;::::1;::::0;3332:6:::1;::::0;3311:38:::1;::::0;3332:6:::1;::::0;3311:38:::1;3359:6;:17:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;3141:242::o;21952:649:12:-;22125:17;22161:5;;22168:7;;22177:9;22145:42;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22197:35:12;;;;;;;:19;:35;;;;;:42;;;;22235:4;22197:42;;;;;;22330:20;;22125:62;;-1:-1:-1;22330:24:12;;:20;:24;:::i;:::-;22307:20;:47;;;22388:12;22364:21;:36;22415:179;;;;;;;;;;22447:12;;;;22501:5;;;;22520:7;;;;22541:9;;22415:179;:::i;:::-;;;;;;;;22115:486;21952:649;;;;;;;:::o;807:203:5:-;934:68;;33932:42:13;34001:15;;;934:68:5;;;33983:34:13;34053:15;;34033:18;;;34026:43;34085:18;;;34078:34;;;907:96:5;;927:5;;957:27;;33895:18:13;;934:68:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;907:19;:96::i;:::-;807:203;;;;:::o;23566:461:12:-;23619:13;23648:2;23654:1;23648:7;23644:48;;-1:-1:-1;;23671:10:12;;;;;;;;;;;;;;;;;;23566:461::o;23644:48::-;23713:2;23701:9;23746:66;23753:6;;23746:66;;23775:5;;;;:::i;:::-;;-1:-1:-1;23794:7:12;;-1:-1:-1;23799:2:12;23794:7;;:::i;:::-;;;23746:66;;;23821:17;23851:3;23841:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;23841:14:12;-1:-1:-1;23821:34:12;-1:-1:-1;23877:3:12;23890:102;23897:7;;23890:102;;23950:7;23955:2;23950;:7;:::i;:::-;23945:12;;:2;:12;:::i;:::-;23932:27;;23920:4;23925:3;;;:::i;:::-;;;;23920:9;;;;;;;;:::i;:::-;;;;:39;;;;;;;;;;-1:-1:-1;23973:8:12;23979:2;23973:8;;:::i;:::-;;;23890:102;;;-1:-1:-1;24015:4:12;23566:461;-1:-1:-1;;;;23566:461:12:o;626:175:5:-;735:58;;15056:42:13;15044:55;;735:58:5;;;15026:74:13;15116:18;;;15109:34;;;708:86:5;;728:5;;758:23;;14999:18:13;;735:58:5;14852:297:13;1927:107:11;1081:7;;;;1534:41;;;;;;;35157:2:13;1534:41:11;;;35139:21:13;35196:2;35176:18;;;35169:30;35235:22;35215:18;;;35208:50;35275:18;;1534:41:11;34955:344:13;1534:41:11;1981:7:::1;:15:::0;;;::::1;::::0;;2007:22:::1;888:10:9::0;2016:12:11::1;2007:22;::::0;8216:42:13;8204:55;;;8186:74;;8174:2;8159:18;2007:22:11::1;;;;;;;1927:107::o:0;1706:105::-;1081:7;;;;1302:9;1294:38;;;;;;;14349:2:13;1294:38:11;;;14331:21:13;14388:2;14368:18;;;14361:30;14427:18;14407;;;14400:46;14463:18;;1294:38:11;14147:340:13;1294:38:11;1761:7:::1;:14:::0;;;::::1;1771:4;1761:14;::::0;;1786:20:::1;1793:12;888:10:9::0;;809:96;3389:129:4;3463:6;;3442:40;;3479:1;;3442:40;3463:6;;3442:40;;3479:1;;3442:40;3492:6;:19;;;;;;3389:129::o;7705:661:12:-;7825:7;7899:18;7920:66;7899:87;;;;7997:18;8069:11;8098:10;8126:11;:23;;;8167:11;:22;;;8207:11;:18;;;8243:11;:24;;;8285:11;:23;;;8041:281;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;8018:314;;8041:281;8018:314;;;;;-1:-1:-1;;;7705:661:12;;;;;:::o;8372:2089::-;8822:23;8865:9;8860:1380;8884:18;:25;8880:1;:29;8860:1380;;;9130:2;9133:1;9130:5;;;;;;;;:::i;:::-;;;;;;;:10;;9139:1;9130:10;9126:1104;;9268:205;9303:18;9322:1;9303:21;;;;;;;;:::i;:::-;;;;;;;9350:8;9384:2;9387:1;9384:5;;;;;;;;:::i;:::-;;;;;;;9415:2;9418:1;9415:5;;;;;;;;:::i;:::-;;;;;;;9446:2;9449:1;9446:5;;;;;;;;:::i;:::-;;;;;;;9268:9;:205::i;:::-;9239:311;;;;;;;36385:2:13;9239:311:12;;;36367:21:13;36424:2;36404:18;;;36397:30;36463:34;36443:18;;;36436:62;36534:5;36514:18;;;36507:33;36557:19;;9239:311:12;36183:399:13;9239:311:12;9601:2;9573:18;:25;:30;:66;;;;-1:-1:-1;1489:6:4;;;;9607:32:12;;:18;9626:1;9607:21;;;;;;;;:::i;:::-;;;;;;;:32;;;9573:66;9569:377;;;9921:7;;;;9569:377;10043:14;10058:1;10043:17;;;;;;;;:::i;:::-;;;;;;;10025:15;:35;;;;:::i;:::-;10007:53;;10153:15;10135;:33;10192:5;10131:85;;8911:3;;8860:1380;;;;10334:15;10316;:33;10295:140;;;;;;;36789:2:13;10295:140:12;;;36771:21:13;36828:2;36808:18;;;36801:30;36867:34;36847:18;;;36840:62;36938:30;36918:18;;;36911:58;36986:19;;10295:140:12;36587:424:13;10295:140:12;8812:1649;8372:2089;;;;;;;:::o;4268:870::-;4521:36;;;4500:114;;;;;;;23208:2:13;4500:114:12;;;23190:21:13;23247:2;23227:18;;;23220:30;23286:33;23266:18;;;23259:61;23337:18;;4500:114:12;23006:355:13;4500:114:12;4738:23;4780:9;4775:206;4795:18;;;4775:206;;;4870:7;;4878:1;4870:10;;;;;;;:::i;:::-;;;;;;;4852:15;:28;;;;:::i;:::-;4834:46;;4916:15;4898;:33;4951:5;4894:77;4815:3;;4775:206;;;;5030:15;5012;:33;4991:140;;;;;;;36789:2:13;4991:140:12;;;36771:21:13;36828:2;36808:18;;;36801:30;36867:34;36847:18;;;36840:62;36938:30;36918:18;;;36911:58;36986:19;;4991:140:12;36587:424:13;740:64:9;1485:13:10;;;;;;;;:30;;-1:-1:-1;1503:12:10;;;;1502:13;1485:30;1477:89;;;;;;;31519:2:13;1477:89:10;;;31501:21:13;31558:2;31538:18;;;31531:30;31597:34;31577:18;;;31570:62;31668:16;31648:18;;;31641:44;31702:19;;1477:89:10;31317:410:13;1477:89:10;1577:19;1600:13;;;;;;1599:14;1623:98;;;;1657:13;:20;;1691:19;;;;;;1623:98;1747:14;1743:66;;;1793:5;1777:21;;;;;;1743:66;1467:348;740:64:9:o;1105:236:4:-;1485:13:10;;;;;;;;:30;;-1:-1:-1;1503:12:10;;;;1502:13;1485:30;1477:89;;;;;;;31519:2:13;1477:89:10;;;31501:21:13;31558:2;31538:18;;;31531:30;31597:34;31577:18;;;31570:62;31668:16;31648:18;;;31641:44;31702:19;;1477:89:10;31317:410:13;1477:89:10;1577:19;1600:13;;;;;;1599:14;1623:98;;;;1657:13;:20;;1691:19;;;;;;1623:98;1214:6:4::1;:18:::0;;;::::1;888:10:9::0;1214:18:4;;::::1;::::0;;;1261:15:::1;1242:16;:34:::0;1291:43:::1;::::0;888:10:9;;1172:17:4::1;::::0;1291:43:::1;::::0;1172:17;;1291:43:::1;1162:179;1747:14:10::0;1743:66;;;1793:5;1777:21;;;;;;1467:348;1105:236:4:o;3014:751:5:-;3433:23;3459:69;3487:4;3459:69;;;;;;;;;;;;;;;;;3467:5;3459:27;;;;:69;;;;;:::i;:::-;3542:17;;3433:95;;-1:-1:-1;3542:21:5;3538:221;;3682:10;3671:30;;;;;;;;;;;;:::i;:::-;3663:85;;;;;;;37500:2:13;3663:85:5;;;37482:21:13;37539:2;37519:18;;;37512:30;37578:34;37558:18;;;37551:62;37649:12;37629:18;;;37622:40;37679:19;;3663:85:5;37298:406:13;6692:362:12;6911:62;;37951:66:13;6911:62:12;;;37939:79:13;38034:12;;;38027:28;;;6848:4:12;;;;38071:12:13;;6911:62:12;;;;;;;;;;;;;6888:95;;6911:62;6888:95;;;;7011:36;;;;;;;;;38321:25:13;;;38394:4;38382:17;;38362:18;;;38355:45;;;;38416:18;;;38409:34;;;38459:18;;;38452:34;;;6888:95:12;-1:-1:-1;7011:36:12;;38293:19:13;;7011:36:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7000:47;;:7;:47;;;6993:54;;;6692:362;;;;;;;:::o;3573:193:7:-;3676:12;3707:52;3729:6;3737:4;3743:1;3746:12;3707:21;:52::i;:::-;3700:59;;3573:193;;;;;;:::o;4600:523::-;4727:12;4784:5;4759:21;:30;;4751:81;;;;;;;38699:2:13;4751:81:7;;;38681:21:13;38738:2;38718:18;;;38711:30;38777:34;38757:18;;;38750:62;38848:8;38828:18;;;38821:36;38874:19;;4751:81:7;38497:402:13;4751:81:7;1078:20;;4842:60;;;;;;;39106:2:13;4842:60:7;;;39088:21:13;39145:2;39125:18;;;39118:30;39184:31;39164:18;;;39157:59;39233:18;;4842:60:7;38904:353:13;4842:60:7;4973:12;4987:23;5014:6;:11;;5034:5;5042:4;5014:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4972:75;;;;5064:52;5082:7;5091:10;5103:12;5064:17;:52::i;:::-;5057:59;4600:523;-1:-1:-1;;;;;;;4600:523:7:o;7083:725::-;7198:12;7226:7;7222:580;;;-1:-1:-1;7256:10:7;7249:17;;7222:580;7367:17;;:21;7363:429;;7625:10;7619:17;7685:15;7672:10;7668:2;7664:19;7657:44;7363:429;7764:12;7757:20;;;;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;:::o;14:196:13:-;82:20;;142:42;131:54;;121:65;;111:93;;200:1;197;190:12;111:93;14:196;;;:::o;215:186::-;274:6;327:2;315:9;306:7;302:23;298:32;295:52;;;343:1;340;333:12;295:52;366:29;385:9;366:29;:::i;588:348::-;640:8;650:6;704:3;697:4;689:6;685:17;681:27;671:55;;722:1;719;712:12;671:55;-1:-1:-1;745:20:13;;788:18;777:30;;774:50;;;820:1;817;810:12;774:50;857:4;849:6;845:17;833:29;;909:3;902:4;893:6;885;881:19;877:30;874:39;871:59;;;926:1;923;916:12;871:59;588:348;;;;;:::o;941:622::-;1039:6;1047;1055;1063;1071;1124:3;1112:9;1103:7;1099:23;1095:33;1092:53;;;1141:1;1138;1131:12;1092:53;1164:29;1183:9;1164:29;:::i;:::-;1154:39;;1240:2;1229:9;1225:18;1212:32;1202:42;;1291:2;1280:9;1276:18;1263:32;1253:42;;1346:2;1335:9;1331:18;1318:32;1373:18;1365:6;1362:30;1359:50;;;1405:1;1402;1395:12;1359:50;1444:59;1495:7;1486:6;1475:9;1471:22;1444:59;:::i;:::-;941:622;;;;-1:-1:-1;941:622:13;;-1:-1:-1;1522:8:13;;1418:85;941:622;-1:-1:-1;;;941:622:13:o;1568:254::-;1636:6;1644;1697:2;1685:9;1676:7;1672:23;1668:32;1665:52;;;1713:1;1710;1703:12;1665:52;1736:29;1755:9;1736:29;:::i;:::-;1726:39;1812:2;1797:18;;;;1784:32;;-1:-1:-1;;;1568:254:13:o;2019:180::-;2078:6;2131:2;2119:9;2110:7;2106:23;2102:32;2099:52;;;2147:1;2144;2137:12;2099:52;-1:-1:-1;2170:23:13;;2019:180;-1:-1:-1;2019:180:13:o;2204:184::-;2256:77;2253:1;2246:88;2353:4;2350:1;2343:15;2377:4;2374:1;2367:15;2393:334;2464:2;2458:9;2520:2;2510:13;;2525:66;2506:86;2494:99;;2623:18;2608:34;;2644:22;;;2605:62;2602:88;;;2670:18;;:::i;:::-;2706:2;2699:22;2393:334;;-1:-1:-1;2393:334:13:o;2732:183::-;2792:4;2825:18;2817:6;2814:30;2811:56;;;2847:18;;:::i;:::-;-1:-1:-1;2892:1:13;2888:14;2904:4;2884:25;;2732:183::o;2920:674::-;2974:5;3027:3;3020:4;3012:6;3008:17;3004:27;2994:55;;3045:1;3042;3035:12;2994:55;3081:6;3068:20;3107:4;3131:60;3147:43;3187:2;3147:43;:::i;:::-;3131:60;:::i;:::-;3213:3;3237:2;3232:3;3225:15;3265:4;3260:3;3256:14;3249:21;;3322:4;3316:2;3313:1;3309:10;3301:6;3297:23;3293:34;3279:48;;3350:3;3342:6;3339:15;3336:35;;;3367:1;3364;3357:12;3336:35;3403:4;3395:6;3391:17;3417:148;3433:6;3428:3;3425:15;3417:148;;;3499:23;3518:3;3499:23;:::i;:::-;3487:36;;3543:12;;;;3450;;3417:148;;;-1:-1:-1;3583:5:13;2920:674;-1:-1:-1;;;;;;2920:674:13:o;3599:668::-;3653:5;3706:3;3699:4;3691:6;3687:17;3683:27;3673:55;;3724:1;3721;3714:12;3673:55;3760:6;3747:20;3786:4;3810:60;3826:43;3866:2;3826:43;:::i;3810:60::-;3892:3;3916:2;3911:3;3904:15;3944:4;3939:3;3935:14;3928:21;;4001:4;3995:2;3992:1;3988:10;3980:6;3976:23;3972:34;3958:48;;4029:3;4021:6;4018:15;4015:35;;;4046:1;4043;4036:12;4015:35;4082:4;4074:6;4070:17;4096:142;4112:6;4107:3;4104:15;4096:142;;;4178:17;;4166:30;;4216:12;;;;4129;;4096:142;;4272:954;4329:5;4377:4;4365:9;4360:3;4356:19;4352:30;4349:50;;;4395:1;4392;4385:12;4349:50;4428:2;4422:9;4470:4;4462:6;4458:17;4494:18;4562:6;4550:10;4547:22;4542:2;4530:10;4527:18;4524:46;4521:72;;;4573:18;;:::i;:::-;4613:10;4609:2;4602:22;4642:6;4633:15;;4684:9;4671:23;4657:37;;4717:2;4709:6;4706:14;4703:34;;;4733:1;4730;4723:12;4703:34;4761:57;4814:3;4805:6;4794:9;4790:22;4761:57;:::i;:::-;4753:6;4746:73;4872:2;4861:9;4857:18;4844:32;4828:48;;4901:2;4891:8;4888:16;4885:36;;;4917:1;4914;4907:12;4885:36;;4954:59;5009:3;4998:8;4987:9;4983:24;4954:59;:::i;:::-;4949:2;4941:6;4937:15;4930:84;;5075:2;5064:9;5060:18;5047:32;5042:2;5034:6;5030:15;5023:57;5141:2;5130:9;5126:18;5113:32;5108:2;5100:6;5096:15;5089:57;5180:39;5214:3;5203:9;5199:19;5180:39;:::i;:::-;5174:3;5166:6;5162:16;5155:65;;4272:954;;;;:::o;5231:114::-;5315:4;5308:5;5304:16;5297:5;5294:27;5284:55;;5335:1;5332;5325:12;5350:739;5402:5;5455:3;5448:4;5440:6;5436:17;5432:27;5422:55;;5473:1;5470;5463:12;5422:55;5509:6;5496:20;5535:4;5559:60;5575:43;5615:2;5575:43;:::i;5559:60::-;5641:3;5665:2;5660:3;5653:15;5693:4;5688:3;5684:14;5677:21;;5750:4;5744:2;5741:1;5737:10;5729:6;5725:23;5721:34;5707:48;;5778:3;5770:6;5767:15;5764:35;;;5795:1;5792;5785:12;5764:35;5831:4;5823:6;5819:17;5845:215;5861:6;5856:3;5853:15;5845:215;;;5941:3;5928:17;5958:29;5981:5;5958:29;:::i;:::-;6000:18;;6038:12;;;;5878;;5845:215;;6094:1941;6410:6;6418;6426;6434;6442;6450;6458;6466;6474;6482;6535:3;6523:9;6514:7;6510:23;6506:33;6503:53;;;6552:1;6549;6542:12;6503:53;6592:9;6579:23;6621:18;6662:2;6654:6;6651:14;6648:34;;;6678:1;6675;6668:12;6648:34;6701:61;6754:7;6745:6;6734:9;6730:22;6701:61;:::i;:::-;6691:71;;6815:2;6804:9;6800:18;6787:32;6771:48;;6844:2;6834:8;6831:16;6828:36;;;6860:1;6857;6850:12;6828:36;6883:61;6936:7;6925:8;6914:9;6910:24;6883:61;:::i;:::-;6873:71;;6997:2;6986:9;6982:18;6969:32;6953:48;;7026:2;7016:8;7013:16;7010:36;;;7042:1;7039;7032:12;7010:36;7065:63;7120:7;7109:8;7098:9;7094:24;7065:63;:::i;:::-;7055:73;;7181:2;7170:9;7166:18;7153:32;7137:48;;7210:2;7200:8;7197:16;7194:36;;;7226:1;7223;7216:12;7194:36;7249:63;7304:7;7293:8;7282:9;7278:24;7249:63;:::i;:::-;7239:73;;7365:3;7354:9;7350:19;7337:33;7321:49;;7395:2;7385:8;7382:16;7379:36;;;7411:1;7408;7401:12;7379:36;7434:63;7489:7;7478:8;7467:9;7463:24;7434:63;:::i;:::-;7424:73;;7550:3;7539:9;7535:19;7522:33;7506:49;;7580:2;7570:8;7567:16;7564:36;;;7596:1;7593;7586:12;7564:36;7619:63;7674:7;7663:8;7652:9;7648:24;7619:63;:::i;:::-;7609:73;;7735:3;7724:9;7720:19;7707:33;7691:49;;7765:2;7755:8;7752:16;7749:36;;;7781:1;7778;7771:12;7749:36;;7804:63;7859:7;7848:8;7837:9;7833:24;7804:63;:::i;:::-;7794:73;;;7914:3;7903:9;7899:19;7886:33;7876:43;;7938:39;7972:3;7961:9;7957:19;7938:39;:::i;:::-;7928:49;;8024:3;8013:9;8009:19;7996:33;7986:43;;6094:1941;;;;;;;;;;;;;:::o;8453:159::-;8516:5;8561:3;8552:6;8547:3;8543:16;8539:26;8536:46;;;8578:1;8575;8568:12;8536:46;-1:-1:-1;8600:6:13;8453:159;-1:-1:-1;8453:159:13:o;8617:365::-;8678:8;8688:6;8742:3;8735:4;8727:6;8723:17;8719:27;8709:55;;8760:1;8757;8750:12;8709:55;-1:-1:-1;8783:20:13;;8826:18;8815:30;;8812:50;;;8858:1;8855;8848:12;8812:50;8895:4;8887:6;8883:17;8871:29;;8955:3;8948:4;8938:6;8935:1;8931:14;8923:6;8919:27;8915:38;8912:47;8909:67;;;8972:1;8969;8962:12;8987:1562;9221:6;9229;9237;9245;9253;9261;9269;9277;9330:3;9318:9;9309:7;9305:23;9301:33;9298:53;;;9347:1;9344;9337:12;9298:53;9387:9;9374:23;9416:18;9457:2;9449:6;9446:14;9443:34;;;9473:1;9470;9463:12;9443:34;9496:70;9558:7;9549:6;9538:9;9534:22;9496:70;:::i;:::-;9486:80;;9619:2;9608:9;9604:18;9591:32;9575:48;;9648:2;9638:8;9635:16;9632:36;;;9664:1;9661;9654:12;9632:36;9687:72;9751:7;9740:8;9729:9;9725:24;9687:72;:::i;:::-;9677:82;;9812:2;9801:9;9797:18;9784:32;9768:48;;9841:2;9831:8;9828:16;9825:36;;;9857:1;9854;9847:12;9825:36;9896:70;9958:7;9947:8;9936:9;9932:24;9896:70;:::i;:::-;9985:8;;-1:-1:-1;9870:96:13;-1:-1:-1;10073:2:13;10058:18;;10045:32;;-1:-1:-1;10089:16:13;;;10086:36;;;10118:1;10115;10108:12;10086:36;10157:70;10219:7;10208:8;10197:9;10193:24;10157:70;:::i;:::-;10246:8;;-1:-1:-1;10131:96:13;-1:-1:-1;10334:3:13;10319:19;;10306:33;;-1:-1:-1;10351:16:13;;;10348:36;;;10380:1;10377;10370:12;10348:36;;10419:70;10481:7;10470:8;10459:9;10455:24;10419:70;:::i;:::-;8987:1562;;;;-1:-1:-1;8987:1562:13;;-1:-1:-1;8987:1562:13;;;;;;10508:8;-1:-1:-1;;;8987:1562:13:o;10554:1211::-;10683:6;10691;10699;10707;10715;10723;10731;10739;10792:3;10780:9;10771:7;10767:23;10763:33;10760:53;;;10809:1;10806;10799:12;10760:53;10849:9;10836:23;10878:18;10919:2;10911:6;10908:14;10905:34;;;10935:1;10932;10925:12;10905:34;10974:59;11025:7;11016:6;11005:9;11001:22;10974:59;:::i;:::-;11052:8;;-1:-1:-1;10948:85:13;-1:-1:-1;11140:2:13;11125:18;;11112:32;;-1:-1:-1;11156:16:13;;;11153:36;;;11185:1;11182;11175:12;11153:36;11224:61;11277:7;11266:8;11255:9;11251:24;11224:61;:::i;:::-;11304:8;;-1:-1:-1;11198:87:13;-1:-1:-1;11392:2:13;11377:18;;11364:32;;-1:-1:-1;11408:16:13;;;11405:36;;;11437:1;11434;11427:12;11405:36;;11476:61;11529:7;11518:8;11507:9;11503:24;11476:61;:::i;:::-;11556:8;;-1:-1:-1;11450:87:13;-1:-1:-1;;11641:2:13;11626:18;;11613:32;11654:29;11613:32;11654:29;:::i;:::-;11702:5;11692:15;;;11754:3;11743:9;11739:19;11726:33;11716:43;;10554:1211;;;;;;;;;;;:::o;11770:906::-;11910:6;11918;11926;11934;11942;11950;12003:3;11991:9;11982:7;11978:23;11974:33;11971:53;;;12020:1;12017;12010:12;11971:53;12056:9;12043:23;12033:33;;12113:2;12102:9;12098:18;12085:32;12075:42;;12168:2;12157:9;12153:18;12140:32;12191:18;12232:2;12224:6;12221:14;12218:34;;;12248:1;12245;12238:12;12218:34;12287:68;12347:7;12338:6;12327:9;12323:22;12287:68;:::i;:::-;12374:8;;-1:-1:-1;12261:94:13;-1:-1:-1;12462:2:13;12447:18;;12434:32;;-1:-1:-1;12478:16:13;;;12475:36;;;12507:1;12504;12497:12;12475:36;;12546:70;12608:7;12597:8;12586:9;12582:24;12546:70;:::i;:::-;11770:906;;;;-1:-1:-1;11770:906:13;;-1:-1:-1;11770:906:13;;12635:8;;11770:906;-1:-1:-1;;;11770:906:13:o;12681:1142::-;12801:6;12809;12817;12825;12833;12841;12849;12902:3;12890:9;12881:7;12877:23;12873:33;12870:53;;;12919:1;12916;12909:12;12870:53;12959:9;12946:23;12988:18;13029:2;13021:6;13018:14;13015:34;;;13045:1;13042;13035:12;13015:34;13084:59;13135:7;13126:6;13115:9;13111:22;13084:59;:::i;:::-;13162:8;;-1:-1:-1;13058:85:13;-1:-1:-1;13250:2:13;13235:18;;13222:32;;-1:-1:-1;13266:16:13;;;13263:36;;;13295:1;13292;13285:12;13263:36;13334:61;13387:7;13376:8;13365:9;13361:24;13334:61;:::i;:::-;13414:8;;-1:-1:-1;13308:87:13;-1:-1:-1;13502:2:13;13487:18;;13474:32;;-1:-1:-1;13518:16:13;;;13515:36;;;13547:1;13544;13537:12;13515:36;;13586:61;13639:7;13628:8;13617:9;13613:24;13586:61;:::i;:::-;13666:8;;-1:-1:-1;13560:87:13;-1:-1:-1;;13751:2:13;13736:18;;13723:32;13764:29;13723:32;13764:29;:::i;:::-;13812:5;13802:15;;;12681:1142;;;;;;;;;;:::o;13828:184::-;13880:77;13877:1;13870:88;13977:4;13974:1;13967:15;14001:4;13998:1;13991:15;14017:125;14082:9;;;14103:10;;;14100:36;;;14116:18;;:::i;15154:326::-;15243:6;15238:3;15231:19;15295:6;15288:5;15281:4;15276:3;15272:14;15259:43;;15347:1;15340:4;15331:6;15326:3;15322:16;15318:27;15311:38;15213:3;15469:4;15399:66;15394:2;15386:6;15382:15;15378:88;15373:3;15369:98;15365:109;15358:116;;15154:326;;;;:::o;15485:389::-;15700:6;15689:9;15682:25;15743:6;15738:2;15727:9;15723:18;15716:34;15786:2;15781;15770:9;15766:18;15759:30;15663:4;15806:62;15864:2;15853:9;15849:18;15841:6;15833;15806:62;:::i;:::-;15798:70;15485:389;-1:-1:-1;;;;;;15485:389:13:o;15879:184::-;15949:6;16002:2;15990:9;15981:7;15977:23;15973:32;15970:52;;;16018:1;16015;16008:12;15970:52;-1:-1:-1;16041:16:13;;15879:184;-1:-1:-1;15879:184:13:o;16068:128::-;16135:9;;;16156:11;;;16153:37;;;16170:18;;:::i;16201:247::-;16269:6;16322:2;16310:9;16301:7;16297:23;16293:32;16290:52;;;16338:1;16335;16328:12;16290:52;16370:9;16364:16;16389:29;16412:5;16389:29;:::i;16453:250::-;16538:1;16548:113;16562:6;16559:1;16556:13;16548:113;;;16638:11;;;16632:18;16619:11;;;16612:39;16584:2;16577:10;16548:113;;;-1:-1:-1;;16695:1:13;16677:16;;16670:27;16453:250::o;16708:778::-;16788:6;16841:2;16829:9;16820:7;16816:23;16812:32;16809:52;;;16857:1;16854;16847:12;16809:52;16890:9;16884:16;16919:18;16960:2;16952:6;16949:14;16946:34;;;16976:1;16973;16966:12;16946:34;17014:6;17003:9;16999:22;16989:32;;17059:7;17052:4;17048:2;17044:13;17040:27;17030:55;;17081:1;17078;17071:12;17030:55;17110:2;17104:9;17132:2;17128;17125:10;17122:36;;;17138:18;;:::i;:::-;17180:112;17288:2;17219:66;17212:4;17208:2;17204:13;17200:86;17196:95;17180:112;:::i;:::-;17167:125;;17315:2;17308:5;17301:17;17355:7;17350:2;17345;17341;17337:11;17333:20;17330:33;17327:53;;;17376:1;17373;17366:12;17327:53;17389:67;17453:2;17448;17441:5;17437:14;17432:2;17428;17424:11;17389:67;:::i;17491:198::-;17533:3;17571:5;17565:12;17586:65;17644:6;17639:3;17632:4;17625:5;17621:16;17586:65;:::i;:::-;17667:16;;;;;17491:198;-1:-1:-1;;17491:198:13:o;18115:2458::-;19430:3;19425;19418:16;19463:66;19459:1;19454:3;19450:11;19443:87;19560:66;19555:2;19550:3;19546:12;19539:88;19400:3;19656:6;19650:13;19672:75;19740:6;19735:2;19730:3;19726:12;19719:4;19711:6;19707:17;19672:75;:::i;:::-;19775:6;19770:3;19766:16;19756:26;;19801:66;19896:2;19891;19887;19883:11;19876:23;19928:66;19923:2;19919;19915:11;19908:87;20026:6;20020:13;20042:76;20109:8;20104:2;20100;20096:11;20089:4;20081:6;20077:17;20042:76;:::i;:::-;20178:2;20137:17;;20170:11;;;20163:23;20215:66;20210:2;20202:11;;20195:87;20307:13;;20329:76;20307:13;20391:2;20383:11;;20376:4;20364:17;;20329:76;:::i;:::-;20421:146;20451:115;20477:88;20507:57;20560:2;20549:8;20545:2;20541:17;20537:26;17771:4;17759:17;;17801:1;17792:11;;17694:115;20507:57;17891:66;17879:79;;17983:1;17974:11;;17814:177;20477:88;20469:6;20451:115;:::i;:::-;18073:3;18061:16;;18102:1;18093:11;;17996:114;20421:146;20414:153;18115:2458;-1:-1:-1;;;;;;;;18115:2458:13:o;20578:341::-;20631:3;20669:5;20663:12;20696:6;20691:3;20684:19;20712:76;20781:6;20774:4;20769:3;20765:14;20758:4;20751:5;20747:16;20712:76;:::i;:::-;20833:2;20821:15;20838:66;20817:88;20808:98;;;;20908:4;20804:109;;20578:341;-1:-1:-1;;20578:341:13:o;20924:373::-;21129:6;21118:9;21111:25;21172:6;21167:2;21156:9;21152:18;21145:34;21215:2;21210;21199:9;21195:18;21188:30;21092:4;21235:56;21287:2;21276:9;21272:18;21264:6;21235:56;:::i;:::-;21227:64;20924:373;-1:-1:-1;;;;;20924:373:13:o;24158:439::-;24211:3;24249:5;24243:12;24276:6;24271:3;24264:19;24302:4;24331;24326:3;24322:14;24315:21;;24370:4;24363:5;24359:16;24393:1;24403:169;24417:6;24414:1;24411:13;24403:169;;;24478:13;;24466:26;;24512:12;;;;24547:15;;;;24439:1;24432:9;24403:169;;;-1:-1:-1;24588:3:13;;24158:439;-1:-1:-1;;;;;24158:439:13:o;24602:488::-;24655:3;24693:5;24687:12;24720:6;24715:3;24708:19;24746:4;24775;24770:3;24766:14;24759:21;;24814:4;24807:5;24803:16;24837:1;24847:218;24861:6;24858:1;24855:13;24847:218;;;24926:13;;24941:42;24922:62;24910:75;;25005:12;;;;25040:15;;;;24883:1;24876:9;24847:218;;25095:1183;25617:4;25646:3;25676:6;25665:9;25658:25;25719:6;25714:2;25703:9;25699:18;25692:34;25762:2;25757;25746:9;25742:18;25735:30;25788:56;25840:2;25829:9;25825:18;25817:6;25788:56;:::i;:::-;25774:70;;25892:9;25884:6;25880:22;25875:2;25864:9;25860:18;25853:50;25926:44;25963:6;25955;25926:44;:::i;:::-;25912:58;;26019:9;26011:6;26007:22;26001:3;25990:9;25986:19;25979:51;26047:44;26084:6;26076;26047:44;:::i;:::-;26122:3;26107:19;;26100:35;;;;-1:-1:-1;;26184:42:13;26172:55;;;;26166:3;26151:19;;26144:84;26259:3;26244:19;;;26237:35;26039:52;25095:1183;-1:-1:-1;;;;;25095:1183:13:o;26283:184::-;26335:77;26332:1;26325:88;26432:4;26429:1;26422:15;26456:4;26453:1;26446:15;27250:604;27343:4;27349:6;27409:11;27396:25;27499:66;27488:8;27472:14;27468:29;27464:102;27444:18;27440:127;27430:155;;27581:1;27578;27571:12;27430:155;27608:33;;27660:20;;;-1:-1:-1;27703:18:13;27692:30;;27689:50;;;27735:1;27732;27725:12;27689:50;27768:4;27756:17;;-1:-1:-1;27819:1:13;27815:14;;;27799;27795:35;27785:46;;27782:66;;;27844:1;27841;27834:12;28961:202;29069:9;29106:51;29142:14;29135:5;29106:51;:::i;29168:472::-;29268:6;29263:3;29256:19;29238:3;29294:4;29323;29318:3;29314:14;29307:21;;29351:5;29374:1;29384:231;29398:6;29395:1;29392:13;29384:231;;;29491:42;29463:26;29482:6;29463:26;:::i;:::-;29459:75;29447:88;;29555:12;;;;29590:15;;;;29420:1;29413:9;29384:231;;29645:358;29745:6;29740:3;29733:19;29715:3;29775:66;29767:6;29764:78;29761:98;;;29855:1;29852;29845:12;29761:98;29891:6;29888:1;29884:14;29943:8;29936:5;29929:4;29924:3;29920:14;29907:45;29972:18;;;;29992:4;29968:29;;29645:358;-1:-1:-1;;;29645:358:13:o;30008:784::-;30369:6;30358:9;30351:25;30412:6;30407:2;30396:9;30392:18;30385:34;30467:42;30459:6;30455:55;30450:2;30439:9;30435:18;30428:83;30547:3;30542:2;30531:9;30527:18;30520:31;30332:4;30574:74;30643:3;30632:9;30628:19;30620:6;30612;30574:74;:::i;:::-;30697:9;30689:6;30685:22;30679:3;30668:9;30664:19;30657:51;30725:61;30779:6;30771;30763;30725:61;:::i;:::-;30717:69;30008:784;-1:-1:-1;;;;;;;;;;30008:784:13:o;30797:515::-;31038:2;31027:9;31020:21;31001:4;31064:62;31122:2;31111:9;31107:18;31099:6;31091;31064:62;:::i;:::-;31174:9;31166:6;31162:22;31157:2;31146:9;31142:18;31135:50;31202;31245:6;31237;31229;31202:50;:::i;:::-;31194:58;;;31300:4;31292:6;31288:17;31283:2;31272:9;31268:18;31261:45;30797:515;;;;;;;;:::o;32936:779::-;33263:3;33252:9;33245:22;33226:4;33290:63;33348:3;33337:9;33333:19;33325:6;33317;33290:63;:::i;:::-;33401:9;33393:6;33389:22;33384:2;33373:9;33369:18;33362:50;33435;33478:6;33470;33462;33435:50;:::i;:::-;33421:64;;33533:9;33525:6;33521:22;33516:2;33505:9;33501:18;33494:50;33561;33604:6;33596;33588;33561:50;:::i;:::-;33659:4;33647:17;;;;33642:2;33627:18;;33620:45;-1:-1:-1;;33696:3:13;33681:19;33674:35;33553:58;32936:779;-1:-1:-1;;;;;;32936:779:13:o;34123:195::-;34162:3;34193:66;34186:5;34183:77;34180:103;;34263:18;;:::i;:::-;-1:-1:-1;34310:1:13;34299:13;;34123:195::o;34323:184::-;34375:77;34372:1;34365:88;34472:4;34469:1;34462:15;34496:4;34493:1;34486:15;34512:120;34552:1;34578;34568:35;;34583:18;;:::i;:::-;-1:-1:-1;34617:9:13;;34512:120::o;34637:112::-;34669:1;34695;34685:35;;34700:18;;:::i;:::-;-1:-1:-1;34734:9:13;;34637:112::o;34754:196::-;34793:3;34821:5;34811:39;;34830:18;;:::i;:::-;-1:-1:-1;34877:66:13;34866:78;;34754:196::o;35304:874::-;35701:6;35690:9;35683:25;35744:6;35739:2;35728:9;35724:18;35717:34;35787:6;35782:2;35771:9;35767:18;35760:34;35830:3;35825:2;35814:9;35810:18;35803:31;35664:4;35857:57;35909:3;35898:9;35894:19;35886:6;35857:57;:::i;:::-;35963:9;35955:6;35951:22;35945:3;35934:9;35930:19;35923:51;35991:44;36028:6;36020;35991:44;:::i;:::-;35983:52;;;36072:6;36066:3;36055:9;36051:19;36044:35;36128:42;36120:6;36116:55;36110:3;36099:9;36095:19;36088:84;35304:874;;;;;;;;;;:::o;37016:277::-;37083:6;37136:2;37124:9;37115:7;37111:23;37107:32;37104:52;;;37152:1;37149;37142:12;37104:52;37184:9;37178:16;37237:5;37230:13;37223:21;37216:5;37213:32;37203:60;;37259:1;37256;37249:12;39262:287;39391:3;39429:6;39423:13;39445:66;39504:6;39499:3;39492:4;39484:6;39480:17;39445:66;:::i;:::-;39527:16;;;;;39262:287;-1:-1:-1;;39262:287:13:o;39554:231::-;39703:2;39692:9;39685:21;39666:4;39723:56;39775:2;39764:9;39760:18;39752:6;39723:56;:::i
Swarm Source
ipfs://3fa5d224d9136d6f17ea4c0ea2cb6af7ac5dc757de473d3cc3e5d9fbbadbaa9f
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.