Address Details
contract
0xb76884F7961e3c8bc0b8893F5728794B841DE0A2
- Contract Name
- AccessControlledAggregator
- Creator
- 0x778895–6382ce at 0x2ed05c–56c524
- Balance
- 0 CELO ( )
- Locked CELO Balance
- 0.00 CELO
- Voting CELO Balance
- 0.00 CELO
- Pending Unlocked Gold
- 0.00 CELO
- Tokens
-
Fetching tokens...
- Transactions
- 1,214 Transactions
- Transfers
- 1 Transfers
- Gas Used
- 149,608,179
- Last Balance Update
- 4979090
Transactions
Token Transfers
Tokens
Internal Transactions
Coin Balance History
Logs
Code
Read Contract
Write Contract
This contract has been verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- AccessControlledAggregator
- Optimization enabled
- false
- Compiler version
- v0.6.6+commit.6c089d02
- EVM Version
- istanbul
- Verified at
- 2022-09-30T07:46:39.823232Z
ACA_flat.sol
// File: https://github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/interfaces/AccessControllerInterface.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; interface AccessControllerInterface { function hasAccess(address user, bytes calldata data) external view returns (bool); } // File: https://github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/Owned.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @title The Owned contract * @notice A contract with helpers for basic contract ownership. */ contract Owned { address public owner; address private pendingOwner; event OwnershipTransferRequested( address indexed from, address indexed to ); event OwnershipTransferred( address indexed from, address indexed to ); constructor() public { owner = msg.sender; } /** * @dev Allows an owner to begin transferring ownership to a new address, * pending. */ function transferOwnership(address _to) external onlyOwner() { pendingOwner = _to; emit OwnershipTransferRequested(owner, _to); } /** * @dev Allows an ownership transfer to be completed by the recipient. */ function acceptOwnership() external { require(msg.sender == pendingOwner, "Must be proposed owner"); address oldOwner = owner; owner = msg.sender; pendingOwner = address(0); emit OwnershipTransferred(oldOwner, msg.sender); } /** * @dev Reverts if called by anyone other than the contract owner. */ modifier onlyOwner() { require(msg.sender == owner, "Only callable by owner"); _; } } // File: https://github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/SimpleWriteAccessController.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @title SimpleWriteAccessController * @notice Gives access to accounts explicitly added to an access list by the * controller's owner. * @dev does not make any special permissions for externally, see * SimpleReadAccessController for that. */ contract SimpleWriteAccessController is AccessControllerInterface, Owned { bool public checkEnabled; mapping(address => bool) internal accessList; event AddedAccess(address user); event RemovedAccess(address user); event CheckAccessEnabled(); event CheckAccessDisabled(); constructor() public { checkEnabled = true; } /** * @notice Returns the access of an address * @param _user The address to query */ function hasAccess( address _user, bytes memory ) public view virtual override returns (bool) { return accessList[_user] || !checkEnabled; } /** * @notice Adds an address to the access list * @param _user The address to add */ function addAccess(address _user) external onlyOwner() { if (!accessList[_user]) { accessList[_user] = true; emit AddedAccess(_user); } } /** * @notice Removes an address from the access list * @param _user The address to remove */ function removeAccess(address _user) external onlyOwner() { if (accessList[_user]) { accessList[_user] = false; emit RemovedAccess(_user); } } /** * @notice makes the access check enforced */ function enableAccessCheck() external onlyOwner() { if (!checkEnabled) { checkEnabled = true; emit CheckAccessEnabled(); } } /** * @notice makes the access check unenforced */ function disableAccessCheck() external onlyOwner() { if (checkEnabled) { checkEnabled = false; emit CheckAccessDisabled(); } } /** * @dev reverts if the caller does not have access */ modifier checkAccess() { require(hasAccess(msg.sender, msg.data), "No access"); _; } } // File: https://github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/SimpleReadAccessController.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @title SimpleReadAccessController * @notice Gives access to: * - any externally owned account (note that offchain actors can always read * any contract storage regardless of onchain access control measures, so this * does not weaken the access control while improving usability) * - accounts explicitly added to an access list * @dev SimpleReadAccessController is not suitable for access controlling writes * since it grants any externally owned account access! See * SimpleWriteAccessController for that. */ contract SimpleReadAccessController is SimpleWriteAccessController { /** * @notice Returns the access of an address * @param _user The address to query */ function hasAccess( address _user, bytes memory _calldata ) public view virtual override returns (bool) { return super.hasAccess(_user, _calldata) || _user == tx.origin; } } // File: https://github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/interfaces/LinkTokenInterface.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; interface LinkTokenInterface { function allowance(address owner, address spender) external view returns (uint256 remaining); function approve(address spender, uint256 value) external returns (bool success); function balanceOf(address owner) external view returns (uint256 balance); function decimals() external view returns (uint8 decimalPlaces); function decreaseApproval(address spender, uint256 addedValue) external returns (bool success); function increaseApproval(address spender, uint256 subtractedValue) external; function name() external view returns (string memory tokenName); function symbol() external view returns (string memory tokenSymbol); function totalSupply() external view returns (uint256 totalTokensIssued); function transfer(address to, uint256 value) external returns (bool success); function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool success); function transferFrom(address from, address to, uint256 value) external returns (bool success); } // File: https://github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/interfaces/AggregatorValidatorInterface.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; interface AggregatorValidatorInterface { function validate( uint256 previousRoundId, int256 previousAnswer, uint256 currentRoundId, int256 currentAnswer ) external returns (bool); } // File: https://github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/interfaces/AggregatorV3Interface.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.0; interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); // getRoundData and latestRoundData should both raise "No data present" // if they do not have data to report, instead of returning unset values // which could be misinterpreted as actual reported values. function getRoundData(uint80 _roundId) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); } // File: https://github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/interfaces/AggregatorInterface.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.0; interface AggregatorInterface { function latestAnswer() external view returns (int256); function latestTimestamp() external view returns (uint256); function latestRound() external view returns (uint256); function getAnswer(uint256 roundId) external view returns (int256); function getTimestamp(uint256 roundId) external view returns (uint256); event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt); event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt); } // File: https://github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/interfaces/AggregatorV2V3Interface.sol // SPDX-License-Identifier: MIT pragma solidity >=0.6.0; interface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface { } // File: https://github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/SafeMath64.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * This library is a version of Open Zeppelin's SafeMath, modified to support * unsigned 64 bit integers. */ library SafeMath64 { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint64 a, uint64 b) internal pure returns (uint64) { uint64 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint64 a, uint64 b) internal pure returns (uint64) { require(b <= a, "SafeMath: subtraction overflow"); uint64 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint64 a, uint64 b) internal pure returns (uint64) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint64 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint64 a, uint64 b) internal pure returns (uint64) { // Solidity only automatically asserts when dividing by 0 require(b > 0, "SafeMath: division by zero"); uint64 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint64 a, uint64 b) internal pure returns (uint64) { require(b != 0, "SafeMath: modulo by zero"); return a % b; } } // File: https://github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/SafeMath32.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * This library is a version of Open Zeppelin's SafeMath, modified to support * unsigned 32 bit integers. */ library SafeMath32 { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint32 a, uint32 b) internal pure returns (uint32) { uint32 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint32 a, uint32 b) internal pure returns (uint32) { require(b <= a, "SafeMath: subtraction overflow"); uint32 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint32 a, uint32 b) internal pure returns (uint32) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint32 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint32 a, uint32 b) internal pure returns (uint32) { // Solidity only automatically asserts when dividing by 0 require(b > 0, "SafeMath: division by zero"); uint32 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint32 a, uint32 b) internal pure returns (uint32) { require(b != 0, "SafeMath: modulo by zero"); return a % b; } } // File: https://github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/SafeMath128.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * This library is a version of Open Zeppelin's SafeMath, modified to support * unsigned 128 bit integers. */ library SafeMath128 { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint128 a, uint128 b) internal pure returns (uint128) { uint128 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint128 a, uint128 b) internal pure returns (uint128) { require(b <= a, "SafeMath: subtraction overflow"); uint128 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint128 a, uint128 b) internal pure returns (uint128) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint128 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint128 a, uint128 b) internal pure returns (uint128) { // Solidity only automatically asserts when dividing by 0 require(b > 0, "SafeMath: division by zero"); uint128 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint128 a, uint128 b) internal pure returns (uint128) { require(b != 0, "SafeMath: modulo by zero"); return a % b; } } // File: https://github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/SignedSafeMath.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; library SignedSafeMath { int256 constant private _INT256_MIN = -2**255; /** * @dev Multiplies two signed integers, reverts on overflow. */ function mul(int256 a, int256 b) internal pure returns (int256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } require(!(a == -1 && b == _INT256_MIN), "SignedSafeMath: multiplication overflow"); int256 c = a * b; require(c / a == b, "SignedSafeMath: multiplication overflow"); return c; } /** * @dev Integer division of two signed integers truncating the quotient, reverts on division by zero. */ function div(int256 a, int256 b) internal pure returns (int256) { require(b != 0, "SignedSafeMath: division by zero"); require(!(b == -1 && a == _INT256_MIN), "SignedSafeMath: division overflow"); int256 c = a / b; return c; } /** * @dev Subtracts two signed integers, reverts on overflow. */ function sub(int256 a, int256 b) internal pure returns (int256) { int256 c = a - b; require((b >= 0 && c <= a) || (b < 0 && c > a), "SignedSafeMath: subtraction overflow"); return c; } /** * @dev Adds two signed integers, reverts on overflow. */ function add(int256 a, int256 b) internal pure returns (int256) { int256 c = a + b; require((b >= 0 && c >= a) || (b < 0 && c < a), "SignedSafeMath: addition overflow"); return c; } /** * @notice Computes average of two signed integers, ensuring that the computation * doesn't overflow. * @dev If the result is not an integer, it is rounded towards zero. For example, * avg(-3, -4) = -3 */ function avg(int256 _a, int256 _b) internal pure returns (int256) { if ((_a < 0 && _b > 0) || (_a > 0 && _b < 0)) { return add(_a, _b) / 2; } int256 remainder = (_a % 2 + _b % 2) / 2; return add(add(_a / 2, _b / 2), remainder); } } // File: https://github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/vendor/SafeMathChainlink.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMathChainlink { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, "SafeMath: division by zero"); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0, "SafeMath: modulo by zero"); return a % b; } } // File: https://github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/Median.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; library Median { using SignedSafeMath for int256; int256 constant INT_MAX = 2**255-1; /** * @notice Returns the sorted middle, or the average of the two middle indexed items if the * array has an even number of elements. * @dev The list passed as an argument isn't modified. * @dev This algorithm has expected runtime O(n), but for adversarially chosen inputs * the runtime is O(n^2). * @param list The list of elements to compare */ function calculate(int256[] memory list) internal pure returns (int256) { return calculateInplace(copy(list)); } /** * @notice See documentation for function calculate. * @dev The list passed as an argument may be permuted. */ function calculateInplace(int256[] memory list) internal pure returns (int256) { require(0 < list.length, "list must not be empty"); uint256 len = list.length; uint256 middleIndex = len / 2; if (len % 2 == 0) { int256 median1; int256 median2; (median1, median2) = quickselectTwo(list, 0, len - 1, middleIndex - 1, middleIndex); return SignedSafeMath.avg(median1, median2); } else { return quickselect(list, 0, len - 1, middleIndex); } } /** * @notice Maximum length of list that shortSelectTwo can handle */ uint256 constant SHORTSELECTTWO_MAX_LENGTH = 7; /** * @notice Select the k1-th and k2-th element from list of length at most 7 * @dev Uses an optimal sorting network */ function shortSelectTwo( int256[] memory list, uint256 lo, uint256 hi, uint256 k1, uint256 k2 ) private pure returns (int256 k1th, int256 k2th) { // Uses an optimal sorting network (https://en.wikipedia.org/wiki/Sorting_network) // for lists of length 7. Network layout is taken from // http://jgamble.ripco.net/cgi-bin/nw.cgi?inputs=7&algorithm=hibbard&output=svg uint256 len = hi + 1 - lo; int256 x0 = list[lo + 0]; int256 x1 = 1 < len ? list[lo + 1] : INT_MAX; int256 x2 = 2 < len ? list[lo + 2] : INT_MAX; int256 x3 = 3 < len ? list[lo + 3] : INT_MAX; int256 x4 = 4 < len ? list[lo + 4] : INT_MAX; int256 x5 = 5 < len ? list[lo + 5] : INT_MAX; int256 x6 = 6 < len ? list[lo + 6] : INT_MAX; if (x0 > x1) {(x0, x1) = (x1, x0);} if (x2 > x3) {(x2, x3) = (x3, x2);} if (x4 > x5) {(x4, x5) = (x5, x4);} if (x0 > x2) {(x0, x2) = (x2, x0);} if (x1 > x3) {(x1, x3) = (x3, x1);} if (x4 > x6) {(x4, x6) = (x6, x4);} if (x1 > x2) {(x1, x2) = (x2, x1);} if (x5 > x6) {(x5, x6) = (x6, x5);} if (x0 > x4) {(x0, x4) = (x4, x0);} if (x1 > x5) {(x1, x5) = (x5, x1);} if (x2 > x6) {(x2, x6) = (x6, x2);} if (x1 > x4) {(x1, x4) = (x4, x1);} if (x3 > x6) {(x3, x6) = (x6, x3);} if (x2 > x4) {(x2, x4) = (x4, x2);} if (x3 > x5) {(x3, x5) = (x5, x3);} if (x3 > x4) {(x3, x4) = (x4, x3);} uint256 index1 = k1 - lo; if (index1 == 0) {k1th = x0;} else if (index1 == 1) {k1th = x1;} else if (index1 == 2) {k1th = x2;} else if (index1 == 3) {k1th = x3;} else if (index1 == 4) {k1th = x4;} else if (index1 == 5) {k1th = x5;} else if (index1 == 6) {k1th = x6;} else {revert("k1 out of bounds");} uint256 index2 = k2 - lo; if (k1 == k2) {return (k1th, k1th);} else if (index2 == 0) {return (k1th, x0);} else if (index2 == 1) {return (k1th, x1);} else if (index2 == 2) {return (k1th, x2);} else if (index2 == 3) {return (k1th, x3);} else if (index2 == 4) {return (k1th, x4);} else if (index2 == 5) {return (k1th, x5);} else if (index2 == 6) {return (k1th, x6);} else {revert("k2 out of bounds");} } /** * @notice Selects the k-th ranked element from list, looking only at indices between lo and hi * (inclusive). Modifies list in-place. */ function quickselect(int256[] memory list, uint256 lo, uint256 hi, uint256 k) private pure returns (int256 kth) { require(lo <= k); require(k <= hi); while (lo < hi) { if (hi - lo < SHORTSELECTTWO_MAX_LENGTH) { int256 ignore; (kth, ignore) = shortSelectTwo(list, lo, hi, k, k); return kth; } uint256 pivotIndex = partition(list, lo, hi); if (k <= pivotIndex) { // since pivotIndex < (original hi passed to partition), // termination is guaranteed in this case hi = pivotIndex; } else { // since (original lo passed to partition) <= pivotIndex, // termination is guaranteed in this case lo = pivotIndex + 1; } } return list[lo]; } /** * @notice Selects the k1-th and k2-th ranked elements from list, looking only at indices between * lo and hi (inclusive). Modifies list in-place. */ function quickselectTwo( int256[] memory list, uint256 lo, uint256 hi, uint256 k1, uint256 k2 ) internal // for testing pure returns (int256 k1th, int256 k2th) { require(k1 < k2); require(lo <= k1 && k1 <= hi); require(lo <= k2 && k2 <= hi); while (true) { if (hi - lo < SHORTSELECTTWO_MAX_LENGTH) { return shortSelectTwo(list, lo, hi, k1, k2); } uint256 pivotIdx = partition(list, lo, hi); if (k2 <= pivotIdx) { hi = pivotIdx; } else if (pivotIdx < k1) { lo = pivotIdx + 1; } else { assert(k1 <= pivotIdx && pivotIdx < k2); k1th = quickselect(list, lo, pivotIdx, k1); k2th = quickselect(list, pivotIdx + 1, hi, k2); return (k1th, k2th); } } } /** * @notice Partitions list in-place using Hoare's partitioning scheme. * Only elements of list between indices lo and hi (inclusive) will be modified. * Returns an index i, such that: * - lo <= i < hi * - forall j in [lo, i]. list[j] <= list[i] * - forall j in [i, hi]. list[i] <= list[j] */ function partition(int256[] memory list, uint256 lo, uint256 hi) private pure returns (uint256) { // We don't care about overflow of the addition, because it would require a list // larger than any feasible computer's memory. int256 pivot = list[(lo + hi) / 2]; lo -= 1; // this can underflow. that's intentional. hi += 1; while (true) { do { lo += 1; } while (list[lo] < pivot); do { hi -= 1; } while (list[hi] > pivot); if (lo < hi) { (list[lo], list[hi]) = (list[hi], list[lo]); } else { // Let orig_lo and orig_hi be the original values of lo and hi passed to partition. // Then, hi < orig_hi, because hi decreases *strictly* monotonically // in each loop iteration and // - either list[orig_hi] > pivot, in which case the first loop iteration // will achieve hi < orig_hi; // - or list[orig_hi] <= pivot, in which case at least two loop iterations are // needed: // - lo will have to stop at least once in the interval // [orig_lo, (orig_lo + orig_hi)/2] // - (orig_lo + orig_hi)/2 < orig_hi return hi; } } } /** * @notice Makes an in-memory copy of the array passed in * @param list Reference to the array to be copied */ function copy(int256[] memory list) private pure returns(int256[] memory) { int256[] memory list2 = new int256[](list.length); for (uint256 i = 0; i < list.length; i++) { list2[i] = list[i]; } return list2; } } // File: https://github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/FluxAggregator.sol // SPDX-License-Identifier: MIT pragma solidity 0.6.6; /** * @title The Prepaid Aggregator contract * @notice Handles aggregating data pushed in from off-chain, and unlocks * payment for oracles as they report. Oracles' submissions are gathered in * rounds, with each round aggregating the submissions for each oracle into a * single answer. The latest aggregated answer is exposed as well as historical * answers and their updated at timestamp. */ contract FluxAggregator is AggregatorV2V3Interface, Owned { using SafeMathChainlink for uint256; using SafeMath128 for uint128; using SafeMath64 for uint64; using SafeMath32 for uint32; struct Round { int256 answer; uint64 startedAt; uint64 updatedAt; uint32 answeredInRound; } struct RoundDetails { int256[] submissions; uint32 maxSubmissions; uint32 minSubmissions; uint32 timeout; uint128 paymentAmount; } struct OracleStatus { uint128 withdrawable; uint32 startingRound; uint32 endingRound; uint32 lastReportedRound; uint32 lastStartedRound; int256 latestSubmission; uint16 index; address admin; address pendingAdmin; } struct Requester { bool authorized; uint32 delay; uint32 lastStartedRound; } struct Funds { uint128 available; uint128 allocated; } LinkTokenInterface public linkToken; AggregatorValidatorInterface public validator; // Round related params uint128 public paymentAmount; uint32 public maxSubmissionCount; uint32 public minSubmissionCount; uint32 public restartDelay; uint32 public timeout; uint8 public override decimals; string public override description; int256 immutable public minSubmissionValue; int256 immutable public maxSubmissionValue; uint256 constant public override version = 3; /** * @notice To ensure owner isn't withdrawing required funds as oracles are * submitting updates, we enforce that the contract maintains a minimum * reserve of RESERVE_ROUNDS * oracleCount() LINK earmarked for payment to * oracles. (Of course, this doesn't prevent the contract from running out of * funds without the owner's intervention.) */ uint256 constant private RESERVE_ROUNDS = 2; uint256 constant private MAX_ORACLE_COUNT = 77; uint32 constant private ROUND_MAX = 2**32-1; uint256 private constant VALIDATOR_GAS_LIMIT = 100000; // An error specific to the Aggregator V3 Interface, to prevent possible // confusion around accidentally reading unset values as reported values. string constant private V3_NO_DATA_ERROR = "No data present"; uint32 private reportingRoundId; uint32 internal latestRoundId; mapping(address => OracleStatus) private oracles; mapping(uint32 => Round) internal rounds; mapping(uint32 => RoundDetails) internal details; mapping(address => Requester) internal requesters; address[] private oracleAddresses; Funds private recordedFunds; event AvailableFundsUpdated( uint256 indexed amount ); event RoundDetailsUpdated( uint128 indexed paymentAmount, uint32 indexed minSubmissionCount, uint32 indexed maxSubmissionCount, uint32 restartDelay, uint32 timeout // measured in seconds ); event OraclePermissionsUpdated( address indexed oracle, bool indexed whitelisted ); event OracleAdminUpdated( address indexed oracle, address indexed newAdmin ); event OracleAdminUpdateRequested( address indexed oracle, address admin, address newAdmin ); event SubmissionReceived( int256 indexed submission, uint32 indexed round, address indexed oracle ); event RequesterPermissionsSet( address indexed requester, bool authorized, uint32 delay ); event ValidatorUpdated( address indexed previous, address indexed current ); /** * @notice set up the aggregator with initial configuration * @param _link The address of the LINK token * @param _paymentAmount The amount paid of LINK paid to each oracle per submission, in wei (units of 10⁻¹⁸ LINK) * @param _timeout is the number of seconds after the previous round that are * allowed to lapse before allowing an oracle to skip an unfinished round * @param _validator is an optional contract address for validating * external validation of answers * @param _minSubmissionValue is an immutable check for a lower bound of what * submission values are accepted from an oracle * @param _maxSubmissionValue is an immutable check for an upper bound of what * submission values are accepted from an oracle * @param _decimals represents the number of decimals to offset the answer by * @param _description a short description of what is being reported */ constructor( address _link, uint128 _paymentAmount, uint32 _timeout, address _validator, int256 _minSubmissionValue, int256 _maxSubmissionValue, uint8 _decimals, string memory _description ) public { linkToken = LinkTokenInterface(_link); updateFutureRounds(_paymentAmount, 0, 0, 0, _timeout); setValidator(_validator); minSubmissionValue = _minSubmissionValue; maxSubmissionValue = _maxSubmissionValue; decimals = _decimals; description = _description; rounds[0].updatedAt = uint64(block.timestamp.sub(uint256(_timeout))); } /** * @notice called by oracles when they have witnessed a need to update * @param _roundId is the ID of the round this submission pertains to * @param _submission is the updated data that the oracle is submitting */ function submit(uint256 _roundId, int256 _submission) external { bytes memory error = validateOracleRound(msg.sender, uint32(_roundId)); require(_submission >= minSubmissionValue, "value below minSubmissionValue"); require(_submission <= maxSubmissionValue, "value above maxSubmissionValue"); require(error.length == 0, string(error)); oracleInitializeNewRound(uint32(_roundId)); recordSubmission(_submission, uint32(_roundId)); (bool updated, int256 newAnswer) = updateRoundAnswer(uint32(_roundId)); payOracle(uint32(_roundId)); deleteRoundDetails(uint32(_roundId)); if (updated) { validateAnswer(uint32(_roundId), newAnswer); } } /** * @notice called by the owner to remove and add new oracles as well as * update the round related parameters that pertain to total oracle count * @param _removed is the list of addresses for the new Oracles being removed * @param _added is the list of addresses for the new Oracles being added * @param _addedAdmins is the admin addresses for the new respective _added * list. Only this address is allowed to access the respective oracle's funds * @param _minSubmissions is the new minimum submission count for each round * @param _maxSubmissions is the new maximum submission count for each round * @param _restartDelay is the number of rounds an Oracle has to wait before * they can initiate a round */ function changeOracles( address[] calldata _removed, address[] calldata _added, address[] calldata _addedAdmins, uint32 _minSubmissions, uint32 _maxSubmissions, uint32 _restartDelay ) external onlyOwner() { for (uint256 i = 0; i < _removed.length; i++) { removeOracle(_removed[i]); } require(_added.length == _addedAdmins.length, "need same oracle and admin count"); require(uint256(oracleCount()).add(_added.length) <= MAX_ORACLE_COUNT, "max oracles allowed"); for (uint256 i = 0; i < _added.length; i++) { addOracle(_added[i], _addedAdmins[i]); } updateFutureRounds(paymentAmount, _minSubmissions, _maxSubmissions, _restartDelay, timeout); } /** * @notice update the round and payment related parameters for subsequent * rounds * @param _paymentAmount is the payment amount for subsequent rounds * @param _minSubmissions is the new minimum submission count for each round * @param _maxSubmissions is the new maximum submission count for each round * @param _restartDelay is the number of rounds an Oracle has to wait before * they can initiate a round */ function updateFutureRounds( uint128 _paymentAmount, uint32 _minSubmissions, uint32 _maxSubmissions, uint32 _restartDelay, uint32 _timeout ) public onlyOwner() { uint32 oracleNum = oracleCount(); // Save on storage reads require(_maxSubmissions >= _minSubmissions, "max must equal/exceed min"); require(oracleNum >= _maxSubmissions, "max cannot exceed total"); require(oracleNum == 0 || oracleNum > _restartDelay, "delay cannot exceed total"); require(recordedFunds.available >= requiredReserve(_paymentAmount), "insufficient funds for payment"); if (oracleCount() > 0) { require(_minSubmissions > 0, "min must be greater than 0"); } paymentAmount = _paymentAmount; minSubmissionCount = _minSubmissions; maxSubmissionCount = _maxSubmissions; restartDelay = _restartDelay; timeout = _timeout; emit RoundDetailsUpdated( paymentAmount, _minSubmissions, _maxSubmissions, _restartDelay, _timeout ); } /** * @notice the amount of payment yet to be withdrawn by oracles */ function allocatedFunds() external view returns (uint128) { return recordedFunds.allocated; } /** * @notice the amount of future funding available to oracles */ function availableFunds() external view returns (uint128) { return recordedFunds.available; } /** * @notice recalculate the amount of LINK available for payouts */ function updateAvailableFunds() public { Funds memory funds = recordedFunds; uint256 nowAvailable = linkToken.balanceOf(address(this)).sub(funds.allocated); if (funds.available != nowAvailable) { recordedFunds.available = uint128(nowAvailable); emit AvailableFundsUpdated(nowAvailable); } } /** * @notice returns the number of oracles */ function oracleCount() public view returns (uint8) { return uint8(oracleAddresses.length); } /** * @notice returns an array of addresses containing the oracles on contract */ function getOracles() external view returns (address[] memory) { return oracleAddresses; } /** * @notice get the most recently reported answer * * @dev #[deprecated] Use latestRoundData instead. This does not error if no * answer has been reached, it will simply return 0. Either wait to point to * an already answered Aggregator or use the recommended latestRoundData * instead which includes better verification information. */ function latestAnswer() public view virtual override returns (int256) { return rounds[latestRoundId].answer; } /** * @notice get the most recent updated at timestamp * * @dev #[deprecated] Use latestRoundData instead. This does not error if no * answer has been reached, it will simply return 0. Either wait to point to * an already answered Aggregator or use the recommended latestRoundData * instead which includes better verification information. */ function latestTimestamp() public view virtual override returns (uint256) { return rounds[latestRoundId].updatedAt; } /** * @notice get the ID of the last updated round * * @dev #[deprecated] Use latestRoundData instead. This does not error if no * answer has been reached, it will simply return 0. Either wait to point to * an already answered Aggregator or use the recommended latestRoundData * instead which includes better verification information. */ function latestRound() public view virtual override returns (uint256) { return latestRoundId; } /** * @notice get past rounds answers * @param _roundId the round number to retrieve the answer for * * @dev #[deprecated] Use getRoundData instead. This does not error if no * answer has been reached, it will simply return 0. Either wait to point to * an already answered Aggregator or use the recommended getRoundData * instead which includes better verification information. */ function getAnswer(uint256 _roundId) public view virtual override returns (int256) { if (validRoundId(_roundId)) { return rounds[uint32(_roundId)].answer; } return 0; } /** * @notice get timestamp when an answer was last updated * @param _roundId the round number to retrieve the updated timestamp for * * @dev #[deprecated] Use getRoundData instead. This does not error if no * answer has been reached, it will simply return 0. Either wait to point to * an already answered Aggregator or use the recommended getRoundData * instead which includes better verification information. */ function getTimestamp(uint256 _roundId) public view virtual override returns (uint256) { if (validRoundId(_roundId)) { return rounds[uint32(_roundId)].updatedAt; } return 0; } /** * @notice get data about a round. Consumers are encouraged to check * that they're receiving fresh data by inspecting the updatedAt and * answeredInRound return values. * @param _roundId the round ID to retrieve the round data for * @return roundId is the round ID for which data was retrieved * @return answer is the answer for the given round * @return startedAt is the timestamp when the round was started. This is 0 * if the round hasn't been started yet. * @return updatedAt is the timestamp when the round last was updated (i.e. * answer was last computed) * @return answeredInRound is the round ID of the round in which the answer * was computed. answeredInRound may be smaller than roundId when the round * timed out. answeredInRound is equal to roundId when the round didn't time out * and was completed regularly. * @dev Note that for in-progress rounds (i.e. rounds that haven't yet received * maxSubmissions) answer and updatedAt may change between queries. */ function getRoundData(uint80 _roundId) public view virtual override returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ) { Round memory r = rounds[uint32(_roundId)]; require(r.answeredInRound > 0 && validRoundId(_roundId), V3_NO_DATA_ERROR); return ( _roundId, r.answer, r.startedAt, r.updatedAt, r.answeredInRound ); } /** * @notice get data about the latest round. Consumers are encouraged to check * that they're receiving fresh data by inspecting the updatedAt and * answeredInRound return values. Consumers are encouraged to * use this more fully featured method over the "legacy" latestRound/ * latestAnswer/latestTimestamp functions. Consumers are encouraged to check * that they're receiving fresh data by inspecting the updatedAt and * answeredInRound return values. * @return roundId is the round ID for which data was retrieved * @return answer is the answer for the given round * @return startedAt is the timestamp when the round was started. This is 0 * if the round hasn't been started yet. * @return updatedAt is the timestamp when the round last was updated (i.e. * answer was last computed) * @return answeredInRound is the round ID of the round in which the answer * was computed. answeredInRound may be smaller than roundId when the round * timed out. answeredInRound is equal to roundId when the round didn't time * out and was completed regularly. * @dev Note that for in-progress rounds (i.e. rounds that haven't yet * received maxSubmissions) answer and updatedAt may change between queries. */ function latestRoundData() public view virtual override returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ) { return getRoundData(latestRoundId); } /** * @notice query the available amount of LINK for an oracle to withdraw */ function withdrawablePayment(address _oracle) external view returns (uint256) { return oracles[_oracle].withdrawable; } /** * @notice transfers the oracle's LINK to another address. Can only be called * by the oracle's admin. * @param _oracle is the oracle whose LINK is transferred * @param _recipient is the address to send the LINK to * @param _amount is the amount of LINK to send */ function withdrawPayment(address _oracle, address _recipient, uint256 _amount) external { require(oracles[_oracle].admin == msg.sender, "only callable by admin"); // Safe to downcast _amount because the total amount of LINK is less than 2^128. uint128 amount = uint128(_amount); uint128 available = oracles[_oracle].withdrawable; require(available >= amount, "insufficient withdrawable funds"); oracles[_oracle].withdrawable = available.sub(amount); recordedFunds.allocated = recordedFunds.allocated.sub(amount); assert(linkToken.transfer(_recipient, uint256(amount))); } /** * @notice transfers the owner's LINK to another address * @param _recipient is the address to send the LINK to * @param _amount is the amount of LINK to send */ function withdrawFunds(address _recipient, uint256 _amount) external onlyOwner() { uint256 available = uint256(recordedFunds.available); require(available.sub(requiredReserve(paymentAmount)) >= _amount, "insufficient reserve funds"); require(linkToken.transfer(_recipient, _amount), "token transfer failed"); updateAvailableFunds(); } /** * @notice get the admin address of an oracle * @param _oracle is the address of the oracle whose admin is being queried */ function getAdmin(address _oracle) external view returns (address) { return oracles[_oracle].admin; } /** * @notice transfer the admin address for an oracle * @param _oracle is the address of the oracle whose admin is being transferred * @param _newAdmin is the new admin address */ function transferAdmin(address _oracle, address _newAdmin) external { require(oracles[_oracle].admin == msg.sender, "only callable by admin"); oracles[_oracle].pendingAdmin = _newAdmin; emit OracleAdminUpdateRequested(_oracle, msg.sender, _newAdmin); } /** * @notice accept the admin address transfer for an oracle * @param _oracle is the address of the oracle whose admin is being transferred */ function acceptAdmin(address _oracle) external { require(oracles[_oracle].pendingAdmin == msg.sender, "only callable by pending admin"); oracles[_oracle].pendingAdmin = address(0); oracles[_oracle].admin = msg.sender; emit OracleAdminUpdated(_oracle, msg.sender); } /** * @notice allows non-oracles to request a new round */ function requestNewRound() external returns (uint80) { require(requesters[msg.sender].authorized, "not authorized requester"); uint32 current = reportingRoundId; require(rounds[current].updatedAt > 0 || timedOut(current), "prev round must be supersedable"); uint32 newRoundId = current.add(1); requesterInitializeNewRound(newRoundId); return newRoundId; } /** * @notice allows the owner to specify new non-oracles to start new rounds * @param _requester is the address to set permissions for * @param _authorized is a boolean specifying whether they can start new rounds or not * @param _delay is the number of rounds the requester must wait before starting another round */ function setRequesterPermissions(address _requester, bool _authorized, uint32 _delay) external onlyOwner() { if (requesters[_requester].authorized == _authorized) return; if (_authorized) { requesters[_requester].authorized = _authorized; requesters[_requester].delay = _delay; } else { delete requesters[_requester]; } emit RequesterPermissionsSet(_requester, _authorized, _delay); } /** * @notice called through LINK's transferAndCall to update available funds * in the same transaction as the funds were transferred to the aggregator * @param _data is mostly ignored. It is checked for length, to be sure * nothing strange is passed in. */ function onTokenTransfer(address, uint256, bytes calldata _data) external { require(_data.length == 0, "transfer doesn't accept calldata"); updateAvailableFunds(); } /** * @notice a method to provide all current info oracles need. Intended only * only to be callable by oracles. Not for use by contracts to read state. * @param _oracle the address to look up information for. */ function oracleRoundState(address _oracle, uint32 _queriedRoundId) external view returns ( bool _eligibleToSubmit, uint32 _roundId, int256 _latestSubmission, uint64 _startedAt, uint64 _timeout, uint128 _availableFunds, uint8 _oracleCount, uint128 _paymentAmount ) { require(msg.sender == tx.origin, "off-chain reading only"); if (_queriedRoundId > 0) { Round storage round = rounds[_queriedRoundId]; RoundDetails storage details = details[_queriedRoundId]; return ( eligibleForSpecificRound(_oracle, _queriedRoundId), _queriedRoundId, oracles[_oracle].latestSubmission, round.startedAt, details.timeout, recordedFunds.available, oracleCount(), (round.startedAt > 0 ? details.paymentAmount : paymentAmount) ); } else { return oracleRoundStateSuggestRound(_oracle); } } /** * @notice method to update the address which does external data validation. * @param _newValidator designates the address of the new validation contract. */ function setValidator(address _newValidator) public onlyOwner() { address previous = address(validator); if (previous != _newValidator) { validator = AggregatorValidatorInterface(_newValidator); emit ValidatorUpdated(previous, _newValidator); } } /** * Private */ function initializeNewRound(uint32 _roundId) private { updateTimedOutRoundInfo(_roundId.sub(1)); reportingRoundId = _roundId; RoundDetails memory nextDetails = RoundDetails( new int256[](0), maxSubmissionCount, minSubmissionCount, timeout, paymentAmount ); details[_roundId] = nextDetails; rounds[_roundId].startedAt = uint64(block.timestamp); emit NewRound(_roundId, msg.sender, rounds[_roundId].startedAt); } function oracleInitializeNewRound(uint32 _roundId) private { if (!newRound(_roundId)) return; uint256 lastStarted = oracles[msg.sender].lastStartedRound; // cache storage reads if (_roundId <= lastStarted + restartDelay && lastStarted != 0) return; initializeNewRound(_roundId); oracles[msg.sender].lastStartedRound = _roundId; } function requesterInitializeNewRound(uint32 _roundId) private { if (!newRound(_roundId)) return; uint256 lastStarted = requesters[msg.sender].lastStartedRound; // cache storage reads require(_roundId > lastStarted + requesters[msg.sender].delay || lastStarted == 0, "must delay requests"); initializeNewRound(_roundId); requesters[msg.sender].lastStartedRound = _roundId; } function updateTimedOutRoundInfo(uint32 _roundId) private { if (!timedOut(_roundId)) return; uint32 prevId = _roundId.sub(1); rounds[_roundId].answer = rounds[prevId].answer; rounds[_roundId].answeredInRound = rounds[prevId].answeredInRound; rounds[_roundId].updatedAt = uint64(block.timestamp); delete details[_roundId]; } function eligibleForSpecificRound(address _oracle, uint32 _queriedRoundId) private view returns (bool _eligible) { if (rounds[_queriedRoundId].startedAt > 0) { return acceptingSubmissions(_queriedRoundId) && validateOracleRound(_oracle, _queriedRoundId).length == 0; } else { return delayed(_oracle, _queriedRoundId) && validateOracleRound(_oracle, _queriedRoundId).length == 0; } } function oracleRoundStateSuggestRound(address _oracle) private view returns ( bool _eligibleToSubmit, uint32 _roundId, int256 _latestSubmission, uint64 _startedAt, uint64 _timeout, uint128 _availableFunds, uint8 _oracleCount, uint128 _paymentAmount ) { Round storage round = rounds[0]; OracleStatus storage oracle = oracles[_oracle]; bool shouldSupersede = oracle.lastReportedRound == reportingRoundId || !acceptingSubmissions(reportingRoundId); // Instead of nudging oracles to submit to the next round, the inclusion of // the shouldSupersede bool in the if condition pushes them towards // submitting in a currently open round. if (supersedable(reportingRoundId) && shouldSupersede) { _roundId = reportingRoundId.add(1); round = rounds[_roundId]; _paymentAmount = paymentAmount; _eligibleToSubmit = delayed(_oracle, _roundId); } else { _roundId = reportingRoundId; round = rounds[_roundId]; _paymentAmount = details[_roundId].paymentAmount; _eligibleToSubmit = acceptingSubmissions(_roundId); } if (validateOracleRound(_oracle, _roundId).length != 0) { _eligibleToSubmit = false; } return ( _eligibleToSubmit, _roundId, oracle.latestSubmission, round.startedAt, details[_roundId].timeout, recordedFunds.available, oracleCount(), _paymentAmount ); } function updateRoundAnswer(uint32 _roundId) internal returns (bool, int256) { if (details[_roundId].submissions.length < details[_roundId].minSubmissions) { return (false, 0); } int256 newAnswer = Median.calculateInplace(details[_roundId].submissions); rounds[_roundId].answer = newAnswer; rounds[_roundId].updatedAt = uint64(block.timestamp); rounds[_roundId].answeredInRound = _roundId; latestRoundId = _roundId; emit AnswerUpdated(newAnswer, _roundId, now); return (true, newAnswer); } function validateAnswer( uint32 _roundId, int256 _newAnswer ) private { AggregatorValidatorInterface av = validator; // cache storage reads if (address(av) == address(0)) return; uint32 prevRound = _roundId.sub(1); uint32 prevAnswerRoundId = rounds[prevRound].answeredInRound; int256 prevRoundAnswer = rounds[prevRound].answer; // We do not want the validator to ever prevent reporting, so we limit its // gas usage and catch any errors that may arise. try av.validate{gas: VALIDATOR_GAS_LIMIT}( prevAnswerRoundId, prevRoundAnswer, _roundId, _newAnswer ) {} catch {} } function payOracle(uint32 _roundId) private { uint128 payment = details[_roundId].paymentAmount; Funds memory funds = recordedFunds; funds.available = funds.available.sub(payment); funds.allocated = funds.allocated.add(payment); recordedFunds = funds; oracles[msg.sender].withdrawable = oracles[msg.sender].withdrawable.add(payment); emit AvailableFundsUpdated(funds.available); } function recordSubmission(int256 _submission, uint32 _roundId) private { require(acceptingSubmissions(_roundId), "round not accepting submissions"); details[_roundId].submissions.push(_submission); oracles[msg.sender].lastReportedRound = _roundId; oracles[msg.sender].latestSubmission = _submission; emit SubmissionReceived(_submission, _roundId, msg.sender); } function deleteRoundDetails(uint32 _roundId) private { if (details[_roundId].submissions.length < details[_roundId].maxSubmissions) return; delete details[_roundId]; } function timedOut(uint32 _roundId) private view returns (bool) { uint64 startedAt = rounds[_roundId].startedAt; uint32 roundTimeout = details[_roundId].timeout; return startedAt > 0 && roundTimeout > 0 && startedAt.add(roundTimeout) < block.timestamp; } function getStartingRound(address _oracle) private view returns (uint32) { uint32 currentRound = reportingRoundId; if (currentRound != 0 && currentRound == oracles[_oracle].endingRound) { return currentRound; } return currentRound.add(1); } function previousAndCurrentUnanswered(uint32 _roundId, uint32 _rrId) private view returns (bool) { return _roundId.add(1) == _rrId && rounds[_rrId].updatedAt == 0; } function requiredReserve(uint256 payment) private view returns (uint256) { return payment.mul(oracleCount()).mul(RESERVE_ROUNDS); } function addOracle( address _oracle, address _admin ) private { require(!oracleEnabled(_oracle), "oracle already enabled"); require(_admin != address(0), "cannot set admin to 0"); require(oracles[_oracle].admin == address(0) || oracles[_oracle].admin == _admin, "owner cannot overwrite admin"); oracles[_oracle].startingRound = getStartingRound(_oracle); oracles[_oracle].endingRound = ROUND_MAX; oracles[_oracle].index = uint16(oracleAddresses.length); oracleAddresses.push(_oracle); oracles[_oracle].admin = _admin; emit OraclePermissionsUpdated(_oracle, true); emit OracleAdminUpdated(_oracle, _admin); } function removeOracle( address _oracle ) private { require(oracleEnabled(_oracle), "oracle not enabled"); oracles[_oracle].endingRound = reportingRoundId.add(1); address tail = oracleAddresses[uint256(oracleCount()).sub(1)]; uint16 index = oracles[_oracle].index; oracles[tail].index = index; delete oracles[_oracle].index; oracleAddresses[index] = tail; oracleAddresses.pop(); emit OraclePermissionsUpdated(_oracle, false); } function validateOracleRound(address _oracle, uint32 _roundId) private view returns (bytes memory) { // cache storage reads uint32 startingRound = oracles[_oracle].startingRound; uint32 rrId = reportingRoundId; if (startingRound == 0) return "not enabled oracle"; if (startingRound > _roundId) return "not yet enabled oracle"; if (oracles[_oracle].endingRound < _roundId) return "no longer allowed oracle"; if (oracles[_oracle].lastReportedRound >= _roundId) return "cannot report on previous rounds"; if (_roundId != rrId && _roundId != rrId.add(1) && !previousAndCurrentUnanswered(_roundId, rrId)) return "invalid round to report"; if (_roundId != 1 && !supersedable(_roundId.sub(1))) return "previous round not supersedable"; } function supersedable(uint32 _roundId) private view returns (bool) { return rounds[_roundId].updatedAt > 0 || timedOut(_roundId); } function oracleEnabled(address _oracle) private view returns (bool) { return oracles[_oracle].endingRound == ROUND_MAX; } function acceptingSubmissions(uint32 _roundId) private view returns (bool) { return details[_roundId].maxSubmissions != 0; } function delayed(address _oracle, uint32 _roundId) private view returns (bool) { uint256 lastStarted = oracles[_oracle].lastStartedRound; return _roundId > lastStarted + restartDelay || lastStarted == 0; } function newRound(uint32 _roundId) private view returns (bool) { return _roundId == reportingRoundId.add(1); } function validRoundId(uint256 _roundId) private pure returns (bool) { return _roundId <= ROUND_MAX; } } // File: https://github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/AccessControlledAggregator.sol // SPDX-License-Identifier: MIT pragma solidity 0.6.6; /** * @title AccessControlled FluxAggregator contract * @notice This contract requires addresses to be added to a controller * in order to read the answers stored in the FluxAggregator contract */ contract AccessControlledAggregator is FluxAggregator, SimpleReadAccessController { /** * @notice set up the aggregator with initial configuration * @param _link The address of the LINK token * @param _paymentAmount The amount paid of LINK paid to each oracle per submission, in wei (units of 10⁻¹⁸ LINK) * @param _timeout is the number of seconds after the previous round that are * allowed to lapse before allowing an oracle to skip an unfinished round * @param _validator is an optional contract address for validating * external validation of answers * @param _minSubmissionValue is an immutable check for a lower bound of what * submission values are accepted from an oracle * @param _maxSubmissionValue is an immutable check for an upper bound of what * submission values are accepted from an oracle * @param _decimals represents the number of decimals to offset the answer by * @param _description a short description of what is being reported */ constructor( address _link, uint128 _paymentAmount, uint32 _timeout, address _validator, int256 _minSubmissionValue, int256 _maxSubmissionValue, uint8 _decimals, string memory _description ) public FluxAggregator( _link, _paymentAmount, _timeout, _validator, _minSubmissionValue, _maxSubmissionValue, _decimals, _description ){} /** * @notice get data about a round. Consumers are encouraged to check * that they're receiving fresh data by inspecting the updatedAt and * answeredInRound return values. * @param _roundId the round ID to retrieve the round data for * @return roundId is the round ID for which data was retrieved * @return answer is the answer for the given round * @return startedAt is the timestamp when the round was started. This is 0 * if the round hasn't been started yet. * @return updatedAt is the timestamp when the round last was updated (i.e. * answer was last computed) * @return answeredInRound is the round ID of the round in which the answer * was computed. answeredInRound may be smaller than roundId when the round * timed out. answerInRound is equal to roundId when the round didn't time out * and was completed regularly. * @dev overridden funcion to add the checkAccess() modifier * @dev Note that for in-progress rounds (i.e. rounds that haven't yet * received maxSubmissions) answer and updatedAt may change between queries. */ function getRoundData(uint80 _roundId) public view override checkAccess() returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ) { return super.getRoundData(_roundId); } /** * @notice get data about the latest round. Consumers are encouraged to check * that they're receiving fresh data by inspecting the updatedAt and * answeredInRound return values. Consumers are encouraged to * use this more fully featured method over the "legacy" latestAnswer * functions. Consumers are encouraged to check that they're receiving fresh * data by inspecting the updatedAt and answeredInRound return values. * @return roundId is the round ID for which data was retrieved * @return answer is the answer for the given round * @return startedAt is the timestamp when the round was started. This is 0 * if the round hasn't been started yet. * @return updatedAt is the timestamp when the round last was updated (i.e. * answer was last computed) * @return answeredInRound is the round ID of the round in which the answer * was computed. answeredInRound may be smaller than roundId when the round * timed out. answerInRound is equal to roundId when the round didn't time out * and was completed regularly. * @dev overridden funcion to add the checkAccess() modifier * @dev Note that for in-progress rounds (i.e. rounds that haven't yet * received maxSubmissions) answer and updatedAt may change between queries. */ function latestRoundData() public view override checkAccess() returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ) { return super.latestRoundData(); } /** * @notice get the most recently reported answer * @dev overridden funcion to add the checkAccess() modifier * * @dev #[deprecated] Use latestRoundData instead. This does not error if no * answer has been reached, it will simply return 0. Either wait to point to * an already answered Aggregator or use the recommended latestRoundData * instead which includes better verification information. */ function latestAnswer() public view override checkAccess() returns (int256) { return super.latestAnswer(); } /** * @notice get the most recently reported round ID * @dev overridden funcion to add the checkAccess() modifier * * @dev #[deprecated] Use latestRoundData instead. This does not error if no * answer has been reached, it will simply return 0. Either wait to point to * an already answered Aggregator or use the recommended latestRoundData * instead which includes better verification information. */ function latestRound() public view override checkAccess() returns (uint256) { return super.latestRound(); } /** * @notice get the most recent updated at timestamp * @dev overridden funcion to add the checkAccess() modifier * * @dev #[deprecated] Use latestRoundData instead. This does not error if no * answer has been reached, it will simply return 0. Either wait to point to * an already answered Aggregator or use the recommended latestRoundData * instead which includes better verification information. */ function latestTimestamp() public view override checkAccess() returns (uint256) { return super.latestTimestamp(); } /** * @notice get past rounds answers * @dev overridden funcion to add the checkAccess() modifier * @param _roundId the round number to retrieve the answer for * * @dev #[deprecated] Use getRoundData instead. This does not error if no * answer has been reached, it will simply return 0. Either wait to point to * an already answered Aggregator or use the recommended getRoundData * instead which includes better verification information. */ function getAnswer(uint256 _roundId) public view override checkAccess() returns (int256) { return super.getAnswer(_roundId); } /** * @notice get timestamp when an answer was last updated * @dev overridden funcion to add the checkAccess() modifier * @param _roundId the round number to retrieve the updated timestamp for * * @dev #[deprecated] Use getRoundData instead. This does not error if no * answer has been reached, it will simply return 0. Either wait to point to * an already answered Aggregator or use the recommended getRoundData * instead which includes better verification information. */ function getTimestamp(uint256 _roundId) public view override checkAccess() returns (uint256) { return super.getTimestamp(_roundId); } } // File: contracts/ACA.sol
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_link","internalType":"address"},{"type":"uint128","name":"_paymentAmount","internalType":"uint128"},{"type":"uint32","name":"_timeout","internalType":"uint32"},{"type":"address","name":"_validator","internalType":"address"},{"type":"int256","name":"_minSubmissionValue","internalType":"int256"},{"type":"int256","name":"_maxSubmissionValue","internalType":"int256"},{"type":"uint8","name":"_decimals","internalType":"uint8"},{"type":"string","name":"_description","internalType":"string"}]},{"type":"event","name":"AddedAccess","inputs":[{"type":"address","name":"user","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"AnswerUpdated","inputs":[{"type":"int256","name":"current","internalType":"int256","indexed":true},{"type":"uint256","name":"roundId","internalType":"uint256","indexed":true},{"type":"uint256","name":"updatedAt","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"AvailableFundsUpdated","inputs":[{"type":"uint256","name":"amount","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"CheckAccessDisabled","inputs":[],"anonymous":false},{"type":"event","name":"CheckAccessEnabled","inputs":[],"anonymous":false},{"type":"event","name":"NewRound","inputs":[{"type":"uint256","name":"roundId","internalType":"uint256","indexed":true},{"type":"address","name":"startedBy","internalType":"address","indexed":true},{"type":"uint256","name":"startedAt","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OracleAdminUpdateRequested","inputs":[{"type":"address","name":"oracle","internalType":"address","indexed":true},{"type":"address","name":"admin","internalType":"address","indexed":false},{"type":"address","name":"newAdmin","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"OracleAdminUpdated","inputs":[{"type":"address","name":"oracle","internalType":"address","indexed":true},{"type":"address","name":"newAdmin","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OraclePermissionsUpdated","inputs":[{"type":"address","name":"oracle","internalType":"address","indexed":true},{"type":"bool","name":"whitelisted","internalType":"bool","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferRequested","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"RemovedAccess","inputs":[{"type":"address","name":"user","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"RequesterPermissionsSet","inputs":[{"type":"address","name":"requester","internalType":"address","indexed":true},{"type":"bool","name":"authorized","internalType":"bool","indexed":false},{"type":"uint32","name":"delay","internalType":"uint32","indexed":false}],"anonymous":false},{"type":"event","name":"RoundDetailsUpdated","inputs":[{"type":"uint128","name":"paymentAmount","internalType":"uint128","indexed":true},{"type":"uint32","name":"minSubmissionCount","internalType":"uint32","indexed":true},{"type":"uint32","name":"maxSubmissionCount","internalType":"uint32","indexed":true},{"type":"uint32","name":"restartDelay","internalType":"uint32","indexed":false},{"type":"uint32","name":"timeout","internalType":"uint32","indexed":false}],"anonymous":false},{"type":"event","name":"SubmissionReceived","inputs":[{"type":"int256","name":"submission","internalType":"int256","indexed":true},{"type":"uint32","name":"round","internalType":"uint32","indexed":true},{"type":"address","name":"oracle","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"ValidatorUpdated","inputs":[{"type":"address","name":"previous","internalType":"address","indexed":true},{"type":"address","name":"current","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"acceptAdmin","inputs":[{"type":"address","name":"_oracle","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"acceptOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addAccess","inputs":[{"type":"address","name":"_user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint128","name":"","internalType":"uint128"}],"name":"allocatedFunds","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint128","name":"","internalType":"uint128"}],"name":"availableFunds","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeOracles","inputs":[{"type":"address[]","name":"_removed","internalType":"address[]"},{"type":"address[]","name":"_added","internalType":"address[]"},{"type":"address[]","name":"_addedAdmins","internalType":"address[]"},{"type":"uint32","name":"_minSubmissions","internalType":"uint32"},{"type":"uint32","name":"_maxSubmissions","internalType":"uint32"},{"type":"uint32","name":"_restartDelay","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"checkEnabled","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"description","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"disableAccessCheck","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"enableAccessCheck","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getAdmin","inputs":[{"type":"address","name":"_oracle","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"int256","name":"","internalType":"int256"}],"name":"getAnswer","inputs":[{"type":"uint256","name":"_roundId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"}],"name":"getOracles","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint80","name":"roundId","internalType":"uint80"},{"type":"int256","name":"answer","internalType":"int256"},{"type":"uint256","name":"startedAt","internalType":"uint256"},{"type":"uint256","name":"updatedAt","internalType":"uint256"},{"type":"uint80","name":"answeredInRound","internalType":"uint80"}],"name":"getRoundData","inputs":[{"type":"uint80","name":"_roundId","internalType":"uint80"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTimestamp","inputs":[{"type":"uint256","name":"_roundId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"hasAccess","inputs":[{"type":"address","name":"_user","internalType":"address"},{"type":"bytes","name":"_calldata","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"int256","name":"","internalType":"int256"}],"name":"latestAnswer","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"latestRound","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint80","name":"roundId","internalType":"uint80"},{"type":"int256","name":"answer","internalType":"int256"},{"type":"uint256","name":"startedAt","internalType":"uint256"},{"type":"uint256","name":"updatedAt","internalType":"uint256"},{"type":"uint80","name":"answeredInRound","internalType":"uint80"}],"name":"latestRoundData","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"latestTimestamp","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract LinkTokenInterface"}],"name":"linkToken","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"maxSubmissionCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"int256","name":"","internalType":"int256"}],"name":"maxSubmissionValue","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"minSubmissionCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"int256","name":"","internalType":"int256"}],"name":"minSubmissionValue","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"onTokenTransfer","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"oracleCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"_eligibleToSubmit","internalType":"bool"},{"type":"uint32","name":"_roundId","internalType":"uint32"},{"type":"int256","name":"_latestSubmission","internalType":"int256"},{"type":"uint64","name":"_startedAt","internalType":"uint64"},{"type":"uint64","name":"_timeout","internalType":"uint64"},{"type":"uint128","name":"_availableFunds","internalType":"uint128"},{"type":"uint8","name":"_oracleCount","internalType":"uint8"},{"type":"uint128","name":"_paymentAmount","internalType":"uint128"}],"name":"oracleRoundState","inputs":[{"type":"address","name":"_oracle","internalType":"address"},{"type":"uint32","name":"_queriedRoundId","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint128","name":"","internalType":"uint128"}],"name":"paymentAmount","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeAccess","inputs":[{"type":"address","name":"_user","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint80","name":"","internalType":"uint80"}],"name":"requestNewRound","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"restartDelay","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setRequesterPermissions","inputs":[{"type":"address","name":"_requester","internalType":"address"},{"type":"bool","name":"_authorized","internalType":"bool"},{"type":"uint32","name":"_delay","internalType":"uint32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setValidator","inputs":[{"type":"address","name":"_newValidator","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"submit","inputs":[{"type":"uint256","name":"_roundId","internalType":"uint256"},{"type":"int256","name":"_submission","internalType":"int256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"timeout","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferAdmin","inputs":[{"type":"address","name":"_oracle","internalType":"address"},{"type":"address","name":"_newAdmin","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"_to","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateAvailableFunds","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateFutureRounds","inputs":[{"type":"uint128","name":"_paymentAmount","internalType":"uint128"},{"type":"uint32","name":"_minSubmissions","internalType":"uint32"},{"type":"uint32","name":"_maxSubmissions","internalType":"uint32"},{"type":"uint32","name":"_restartDelay","internalType":"uint32"},{"type":"uint32","name":"_timeout","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract AggregatorValidatorInterface"}],"name":"validator","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"version","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawFunds","inputs":[{"type":"address","name":"_recipient","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawPayment","inputs":[{"type":"address","name":"_oracle","internalType":"address"},{"type":"address","name":"_recipient","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"withdrawablePayment","inputs":[{"type":"address","name":"_oracle","internalType":"address"}]}]
Contract Creation Code
0x60c06040523480156200001157600080fd5b5060405162008c3538038062008c3583398181016040526101008110156200003857600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190805160405193929190846401000000008211156200009f57600080fd5b83820191506020820185811115620000b657600080fd5b8251866001820283011164010000000082111715620000d457600080fd5b8083526020830192505050908051906020019080838360005b838110156200010a578082015181840152602081019050620000ed565b50505050905090810190601f168015620001385780820380516001836020036101000a031916815260200191505b506040525050508787878787878787336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555087600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620001df8760008060008a620002c760201b60201c565b620001f085620007fc60201b60201c565b83608081815250508260a0818152505081600560006101000a81548160ff021916908360ff16021790555080600690805190602001906200023392919062000b2b565b50620002548663ffffffff1642620009ba60201b62005e901790919060201c565b600960008063ffffffff16815260200190815260200160002060010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050505050505050506001600e60006101000a81548160ff021916908315150217905550505050505050505062000bda565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146200038a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b60006200039c62000a4460201b60201c565b60ff1690508463ffffffff168463ffffffff16101562000424576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f6d6178206d75737420657175616c2f657863656564206d696e0000000000000081525060200191505060405180910390fd5b8363ffffffff168163ffffffff161015620004a7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f6d61782063616e6e6f742065786365656420746f74616c00000000000000000081525060200191505060405180910390fd5b60008163ffffffff161480620004c857508263ffffffff168163ffffffff16115b6200053b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f64656c61792063616e6e6f742065786365656420746f74616c0000000000000081525060200191505060405180910390fd5b6200055e866fffffffffffffffffffffffffffffffff1662000a5160201b60201c565b600d60000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16101562000607576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f696e73756666696369656e742066756e647320666f72207061796d656e74000081525060200191505060405180910390fd5b60006200061962000a4460201b60201c565b60ff161115620006a15760008563ffffffff1611620006a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f6d696e206d7573742062652067726561746572207468616e203000000000000081525060200191505060405180910390fd5b5b85600460006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555084600460146101000a81548163ffffffff021916908363ffffffff16021790555083600460106101000a81548163ffffffff021916908363ffffffff16021790555082600460186101000a81548163ffffffff021916908363ffffffff160217905550816004601c6101000a81548163ffffffff021916908363ffffffff1602179055508363ffffffff168563ffffffff16600460009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff167f56800c9d1ed723511246614d15e58cfcde15b6a33c245b5c961b689c1890fd8f8686604051808363ffffffff1663ffffffff1681526020018263ffffffff1663ffffffff1681526020019250505060405180910390a4505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614620008bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614620009b65781600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fcfac5dc75b8d9a7e074162f59d9adcd33da59f0fe8dfb21580db298fc0fdad0d60405160405180910390a35b5050565b60008282111562000a33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b600082840390508091505092915050565b6000600c80549050905090565b600062000a99600262000a8562000a6d62000a4460201b60201c565b60ff168562000aa060201b6200704c1790919060201c565b62000aa060201b6200704c1790919060201c565b9050919050565b60008083141562000ab5576000905062000b25565b600082840290508284828162000ac757fe5b041462000b20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018062008c146021913960400191505060405180910390fd5b809150505b92915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1062000b6e57805160ff191683800117855562000b9f565b8280016001018555821562000b9f579182015b8281111562000b9e57825182559160200191906001019062000b81565b5b50905062000bae919062000bb2565b5090565b62000bd791905b8082111562000bd357600081600090555060010162000bb9565b5090565b90565b60805160a05161800c62000c08600039806114bf52806119285250806114295280613030525061800c6000f3fe608060405234801561001057600080fd5b50600436106102955760003560e01c806370dea79a11610167578063a4c0ed36116100ce578063d4cc54e411610087578063d4cc54e414610f6e578063dc7f012414610fb0578063e2e4031714610fd2578063e9ee6eeb1461102a578063f2fde38b1461108e578063feaf968c146110d257610295565b8063a4c0ed3614610d8d578063b5ab58dc14610e30578063b633620c14610e72578063c107532914610eb4578063c35905c614610f02578063c937450014610f4457610295565b80638823da6c116101205780638823da6c14610acc57806388aa80e714610b105780638da5cb5b14610c2f57806398e5b12a14610c795780639a6fc8f514610caf578063a118f24914610d4957610295565b806370dea79a146109cf5780637284e416146109f957806379ba509714610a7c5780637c2b0b2114610a865780638038e4a114610aa45780638205bf6a14610aae57610295565b806340884c521161020b57806358609e44116101c457806358609e44146107a8578063613d8fcc146107d2578063628806ef146107f657806364efb22b1461083a578063668a0f02146108be5780636b14daf8146108dc57610295565b806340884c521461067757806346fcff4c146106d65780634f8fc3b51461071857806350d25bcd1461072257806354fd4d501461074057806357970e931461075e57610295565b8063313ce5671161025d578063313ce5671461039e578063357ebb02146103c257806338aa4c72146103ec5780633969c20f1461046c5780633a5381b5146105bf5780633d3d77141461060957610295565b80630a7569831461029a5780631327d3d8146102a4578063202ee0ed146102e857806320ed02751461032057806323ca290314610380575b600080fd5b6102a261113c565b005b6102e6600480360360208110156102ba57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061125d565b005b61031e600480360360408110156102fe57600080fd5b810190808035906020019092919080359060200190929190505050611419565b005b61037e6004803603606081101561033657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190803563ffffffff16906020019092919050505061164d565b005b610388611926565b6040518082815260200191505060405180910390f35b6103a661194a565b604051808260ff1660ff16815260200191505060405180910390f35b6103ca61195d565b604051808263ffffffff1663ffffffff16815260200191505060405180910390f35b61046a600480360360a081101561040257600080fd5b8101908080356fffffffffffffffffffffffffffffffff169060200190929190803563ffffffff169060200190929190803563ffffffff169060200190929190803563ffffffff169060200190929190803563ffffffff169060200190929190505050611973565b005b6105bd600480360360c081101561048257600080fd5b810190808035906020019064010000000081111561049f57600080fd5b8201836020820111156104b157600080fd5b803590602001918460208302840111640100000000831117156104d357600080fd5b9091929391929390803590602001906401000000008111156104f457600080fd5b82018360208201111561050657600080fd5b8035906020019184602083028401116401000000008311171561052857600080fd5b90919293919293908035906020019064010000000081111561054957600080fd5b82018360208201111561055b57600080fd5b8035906020019184602083028401116401000000008311171561057d57600080fd5b9091929391929390803563ffffffff169060200190929190803563ffffffff169060200190929190803563ffffffff169060200190929190505050611e88565b005b6105c761216c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6106756004803603606081101561061f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612192565b005b61067f6125b8565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156106c25780820151818401526020810190506106a7565b505050509050019250505060405180910390f35b6106de612646565b60405180826fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61072061266f565b005b61072a6128ab565b6040518082815260200191505060405180910390f35b61074861297b565b6040518082815260200191505060405180910390f35b610766612980565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107b06129a6565b604051808263ffffffff1663ffffffff16815260200191505060405180910390f35b6107da6129bc565b604051808260ff1660ff16815260200191505060405180910390f35b6108386004803603602081101561080c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506129c9565b005b61087c6004803603602081101561085057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612c2c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6108c6612c98565b6040518082815260200191505060405180910390f35b6109b5600480360360408110156108f257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561092f57600080fd5b82018360208201111561094157600080fd5b8035906020019184600183028401116401000000008311171561096357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612d68565b604051808215151515815260200191505060405180910390f35b6109d7612db2565b604051808263ffffffff1663ffffffff16815260200191505060405180910390f35b610a01612dc8565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610a41578082015181840152602081019050610a26565b50505050905090810190601f168015610a6e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610a84612e66565b005b610a8e61302e565b6040518082815260200191505060405180910390f35b610aac613052565b005b610ab6613172565b6040518082815260200191505060405180910390f35b610b0e60048036036020811015610ae257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613242565b005b610b6260048036036040811015610b2657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803563ffffffff169060200190929190505050613415565b60405180891515151581526020018863ffffffff1663ffffffff1681526020018781526020018667ffffffffffffffff1667ffffffffffffffff1681526020018567ffffffffffffffff1667ffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020018360ff1660ff168152602001826fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020019850505050505050505060405180910390f35b610c37613674565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610c81613699565b604051808269ffffffffffffffffffff1669ffffffffffffffffffff16815260200191505060405180910390f35b610ce760048036036020811015610cc557600080fd5b81019080803569ffffffffffffffffffff16906020019092919050505061386f565b604051808669ffffffffffffffffffff1669ffffffffffffffffffff1681526020018581526020018481526020018381526020018269ffffffffffffffffffff1669ffffffffffffffffffff1681526020019550505050505060405180910390f35b610d8b60048036036020811015610d5f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613954565b005b610e2e60048036036060811015610da357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610dea57600080fd5b820183602082011115610dfc57600080fd5b80359060200191846001830284011164010000000083111715610e1e57600080fd5b9091929391929390505050613b26565b005b610e5c60048036036020811015610e4657600080fd5b8101908080359060200190929190505050613bad565b6040518082815260200191505060405180910390f35b610e9e60048036036020811015610e8857600080fd5b8101908080359060200190929190505050613c80565b6040518082815260200191505060405180910390f35b610f0060048036036040811015610eca57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613d53565b005b610f0a614070565b60405180826fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610f4c614092565b604051808263ffffffff1663ffffffff16815260200191505060405180910390f35b610f766140a8565b60405180826fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610fb86140d1565b604051808215151515815260200191505060405180910390f35b61101460048036036020811015610fe857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506140e4565b6040518082815260200191505060405180910390f35b61108c6004803603604081101561104057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061415e565b005b6110d0600480360360208110156110a457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614394565b005b6110da614515565b604051808669ffffffffffffffffffff1669ffffffffffffffffffff1681526020018581526020018481526020018381526020018269ffffffffffffffffffff1669ffffffffffffffffffff1681526020019550505050505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146111fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b600e60009054906101000a900460ff161561125b576000600e60006101000a81548160ff0219169083151502179055507f3be8a977a014527b50ae38adda80b56911c267328965c98ddc385d248f53963860405160405180910390a15b565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461131f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146114155781600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fcfac5dc75b8d9a7e074162f59d9adcd33da59f0fe8dfb21580db298fc0fdad0d60405160405180910390a35b5050565b606061142533846145f7565b90507f00000000000000000000000000000000000000000000000000000000000000008212156114bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f76616c75652062656c6f77206d696e5375626d697373696f6e56616c7565000081525060200191505060405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000821315611553576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f76616c75652061626f7665206d61785375626d697373696f6e56616c7565000081525060200191505060405180910390fd5b600081511481906115ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156115c45780820151818401526020810190506115a9565b50505050905090810190601f1680156115f15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506116098361496c565b6116138284614a86565b60008061161f85614c41565b9150915061162c85614e54565b611635856151b9565b81156116465761164585826152c1565b5b5050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461170f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b811515600b60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff161515141561176f57611921565b81156118355781600b60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff02191690831515021790555080600b60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160016101000a81548163ffffffff021916908363ffffffff1602179055506118ba565b600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080820160006101000a81549060ff02191690556000820160016101000a81549063ffffffff02191690556000820160056101000a81549063ffffffff021916905550505b8273ffffffffffffffffffffffffffffffffffffffff167fc3df5a754e002718f2e10804b99e6605e7c701d95cec9552c7680ca2b6f2820a838360405180831515151581526020018263ffffffff1663ffffffff1681526020019250505060405180910390a25b505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600560009054906101000a900460ff1681565b600460189054906101000a900463ffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611a35576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b6000611a3f6129bc565b60ff1690508463ffffffff168463ffffffff161015611ac6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f6d6178206d75737420657175616c2f657863656564206d696e0000000000000081525060200191505060405180910390fd5b8363ffffffff168163ffffffff161015611b48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f6d61782063616e6e6f742065786365656420746f74616c00000000000000000081525060200191505060405180910390fd5b60008163ffffffff161480611b6857508263ffffffff168163ffffffff16115b611bda576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f64656c61792063616e6e6f742065786365656420746f74616c0000000000000081525060200191505060405180910390fd5b611bf5866fffffffffffffffffffffffffffffffff16615463565b600d60000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161015611c9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f696e73756666696369656e742066756e647320666f72207061796d656e74000081525060200191505060405180910390fd5b6000611ca76129bc565b60ff161115611d2d5760008563ffffffff1611611d2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f6d696e206d7573742062652067726561746572207468616e203000000000000081525060200191505060405180910390fd5b5b85600460006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555084600460146101000a81548163ffffffff021916908363ffffffff16021790555083600460106101000a81548163ffffffff021916908363ffffffff16021790555082600460186101000a81548163ffffffff021916908363ffffffff160217905550816004601c6101000a81548163ffffffff021916908363ffffffff1602179055508363ffffffff168563ffffffff16600460009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff167f56800c9d1ed723511246614d15e58cfcde15b6a33c245b5c961b689c1890fd8f8686604051808363ffffffff1663ffffffff1681526020018263ffffffff1663ffffffff1681526020019250505060405180910390a4505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f4a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b60008090505b89899050811015611f9957611f8c8a8a83818110611f6a57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1661549c565b8080600101915050611f50565b50848490508787905014612015576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f6e6565642073616d65206f7261636c6520616e642061646d696e20636f756e7481525060200191505060405180910390fd5b604d612037888890506120266129bc565b60ff166157e790919063ffffffff16565b11156120ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f6d6178206f7261636c657320616c6c6f7765640000000000000000000000000081525060200191505060405180910390fd5b60008090505b87879050811015612123576121168888838181106120cb57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff168787848181106120f457fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1661586f565b80806001019150506120b1565b50612161600460009054906101000a90046fffffffffffffffffffffffffffffffff168484846004601c9054906101000a900463ffffffff16611973565b505050505050505050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff16600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612295576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f6e6c792063616c6c61626c652062792061646d696e0000000000000000000081525060200191505060405180910390fd5b60008190506000600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a90046fffffffffffffffffffffffffffffffff169050816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161015612397576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f696e73756666696369656e7420776974686472617761626c652066756e64730081525060200191505060405180910390fd5b6123bc82826fffffffffffffffffffffffffffffffff16615de390919063ffffffff16565b600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555061247a82600d60000160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16615de390919063ffffffff16565b600d60000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85846fffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561257057600080fd5b505af1158015612584573d6000803e3d6000fd5b505050506040513d602081101561259a57600080fd5b81019080805190602001909291905050506125b157fe5b5050505050565b6060600c80548060200260200160405190810160405280929190818152602001828054801561263c57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116125f2575b5050505050905090565b6000600d60000160009054906101000a90046fffffffffffffffffffffffffffffffff16905090565b612677617e2e565b600d6040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16815250509050600061281e82602001516fffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156127d557600080fd5b505afa1580156127e9573d6000803e3d6000fd5b505050506040513d60208110156127ff57600080fd5b8101908080519060200190929190505050615e9090919063ffffffff16565b90508082600001516fffffffffffffffffffffffffffffffff16146128a75780600d60000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550807ffe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234f60405160405180910390a25b5050565b60006128fc336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612d68565b61296e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260098152602001807f4e6f20616363657373000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b612976615f19565b905090565b600381565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460109054906101000a900463ffffffff1681565b6000600c80549050905090565b3373ffffffffffffffffffffffffffffffffffffffff16600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612acc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f6f6e6c792063616c6c61626c652062792070656e64696e672061646d696e000081525060200191505060405180910390fd5b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555033600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160026101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f0c5055390645c15a4be9a21b3f8d019153dcb4a0c125685da6eb84048e2fe90460405160405180910390a350565b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160029054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000612ce9336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612d68565b612d5b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260098152602001807f4e6f20616363657373000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b612d63615f55565b905090565b6000612d748383615f75565b80612daa57503273ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b905092915050565b6004601c9054906101000a900463ffffffff1681565b60068054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015612e5e5780601f10612e3357610100808354040283529160200191612e5e565b820191906000526020600020905b815481529060010190602001808311612e4157829003601f168201915b505050505081565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612f29576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4d7573742062652070726f706f736564206f776e65720000000000000000000081525060200191505060405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a350565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613114576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b600e60009054906101000a900460ff16613170576001600e60006101000a81548160ff0219169083151502179055507faebf329500988c6488a0074e5a0a9ff304561fc5c6fc877aeb1d59c8282c348060405160405180910390a15b565b60006131c3336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612d68565b613235576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260098152602001807f4e6f20616363657373000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61323d615fe4565b905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613304576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b600f60008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615613412576000600f60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f3d68a6fce901d20453d1a7aa06bf3950302a735948037deb182a8db66df2a0d181604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b50565b6000806000806000806000803273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146134c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f66662d636861696e2072656164696e67206f6e6c790000000000000000000081525060200191505060405180910390fd5b60008963ffffffff16111561364d576000600960008b63ffffffff1663ffffffff16815260200190815260200160002090506000600a60008c63ffffffff1663ffffffff16815260200190815260200160002090506135218c8c61603e565b8b600860008f73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101548460010160009054906101000a900467ffffffffffffffff168460010160089054906101000a900463ffffffff16600d60000160009054906101000a90046fffffffffffffffffffffffffffffffff166135bd6129bc565b60008960010160009054906101000a900467ffffffffffffffff1667ffffffffffffffff161161360b57600460009054906101000a90046fffffffffffffffffffffffffffffffff1661362d565b87600101600c9054906101000a90046fffffffffffffffffffffffffffffffff165b8363ffffffff169350995099509950995099509950995099505050613667565b6136568a6160d7565b975097509750975097509750975097505b9295985092959890939650565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1661375d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f6e6f7420617574686f72697a656420726571756573746572000000000000000081525060200191505060405180910390fd5b6000600760009054906101000a900463ffffffff1690506000600960008363ffffffff1663ffffffff16815260200190815260200160002060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff1611806137c857506137c781616388565b5b61383a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f7072657620726f756e64206d75737420626520737570657273656461626c650081525060200191505060405180910390fd5b600061385660018363ffffffff1661645b90919063ffffffff16565b9050613861816164ef565b8063ffffffff169250505090565b60008060008060006138c6336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612d68565b613938576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260098152602001807f4e6f20616363657373000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b613941866166ad565b9450945094509450945091939590929450565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613a16576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b600f60008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16613b23576001600f60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db481604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b50565b60008282905014613b9f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f7472616e7366657220646f65736e2774206163636570742063616c6c6461746181525060200191505060405180910390fd5b613ba761266f565b50505050565b6000613bfe336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612d68565b613c70576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260098152602001807f4e6f20616363657373000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b613c79826168d1565b9050919050565b6000613cd1336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612d68565b613d43576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260098152602001807f4e6f20616363657373000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b613d4c82616915565b9050919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613e15576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b6000600d60000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16905081613e99613e8a600460009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16615463565b83615e9090919063ffffffff16565b1015613f0d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f696e73756666696369656e7420726573657276652066756e647300000000000081525060200191505060405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015613fb657600080fd5b505af1158015613fca573d6000803e3d6000fd5b505050506040513d6020811015613fe057600080fd5b8101908080519060200190929190505050614063576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f746f6b656e207472616e73666572206661696c6564000000000000000000000081525060200191505060405180910390fd5b61406b61266f565b505050565b600460009054906101000a90046fffffffffffffffffffffffffffffffff1681565b600460149054906101000a900463ffffffff1681565b6000600d60000160109054906101000a90046fffffffffffffffffffffffffffffffff16905090565b600e60009054906101000a900460ff1681565b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff169050919050565b3373ffffffffffffffffffffffffffffffffffffffff16600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614261576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f6e6c792063616c6c61626c652062792061646d696e0000000000000000000081525060200191505060405180910390fd5b80600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff167fb79bf2e89c2d70dde91d2991fb1ea69b7e478061ad7c04ed5b02b96bc52b81043383604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a25050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614456576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127860405160405180910390a350565b600080600080600061456c336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612d68565b6145de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260098152602001807f4e6f20616363657373000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6145e6616977565b945094509450945094509091929394565b60606000600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160109054906101000a900463ffffffff1690506000600760009054906101000a900463ffffffff16905060008263ffffffff1614156146b5576040518060400160405280601281526020017f6e6f7420656e61626c6564206f7261636c65000000000000000000000000000081525092505050614966565b8363ffffffff168263ffffffff161115614708576040518060400160405280601681526020017f6e6f742079657420656e61626c6564206f7261636c650000000000000000000081525092505050614966565b8363ffffffff16600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160149054906101000a900463ffffffff1663ffffffff1610156147ad576040518060400160405280601881526020017f6e6f206c6f6e67657220616c6c6f776564206f7261636c65000000000000000081525092505050614966565b8363ffffffff16600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160189054906101000a900463ffffffff1663ffffffff1610614851576040518060400160405280602081526020017f63616e6e6f74207265706f7274206f6e2070726576696f757320726f756e647381525092505050614966565b8063ffffffff168463ffffffff1614158015614892575061488260018263ffffffff1661645b90919063ffffffff16565b63ffffffff168463ffffffff1614155b80156148a557506148a384826169b1565b155b156148e9576040518060400160405280601781526020017f696e76616c696420726f756e6420746f207265706f727400000000000000000081525092505050614966565b60018463ffffffff161415801561491f575061491d61491860018663ffffffff16616a2f90919063ffffffff16565b616ac4565b155b15614963576040518060400160405280601f81526020017f70726576696f757320726f756e64206e6f7420737570657273656461626c650081525092505050614966565b50505b92915050565b61497581616b20565b61497e57614a83565b6000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001601c9054906101000a900463ffffffff1663ffffffff169050600460189054906101000a900463ffffffff1663ffffffff1681018263ffffffff1611158015614a0c575060008114155b15614a175750614a83565b614a2082616b63565b81600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001601c6101000a81548163ffffffff021916908363ffffffff160217905550505b50565b614a8f81616e6c565b614b01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f726f756e64206e6f7420616363657074696e67207375626d697373696f6e730081525060200191505060405180910390fd5b600a60008263ffffffff1663ffffffff16815260200190815260200160002060000182908060018154018082558091505060019003906000526020600020016000909190919091505580600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160186101000a81548163ffffffff021916908363ffffffff16021790555081600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055503373ffffffffffffffffffffffffffffffffffffffff168163ffffffff16837f92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c60405160405180910390a45050565b600080600a60008463ffffffff1663ffffffff16815260200190815260200160002060010160049054906101000a900463ffffffff1663ffffffff16600a60008563ffffffff1663ffffffff168152602001908152602001600020600001805490501015614cb85760008080905091509150614e4f565b6000614d33600a60008663ffffffff1663ffffffff168152602001908152602001600020600001805480602002602001604051908101604052809291908181526020018280548015614d2957602002820191906000526020600020905b815481526020019060010190808311614d15575b5050505050616eb1565b905080600960008663ffffffff1663ffffffff1681526020019081526020016000206000018190555042600960008663ffffffff1663ffffffff16815260200190815260200160002060010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555083600960008663ffffffff1663ffffffff16815260200190815260200160002060010160106101000a81548163ffffffff021916908363ffffffff16021790555083600760046101000a81548163ffffffff021916908363ffffffff1602179055508363ffffffff16817f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f426040518082815260200191505060405180910390a360018192509250505b915091565b6000600a60008363ffffffff1663ffffffff168152602001908152602001600020600101600c9054906101000a90046fffffffffffffffffffffffffffffffff169050614e9f617e2e565b600d6040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16815250509050614f6b8282600001516fffffffffffffffffffffffffffffffff16615de390919063ffffffff16565b81600001906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff1681525050614fc38282602001516fffffffffffffffffffffffffffffffff16616fa090919063ffffffff16565b81602001906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff168152505080600d60008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055509050506150f982600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16616fa090919063ffffffff16565b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555080600001516fffffffffffffffffffffffffffffffff167ffe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234f60405160405180910390a2505050565b600a60008263ffffffff1663ffffffff16815260200190815260200160002060010160009054906101000a900463ffffffff1663ffffffff16600a60008363ffffffff1663ffffffff168152602001908152602001600020600001805490501015615223576152be565b600a60008263ffffffff1663ffffffff168152602001908152602001600020600080820160006152539190617e6c565b6001820160006101000a81549063ffffffff02191690556001820160046101000a81549063ffffffff02191690556001820160086101000a81549063ffffffff021916905560018201600c6101000a8154906fffffffffffffffffffffffffffffffff021916905550505b50565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415615323575061545f565b600061533f60018563ffffffff16616a2f90919063ffffffff16565b90506000600960008363ffffffff1663ffffffff16815260200190815260200160002060010160109054906101000a900463ffffffff1690506000600960008463ffffffff1663ffffffff1681526020019081526020016000206000015490508373ffffffffffffffffffffffffffffffffffffffff1663beed9b51620186a084848a8a6040518663ffffffff1660e01b8152600401808563ffffffff1681526020018481526020018363ffffffff168152602001828152602001945050505050602060405180830381600088803b15801561541a57600080fd5b5087f19350505050801561544f57506040513d602081101561543b57600080fd5b810190808051906020019092919050505060015b6154585761545a565b505b505050505b5050565b600061549560026154876154756129bc565b60ff168561704c90919063ffffffff16565b61704c90919063ffffffff16565b9050919050565b6154a5816170d2565b615517576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6f7261636c65206e6f7420656e61626c6564000000000000000000000000000081525060200191505060405180910390fd5b6155436001600760009054906101000a900463ffffffff1663ffffffff1661645b90919063ffffffff16565b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff1602179055506000600c6155c560016155b46129bc565b60ff16615e9090919063ffffffff16565b815481106155cf57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160009054906101000a900461ffff16905080600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160006101000a81548161ffff021916908361ffff160217905550600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160006101000a81549061ffff021916905581600c8261ffff168154811061571357fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600c80548061576657fe5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690559055600015158373ffffffffffffffffffffffffffffffffffffffff167f18dd09695e4fbdae8d1a5edb11221eb04564269c29a089b9753a6535c54ba92e60405160405180910390a3505050565b600080828401905083811015615865576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b615878826170d2565b156158eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f7261636c6520616c726561647920656e61626c65640000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561598e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f63616e6e6f74207365742061646d696e20746f2030000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161480615ab857508073ffffffffffffffffffffffffffffffffffffffff16600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b615b2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f6f776e65722063616e6e6f74206f76657277726974652061646d696e0000000081525060200191505060405180910390fd5b615b338261713c565b600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160106101000a81548163ffffffff021916908363ffffffff16021790555063ffffffff600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff160217905550600c80549050600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160006101000a81548161ffff021916908361ffff160217905550600c829080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160026101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600115158273ffffffffffffffffffffffffffffffffffffffff167f18dd09695e4fbdae8d1a5edb11221eb04564269c29a089b9753a6535c54ba92e60405160405180910390a38073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f0c5055390645c15a4be9a21b3f8d019153dcb4a0c125685da6eb84048e2fe90460405160405180910390a35050565b6000826fffffffffffffffffffffffffffffffff16826fffffffffffffffffffffffffffffffff161115615e7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b600082840390508091505092915050565b600082821115615f08576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b600082840390508091505092915050565b600060096000600760049054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200190815260200160002060000154905090565b6000600760049054906101000a900463ffffffff1663ffffffff16905090565b6000600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1680615fdc5750600e60009054906101000a900460ff16155b905092915050565b600060096000600760049054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200190815260200160002060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff16905090565b600080600960008463ffffffff1663ffffffff16815260200190815260200160002060010160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1611156160ae5761609182616e6c565b80156160a7575060006160a484846145f7565b51145b90506160d1565b6160b883836171f9565b80156160ce575060006160cb84846145f7565b51145b90505b92915050565b6000806000806000806000806000600960008063ffffffff16815260200190815260200160002090506000600860008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000600760009054906101000a900463ffffffff1663ffffffff168260000160189054906101000a900463ffffffff1663ffffffff16148061619d575061619b600760009054906101000a900463ffffffff16616e6c565b155b90506161ba600760009054906101000a900463ffffffff16616ac4565b80156161c35750805b15616249576161f46001600760009054906101000a900463ffffffff1663ffffffff1661645b90919063ffffffff16565b9950600960008b63ffffffff1663ffffffff1681526020019081526020016000209250600460009054906101000a90046fffffffffffffffffffffffffffffffff1693506162428c8b6171f9565b9a506162cc565b600760009054906101000a900463ffffffff169950600960008b63ffffffff1663ffffffff1681526020019081526020016000209250600a60008b63ffffffff1663ffffffff168152602001908152602001600020600101600c9054906101000a90046fffffffffffffffffffffffffffffffff1693506162c98a616e6c565b9a505b60006162d88d8c6145f7565b51146162e35760009a505b8a8a83600101548560010160009054906101000a900467ffffffffffffffff16600a60008f63ffffffff1663ffffffff16815260200190815260200160002060010160089054906101000a900463ffffffff16600d60000160009054906101000a90046fffffffffffffffffffffffffffffffff166163606129bc565b8a8363ffffffff1693509a509a509a509a509a509a509a509a50505050919395975091939597565b600080600960008463ffffffff1663ffffffff16815260200190815260200160002060010160009054906101000a900467ffffffffffffffff1690506000600a60008563ffffffff1663ffffffff16815260200190815260200160002060010160089054906101000a900463ffffffff16905060008267ffffffffffffffff1611801561641b575060008163ffffffff16115b80156164525750426164468263ffffffff168467ffffffffffffffff1661728e90919063ffffffff16565b67ffffffffffffffff16105b92505050919050565b60008082840190508363ffffffff168163ffffffff1610156164e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b6164f881616b20565b616501576166aa565b6000600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160059054906101000a900463ffffffff1663ffffffff169050600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160019054906101000a900463ffffffff1663ffffffff1681018263ffffffff1611806165cc5750600081145b61663e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f6d7573742064656c61792072657175657374730000000000000000000000000081525060200191505060405180910390fd5b61664782616b63565b81600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160056101000a81548163ffffffff021916908363ffffffff160217905550505b50565b60008060008060006166bd617e8d565b600960008863ffffffff1663ffffffff168152602001908152602001600020604051806080016040529081600082015481526020016001820160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020016001820160089054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020016001820160109054906101000a900463ffffffff1663ffffffff1663ffffffff168152505090506000816060015163ffffffff161180156167a857506167a78769ffffffffffffffffffff1661732a565b5b6040518060400160405280600f81526020017f4e6f20646174612070726573656e74000000000000000000000000000000000081525090616884576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561684957808201518184015260208101905061682e565b50505050905090810190601f1680156168765780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b508681600001518260200151836040015184606001518267ffffffffffffffff1692508167ffffffffffffffff1691508063ffffffff169050955095509550955095505091939590929450565b60006168dc8261732a565b1561690b57600960008363ffffffff1663ffffffff168152602001908152602001600020600001549050616910565b600090505b919050565b60006169208261732a565b1561696d57600960008363ffffffff1663ffffffff16815260200190815260200160002060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff169050616972565b600090505b919050565b60008060008060006169a0600760049054906101000a900463ffffffff1663ffffffff1661386f565b945094509450945094509091929394565b60008163ffffffff166169d460018563ffffffff1661645b90919063ffffffff16565b63ffffffff16148015616a2757506000600960008463ffffffff1663ffffffff16815260200190815260200160002060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff16145b905092915050565b60008263ffffffff168263ffffffff161115616ab3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b600082840390508091505092915050565b600080600960008463ffffffff1663ffffffff16815260200190815260200160002060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff161180616b195750616b1882616388565b5b9050919050565b6000616b4e6001600760009054906101000a900463ffffffff1663ffffffff1661645b90919063ffffffff16565b63ffffffff168263ffffffff16149050919050565b616b85616b8060018363ffffffff16616a2f90919063ffffffff16565b61733d565b80600760006101000a81548163ffffffff021916908363ffffffff160217905550616bae617ecf565b6040518060a00160405280600067ffffffffffffffff81118015616bd157600080fd5b50604051908082528060200260200182016040528015616c005781602001602082028036833780820191505090505b508152602001600460109054906101000a900463ffffffff1663ffffffff168152602001600460149054906101000a900463ffffffff1663ffffffff1681526020016004601c9054906101000a900463ffffffff1663ffffffff168152602001600460009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16815250905080600a60008463ffffffff1663ffffffff1681526020019081526020016000206000820151816000019080519060200190616cd2929190617f22565b5060208201518160010160006101000a81548163ffffffff021916908363ffffffff16021790555060408201518160010160046101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160086101000a81548163ffffffff021916908363ffffffff160217905550608082015181600101600c6101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555090505042600960008463ffffffff1663ffffffff16815260200190815260200160002060010160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff168263ffffffff167f0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271600960008663ffffffff1663ffffffff16815260200190815260200160002060010160009054906101000a900467ffffffffffffffff16604051808267ffffffffffffffff16815260200191505060405180910390a35050565b600080600a60008463ffffffff1663ffffffff16815260200190815260200160002060010160009054906101000a900463ffffffff1663ffffffff1614159050919050565b60008151600010616f2a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6c697374206d757374206e6f7420626520656d7074790000000000000000000081525060200191505060405180910390fd5b600082519050600060028281616f3c57fe5b049050600060028381616f4b57fe5b061415616f8657600080616f69866000600187036001870387617511565b8092508193505050616f7b82826175fe565b945050505050616f9b565b616f96846000600185038461769b565b925050505b919050565b6000808284019050836fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161015617042576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60008083141561705f57600090506170cc565b600082840290508284828161707057fe5b04146170c7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180617fb66021913960400191505060405180910390fd5b809150505b92915050565b600063ffffffff8016600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160149054906101000a900463ffffffff1663ffffffff16149050919050565b600080600760009054906101000a900463ffffffff16905060008163ffffffff16141580156171c85750600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160149054906101000a900463ffffffff1663ffffffff168163ffffffff16145b156171d657809150506171f4565b6171f060018263ffffffff1661645b90919063ffffffff16565b9150505b919050565b600080600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001601c9054906101000a900463ffffffff1663ffffffff169050600460189054906101000a900463ffffffff1663ffffffff1681018363ffffffff1611806172855750600081145b91505092915050565b60008082840190508367ffffffffffffffff168167ffffffffffffffff161015617320576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600063ffffffff80168211159050919050565b61734681616388565b61734f5761750e565b600061736b60018363ffffffff16616a2f90919063ffffffff16565b9050600960008263ffffffff1663ffffffff16815260200190815260200160002060000154600960008463ffffffff1663ffffffff16815260200190815260200160002060000181905550600960008263ffffffff1663ffffffff16815260200190815260200160002060010160109054906101000a900463ffffffff16600960008463ffffffff1663ffffffff16815260200190815260200160002060010160106101000a81548163ffffffff021916908363ffffffff16021790555042600960008463ffffffff1663ffffffff16815260200190815260200160002060010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600a60008363ffffffff1663ffffffff168152602001908152602001600020600080820160006174a29190617e6c565b6001820160006101000a81549063ffffffff02191690556001820160046101000a81549063ffffffff02191690556001820160086101000a81549063ffffffff021916905560018201600c6101000a8154906fffffffffffffffffffffffffffffffff02191690555050505b50565b60008082841061752057600080fd5b8386111580156175305750848411155b61753957600080fd5b8286111580156175495750848311155b61755257600080fd5b5b6001156175f3576007868603101561757b576175728787878787617735565b915091506175f4565b6000617588888888617ca9565b9050808411617599578095506175ed565b848110156175ac576001810196506175ec565b8085111580156175bb57508381105b6175c157fe5b6175cd8888838861769b565b92506175de8860018301888761769b565b9150828292509250506175f4565b5b50617553565b5b9550959350505050565b6000808312801561760f5750600082135b8061762657506000831380156176255750600082125b5b156176465760026176378484617da0565b8161763e57fe5b059050617695565b6000600280848161765357fe5b076002868161765e57fe5b07018161766757fe5b05905061769161768b6002868161767a57fe5b056002868161768557fe5b05617da0565b82617da0565b9150505b92915050565b6000818411156176aa57600080fd5b828211156176b757600080fd5b5b8284101561771657600784840310156176eb5760006176da8686868687617735565b80925081935050508191505061772d565b60006176f8868686617ca9565b905080831161770957809350617710565b6001810194505b506176b8565b84848151811061772257fe5b602002602001015190505b949350505050565b60008060008660018701039050600088600089018151811061775357fe5b6020026020010151905060008260011061778d577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6177a5565b8960018a018151811061779c57fe5b60200260200101515b90506000836002106177d7577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6177ef565b8a60028b01815181106177e657fe5b60200260200101515b9050600084600310617821577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff617839565b8b60038c018151811061783057fe5b60200260200101515b905060008560041061786b577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff617883565b8c60048d018151811061787a57fe5b60200260200101515b90506000866005106178b5577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6178cd565b8d60058e01815181106178c457fe5b60200260200101515b90506000876006106178ff577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff617917565b8e60068f018151811061790e57fe5b60200260200101515b90508587131561792c57858780975081985050505b8385131561793f57838580955081965050505b8183131561795257818380935081945050505b8487131561796557848780965081985050505b8386131561797857838680955081975050505b8083131561798b57808380925081945050505b8486131561799e57848680965081975050505b808213156179b157808280925081935050505b828713156179c457828780945081985050505b818613156179d757818680935081975050505b808513156179ea57808580925081965050505b828613156179fd57828680945081975050505b80841315617a1057808480925081955050505b82851315617a2357828580945081965050505b81841315617a3657818480935081955050505b82841315617a4957828480945081955050505b60008e8d0390506000811415617a6157879a50617b3b565b6001811415617a7257869a50617b3a565b6002811415617a8357859a50617b39565b6003811415617a9457849a50617b38565b6004811415617aa557839a50617b37565b6005811415617ab657829a50617b36565b6006811415617ac757819a50617b35565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f6b31206f7574206f6620626f756e64730000000000000000000000000000000081525060200191505060405180910390fd5b5b5b5b5b5b5b60008f8d0390508c8e1415617b5f578b8c9b509b5050505050505050505050617c9f565b6000811415617b7d578b899b509b5050505050505050505050617c9f565b6001811415617b9b578b889b509b5050505050505050505050617c9f565b6002811415617bb9578b879b509b5050505050505050505050617c9f565b6003811415617bd7578b869b509b5050505050505050505050617c9f565b6004811415617bf5578b859b509b5050505050505050505050617c9f565b6005811415617c13578b849b509b5050505050505050505050617c9f565b6006811415617c31578b839b509b5050505050505050505050617c9f565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f6b32206f7574206f6620626f756e64730000000000000000000000000000000081525060200191505060405180910390fd5b9550959350505050565b60008084600284860181617cb957fe5b0481518110617cc457fe5b602002602001015190506001840393506001830192505b600115617d97575b60018401935080858581518110617cf657fe5b602002602001015112617ce3575b60018303925080858481518110617d1757fe5b602002602001015113617d045782841015617d8957848381518110617d3857fe5b6020026020010151858581518110617d4c57fe5b6020026020010151868681518110617d6057fe5b60200260200101878681518110617d7357fe5b6020026020010182815250828152505050617d92565b82915050617d99565b617cdb565b505b9392505050565b600080828401905060008312158015617db95750838112155b80617dcf5750600083128015617dce57508381125b5b617e24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180617f956021913960400191505060405180910390fd5b8091505092915050565b604051806040016040528060006fffffffffffffffffffffffffffffffff16815260200160006fffffffffffffffffffffffffffffffff1681525090565b5080546000825590600052602060002090810190617e8a9190617f6f565b50565b604051806080016040528060008152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600063ffffffff1681525090565b6040518060a0016040528060608152602001600063ffffffff168152602001600063ffffffff168152602001600063ffffffff16815260200160006fffffffffffffffffffffffffffffffff1681525090565b828054828255906000526020600020908101928215617f5e579160200282015b82811115617f5d578251825591602001919060010190617f42565b5b509050617f6b9190617f6f565b5090565b617f9191905b80821115617f8d576000816000905550600101617f75565b5090565b9056fe5369676e6564536166654d6174683a206164646974696f6e206f766572666c6f77536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a26469706673582212203a648420c98021dfe39787881be80ceea9e624f98cad1e6c764135615d564fc064736f6c63430006060033536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7700000000000000000000000095abfbae962690fe64003da5debe0a67c84058c40000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000033b2e3c9fd0803ce80000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000064554485553440000000000000000000000000000000000000000000000000000
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106102955760003560e01c806370dea79a11610167578063a4c0ed36116100ce578063d4cc54e411610087578063d4cc54e414610f6e578063dc7f012414610fb0578063e2e4031714610fd2578063e9ee6eeb1461102a578063f2fde38b1461108e578063feaf968c146110d257610295565b8063a4c0ed3614610d8d578063b5ab58dc14610e30578063b633620c14610e72578063c107532914610eb4578063c35905c614610f02578063c937450014610f4457610295565b80638823da6c116101205780638823da6c14610acc57806388aa80e714610b105780638da5cb5b14610c2f57806398e5b12a14610c795780639a6fc8f514610caf578063a118f24914610d4957610295565b806370dea79a146109cf5780637284e416146109f957806379ba509714610a7c5780637c2b0b2114610a865780638038e4a114610aa45780638205bf6a14610aae57610295565b806340884c521161020b57806358609e44116101c457806358609e44146107a8578063613d8fcc146107d2578063628806ef146107f657806364efb22b1461083a578063668a0f02146108be5780636b14daf8146108dc57610295565b806340884c521461067757806346fcff4c146106d65780634f8fc3b51461071857806350d25bcd1461072257806354fd4d501461074057806357970e931461075e57610295565b8063313ce5671161025d578063313ce5671461039e578063357ebb02146103c257806338aa4c72146103ec5780633969c20f1461046c5780633a5381b5146105bf5780633d3d77141461060957610295565b80630a7569831461029a5780631327d3d8146102a4578063202ee0ed146102e857806320ed02751461032057806323ca290314610380575b600080fd5b6102a261113c565b005b6102e6600480360360208110156102ba57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061125d565b005b61031e600480360360408110156102fe57600080fd5b810190808035906020019092919080359060200190929190505050611419565b005b61037e6004803603606081101561033657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190803563ffffffff16906020019092919050505061164d565b005b610388611926565b6040518082815260200191505060405180910390f35b6103a661194a565b604051808260ff1660ff16815260200191505060405180910390f35b6103ca61195d565b604051808263ffffffff1663ffffffff16815260200191505060405180910390f35b61046a600480360360a081101561040257600080fd5b8101908080356fffffffffffffffffffffffffffffffff169060200190929190803563ffffffff169060200190929190803563ffffffff169060200190929190803563ffffffff169060200190929190803563ffffffff169060200190929190505050611973565b005b6105bd600480360360c081101561048257600080fd5b810190808035906020019064010000000081111561049f57600080fd5b8201836020820111156104b157600080fd5b803590602001918460208302840111640100000000831117156104d357600080fd5b9091929391929390803590602001906401000000008111156104f457600080fd5b82018360208201111561050657600080fd5b8035906020019184602083028401116401000000008311171561052857600080fd5b90919293919293908035906020019064010000000081111561054957600080fd5b82018360208201111561055b57600080fd5b8035906020019184602083028401116401000000008311171561057d57600080fd5b9091929391929390803563ffffffff169060200190929190803563ffffffff169060200190929190803563ffffffff169060200190929190505050611e88565b005b6105c761216c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6106756004803603606081101561061f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612192565b005b61067f6125b8565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156106c25780820151818401526020810190506106a7565b505050509050019250505060405180910390f35b6106de612646565b60405180826fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61072061266f565b005b61072a6128ab565b6040518082815260200191505060405180910390f35b61074861297b565b6040518082815260200191505060405180910390f35b610766612980565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6107b06129a6565b604051808263ffffffff1663ffffffff16815260200191505060405180910390f35b6107da6129bc565b604051808260ff1660ff16815260200191505060405180910390f35b6108386004803603602081101561080c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506129c9565b005b61087c6004803603602081101561085057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612c2c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6108c6612c98565b6040518082815260200191505060405180910390f35b6109b5600480360360408110156108f257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561092f57600080fd5b82018360208201111561094157600080fd5b8035906020019184600183028401116401000000008311171561096357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612d68565b604051808215151515815260200191505060405180910390f35b6109d7612db2565b604051808263ffffffff1663ffffffff16815260200191505060405180910390f35b610a01612dc8565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610a41578082015181840152602081019050610a26565b50505050905090810190601f168015610a6e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610a84612e66565b005b610a8e61302e565b6040518082815260200191505060405180910390f35b610aac613052565b005b610ab6613172565b6040518082815260200191505060405180910390f35b610b0e60048036036020811015610ae257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613242565b005b610b6260048036036040811015610b2657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803563ffffffff169060200190929190505050613415565b60405180891515151581526020018863ffffffff1663ffffffff1681526020018781526020018667ffffffffffffffff1667ffffffffffffffff1681526020018567ffffffffffffffff1667ffffffffffffffff168152602001846fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020018360ff1660ff168152602001826fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020019850505050505050505060405180910390f35b610c37613674565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610c81613699565b604051808269ffffffffffffffffffff1669ffffffffffffffffffff16815260200191505060405180910390f35b610ce760048036036020811015610cc557600080fd5b81019080803569ffffffffffffffffffff16906020019092919050505061386f565b604051808669ffffffffffffffffffff1669ffffffffffffffffffff1681526020018581526020018481526020018381526020018269ffffffffffffffffffff1669ffffffffffffffffffff1681526020019550505050505060405180910390f35b610d8b60048036036020811015610d5f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613954565b005b610e2e60048036036060811015610da357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610dea57600080fd5b820183602082011115610dfc57600080fd5b80359060200191846001830284011164010000000083111715610e1e57600080fd5b9091929391929390505050613b26565b005b610e5c60048036036020811015610e4657600080fd5b8101908080359060200190929190505050613bad565b6040518082815260200191505060405180910390f35b610e9e60048036036020811015610e8857600080fd5b8101908080359060200190929190505050613c80565b6040518082815260200191505060405180910390f35b610f0060048036036040811015610eca57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613d53565b005b610f0a614070565b60405180826fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610f4c614092565b604051808263ffffffff1663ffffffff16815260200191505060405180910390f35b610f766140a8565b60405180826fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610fb86140d1565b604051808215151515815260200191505060405180910390f35b61101460048036036020811015610fe857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506140e4565b6040518082815260200191505060405180910390f35b61108c6004803603604081101561104057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061415e565b005b6110d0600480360360208110156110a457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614394565b005b6110da614515565b604051808669ffffffffffffffffffff1669ffffffffffffffffffff1681526020018581526020018481526020018381526020018269ffffffffffffffffffff1669ffffffffffffffffffff1681526020019550505050505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146111fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b600e60009054906101000a900460ff161561125b576000600e60006101000a81548160ff0219169083151502179055507f3be8a977a014527b50ae38adda80b56911c267328965c98ddc385d248f53963860405160405180910390a15b565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461131f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146114155781600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fcfac5dc75b8d9a7e074162f59d9adcd33da59f0fe8dfb21580db298fc0fdad0d60405160405180910390a35b5050565b606061142533846145f7565b90507f00000000000000000000000000000000000000000000000000000000000000018212156114bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f76616c75652062656c6f77206d696e5375626d697373696f6e56616c7565000081525060200191505060405180910390fd5b7f0000000000000000000000000000000000000000033b2e3c9fd0803ce8000000821315611553576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f76616c75652061626f7665206d61785375626d697373696f6e56616c7565000081525060200191505060405180910390fd5b600081511481906115ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156115c45780820151818401526020810190506115a9565b50505050905090810190601f1680156115f15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506116098361496c565b6116138284614a86565b60008061161f85614c41565b9150915061162c85614e54565b611635856151b9565b81156116465761164585826152c1565b5b5050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461170f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b811515600b60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff161515141561176f57611921565b81156118355781600b60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff02191690831515021790555080600b60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160016101000a81548163ffffffff021916908363ffffffff1602179055506118ba565b600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080820160006101000a81549060ff02191690556000820160016101000a81549063ffffffff02191690556000820160056101000a81549063ffffffff021916905550505b8273ffffffffffffffffffffffffffffffffffffffff167fc3df5a754e002718f2e10804b99e6605e7c701d95cec9552c7680ca2b6f2820a838360405180831515151581526020018263ffffffff1663ffffffff1681526020019250505060405180910390a25b505050565b7f0000000000000000000000000000000000000000033b2e3c9fd0803ce800000081565b600560009054906101000a900460ff1681565b600460189054906101000a900463ffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611a35576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b6000611a3f6129bc565b60ff1690508463ffffffff168463ffffffff161015611ac6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f6d6178206d75737420657175616c2f657863656564206d696e0000000000000081525060200191505060405180910390fd5b8363ffffffff168163ffffffff161015611b48576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f6d61782063616e6e6f742065786365656420746f74616c00000000000000000081525060200191505060405180910390fd5b60008163ffffffff161480611b6857508263ffffffff168163ffffffff16115b611bda576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f64656c61792063616e6e6f742065786365656420746f74616c0000000000000081525060200191505060405180910390fd5b611bf5866fffffffffffffffffffffffffffffffff16615463565b600d60000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161015611c9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f696e73756666696369656e742066756e647320666f72207061796d656e74000081525060200191505060405180910390fd5b6000611ca76129bc565b60ff161115611d2d5760008563ffffffff1611611d2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f6d696e206d7573742062652067726561746572207468616e203000000000000081525060200191505060405180910390fd5b5b85600460006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555084600460146101000a81548163ffffffff021916908363ffffffff16021790555083600460106101000a81548163ffffffff021916908363ffffffff16021790555082600460186101000a81548163ffffffff021916908363ffffffff160217905550816004601c6101000a81548163ffffffff021916908363ffffffff1602179055508363ffffffff168563ffffffff16600460009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff167f56800c9d1ed723511246614d15e58cfcde15b6a33c245b5c961b689c1890fd8f8686604051808363ffffffff1663ffffffff1681526020018263ffffffff1663ffffffff1681526020019250505060405180910390a4505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f4a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b60008090505b89899050811015611f9957611f8c8a8a83818110611f6a57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1661549c565b8080600101915050611f50565b50848490508787905014612015576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f6e6565642073616d65206f7261636c6520616e642061646d696e20636f756e7481525060200191505060405180910390fd5b604d612037888890506120266129bc565b60ff166157e790919063ffffffff16565b11156120ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f6d6178206f7261636c657320616c6c6f7765640000000000000000000000000081525060200191505060405180910390fd5b60008090505b87879050811015612123576121168888838181106120cb57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff168787848181106120f457fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1661586f565b80806001019150506120b1565b50612161600460009054906101000a90046fffffffffffffffffffffffffffffffff168484846004601c9054906101000a900463ffffffff16611973565b505050505050505050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff16600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612295576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f6e6c792063616c6c61626c652062792061646d696e0000000000000000000081525060200191505060405180910390fd5b60008190506000600860008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a90046fffffffffffffffffffffffffffffffff169050816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161015612397576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f696e73756666696369656e7420776974686472617761626c652066756e64730081525060200191505060405180910390fd5b6123bc82826fffffffffffffffffffffffffffffffff16615de390919063ffffffff16565b600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555061247a82600d60000160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16615de390919063ffffffff16565b600d60000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85846fffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561257057600080fd5b505af1158015612584573d6000803e3d6000fd5b505050506040513d602081101561259a57600080fd5b81019080805190602001909291905050506125b157fe5b5050505050565b6060600c80548060200260200160405190810160405280929190818152602001828054801561263c57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116125f2575b5050505050905090565b6000600d60000160009054906101000a90046fffffffffffffffffffffffffffffffff16905090565b612677617e2e565b600d6040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16815250509050600061281e82602001516fffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156127d557600080fd5b505afa1580156127e9573d6000803e3d6000fd5b505050506040513d60208110156127ff57600080fd5b8101908080519060200190929190505050615e9090919063ffffffff16565b90508082600001516fffffffffffffffffffffffffffffffff16146128a75780600d60000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550807ffe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234f60405160405180910390a25b5050565b60006128fc336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612d68565b61296e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260098152602001807f4e6f20616363657373000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b612976615f19565b905090565b600381565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460109054906101000a900463ffffffff1681565b6000600c80549050905090565b3373ffffffffffffffffffffffffffffffffffffffff16600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612acc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f6f6e6c792063616c6c61626c652062792070656e64696e672061646d696e000081525060200191505060405180910390fd5b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555033600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160026101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f0c5055390645c15a4be9a21b3f8d019153dcb4a0c125685da6eb84048e2fe90460405160405180910390a350565b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160029054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000612ce9336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612d68565b612d5b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260098152602001807f4e6f20616363657373000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b612d63615f55565b905090565b6000612d748383615f75565b80612daa57503273ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b905092915050565b6004601c9054906101000a900463ffffffff1681565b60068054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015612e5e5780601f10612e3357610100808354040283529160200191612e5e565b820191906000526020600020905b815481529060010190602001808311612e4157829003601f168201915b505050505081565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612f29576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4d7573742062652070726f706f736564206f776e65720000000000000000000081525060200191505060405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a350565b7f000000000000000000000000000000000000000000000000000000000000000181565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613114576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b600e60009054906101000a900460ff16613170576001600e60006101000a81548160ff0219169083151502179055507faebf329500988c6488a0074e5a0a9ff304561fc5c6fc877aeb1d59c8282c348060405160405180910390a15b565b60006131c3336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612d68565b613235576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260098152602001807f4e6f20616363657373000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61323d615fe4565b905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613304576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b600f60008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615613412576000600f60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f3d68a6fce901d20453d1a7aa06bf3950302a735948037deb182a8db66df2a0d181604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b50565b6000806000806000806000803273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146134c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f66662d636861696e2072656164696e67206f6e6c790000000000000000000081525060200191505060405180910390fd5b60008963ffffffff16111561364d576000600960008b63ffffffff1663ffffffff16815260200190815260200160002090506000600a60008c63ffffffff1663ffffffff16815260200190815260200160002090506135218c8c61603e565b8b600860008f73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101548460010160009054906101000a900467ffffffffffffffff168460010160089054906101000a900463ffffffff16600d60000160009054906101000a90046fffffffffffffffffffffffffffffffff166135bd6129bc565b60008960010160009054906101000a900467ffffffffffffffff1667ffffffffffffffff161161360b57600460009054906101000a90046fffffffffffffffffffffffffffffffff1661362d565b87600101600c9054906101000a90046fffffffffffffffffffffffffffffffff165b8363ffffffff169350995099509950995099509950995099505050613667565b6136568a6160d7565b975097509750975097509750975097505b9295985092959890939650565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1661375d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f6e6f7420617574686f72697a656420726571756573746572000000000000000081525060200191505060405180910390fd5b6000600760009054906101000a900463ffffffff1690506000600960008363ffffffff1663ffffffff16815260200190815260200160002060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff1611806137c857506137c781616388565b5b61383a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f7072657620726f756e64206d75737420626520737570657273656461626c650081525060200191505060405180910390fd5b600061385660018363ffffffff1661645b90919063ffffffff16565b9050613861816164ef565b8063ffffffff169250505090565b60008060008060006138c6336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612d68565b613938576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260098152602001807f4e6f20616363657373000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b613941866166ad565b9450945094509450945091939590929450565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613a16576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b600f60008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16613b23576001600f60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db481604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b50565b60008282905014613b9f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f7472616e7366657220646f65736e2774206163636570742063616c6c6461746181525060200191505060405180910390fd5b613ba761266f565b50505050565b6000613bfe336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612d68565b613c70576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260098152602001807f4e6f20616363657373000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b613c79826168d1565b9050919050565b6000613cd1336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612d68565b613d43576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260098152602001807f4e6f20616363657373000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b613d4c82616915565b9050919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613e15576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b6000600d60000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16905081613e99613e8a600460009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16615463565b83615e9090919063ffffffff16565b1015613f0d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f696e73756666696369656e7420726573657276652066756e647300000000000081525060200191505060405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015613fb657600080fd5b505af1158015613fca573d6000803e3d6000fd5b505050506040513d6020811015613fe057600080fd5b8101908080519060200190929190505050614063576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f746f6b656e207472616e73666572206661696c6564000000000000000000000081525060200191505060405180910390fd5b61406b61266f565b505050565b600460009054906101000a90046fffffffffffffffffffffffffffffffff1681565b600460149054906101000a900463ffffffff1681565b6000600d60000160109054906101000a90046fffffffffffffffffffffffffffffffff16905090565b600e60009054906101000a900460ff1681565b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff169050919050565b3373ffffffffffffffffffffffffffffffffffffffff16600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614261576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f6e6c792063616c6c61626c652062792061646d696e0000000000000000000081525060200191505060405180910390fd5b80600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff167fb79bf2e89c2d70dde91d2991fb1ea69b7e478061ad7c04ed5b02b96bc52b81043383604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a25050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614456576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000081525060200191505060405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127860405160405180910390a350565b600080600080600061456c336000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612d68565b6145de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260098152602001807f4e6f20616363657373000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6145e6616977565b945094509450945094509091929394565b60606000600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160109054906101000a900463ffffffff1690506000600760009054906101000a900463ffffffff16905060008263ffffffff1614156146b5576040518060400160405280601281526020017f6e6f7420656e61626c6564206f7261636c65000000000000000000000000000081525092505050614966565b8363ffffffff168263ffffffff161115614708576040518060400160405280601681526020017f6e6f742079657420656e61626c6564206f7261636c650000000000000000000081525092505050614966565b8363ffffffff16600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160149054906101000a900463ffffffff1663ffffffff1610156147ad576040518060400160405280601881526020017f6e6f206c6f6e67657220616c6c6f776564206f7261636c65000000000000000081525092505050614966565b8363ffffffff16600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160189054906101000a900463ffffffff1663ffffffff1610614851576040518060400160405280602081526020017f63616e6e6f74207265706f7274206f6e2070726576696f757320726f756e647381525092505050614966565b8063ffffffff168463ffffffff1614158015614892575061488260018263ffffffff1661645b90919063ffffffff16565b63ffffffff168463ffffffff1614155b80156148a557506148a384826169b1565b155b156148e9576040518060400160405280601781526020017f696e76616c696420726f756e6420746f207265706f727400000000000000000081525092505050614966565b60018463ffffffff161415801561491f575061491d61491860018663ffffffff16616a2f90919063ffffffff16565b616ac4565b155b15614963576040518060400160405280601f81526020017f70726576696f757320726f756e64206e6f7420737570657273656461626c650081525092505050614966565b50505b92915050565b61497581616b20565b61497e57614a83565b6000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001601c9054906101000a900463ffffffff1663ffffffff169050600460189054906101000a900463ffffffff1663ffffffff1681018263ffffffff1611158015614a0c575060008114155b15614a175750614a83565b614a2082616b63565b81600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001601c6101000a81548163ffffffff021916908363ffffffff160217905550505b50565b614a8f81616e6c565b614b01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f726f756e64206e6f7420616363657074696e67207375626d697373696f6e730081525060200191505060405180910390fd5b600a60008263ffffffff1663ffffffff16815260200190815260200160002060000182908060018154018082558091505060019003906000526020600020016000909190919091505580600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160186101000a81548163ffffffff021916908363ffffffff16021790555081600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055503373ffffffffffffffffffffffffffffffffffffffff168163ffffffff16837f92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c60405160405180910390a45050565b600080600a60008463ffffffff1663ffffffff16815260200190815260200160002060010160049054906101000a900463ffffffff1663ffffffff16600a60008563ffffffff1663ffffffff168152602001908152602001600020600001805490501015614cb85760008080905091509150614e4f565b6000614d33600a60008663ffffffff1663ffffffff168152602001908152602001600020600001805480602002602001604051908101604052809291908181526020018280548015614d2957602002820191906000526020600020905b815481526020019060010190808311614d15575b5050505050616eb1565b905080600960008663ffffffff1663ffffffff1681526020019081526020016000206000018190555042600960008663ffffffff1663ffffffff16815260200190815260200160002060010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555083600960008663ffffffff1663ffffffff16815260200190815260200160002060010160106101000a81548163ffffffff021916908363ffffffff16021790555083600760046101000a81548163ffffffff021916908363ffffffff1602179055508363ffffffff16817f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f426040518082815260200191505060405180910390a360018192509250505b915091565b6000600a60008363ffffffff1663ffffffff168152602001908152602001600020600101600c9054906101000a90046fffffffffffffffffffffffffffffffff169050614e9f617e2e565b600d6040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16815250509050614f6b8282600001516fffffffffffffffffffffffffffffffff16615de390919063ffffffff16565b81600001906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff1681525050614fc38282602001516fffffffffffffffffffffffffffffffff16616fa090919063ffffffff16565b81602001906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff168152505080600d60008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055509050506150f982600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16616fa090919063ffffffff16565b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555080600001516fffffffffffffffffffffffffffffffff167ffe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234f60405160405180910390a2505050565b600a60008263ffffffff1663ffffffff16815260200190815260200160002060010160009054906101000a900463ffffffff1663ffffffff16600a60008363ffffffff1663ffffffff168152602001908152602001600020600001805490501015615223576152be565b600a60008263ffffffff1663ffffffff168152602001908152602001600020600080820160006152539190617e6c565b6001820160006101000a81549063ffffffff02191690556001820160046101000a81549063ffffffff02191690556001820160086101000a81549063ffffffff021916905560018201600c6101000a8154906fffffffffffffffffffffffffffffffff021916905550505b50565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415615323575061545f565b600061533f60018563ffffffff16616a2f90919063ffffffff16565b90506000600960008363ffffffff1663ffffffff16815260200190815260200160002060010160109054906101000a900463ffffffff1690506000600960008463ffffffff1663ffffffff1681526020019081526020016000206000015490508373ffffffffffffffffffffffffffffffffffffffff1663beed9b51620186a084848a8a6040518663ffffffff1660e01b8152600401808563ffffffff1681526020018481526020018363ffffffff168152602001828152602001945050505050602060405180830381600088803b15801561541a57600080fd5b5087f19350505050801561544f57506040513d602081101561543b57600080fd5b810190808051906020019092919050505060015b6154585761545a565b505b505050505b5050565b600061549560026154876154756129bc565b60ff168561704c90919063ffffffff16565b61704c90919063ffffffff16565b9050919050565b6154a5816170d2565b615517576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f6f7261636c65206e6f7420656e61626c6564000000000000000000000000000081525060200191505060405180910390fd5b6155436001600760009054906101000a900463ffffffff1663ffffffff1661645b90919063ffffffff16565b600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff1602179055506000600c6155c560016155b46129bc565b60ff16615e9090919063ffffffff16565b815481106155cf57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160009054906101000a900461ffff16905080600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160006101000a81548161ffff021916908361ffff160217905550600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160006101000a81549061ffff021916905581600c8261ffff168154811061571357fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600c80548061576657fe5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690559055600015158373ffffffffffffffffffffffffffffffffffffffff167f18dd09695e4fbdae8d1a5edb11221eb04564269c29a089b9753a6535c54ba92e60405160405180910390a3505050565b600080828401905083811015615865576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b615878826170d2565b156158eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6f7261636c6520616c726561647920656e61626c65640000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561598e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f63616e6e6f74207365742061646d696e20746f2030000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161480615ab857508073ffffffffffffffffffffffffffffffffffffffff16600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b615b2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f6f776e65722063616e6e6f74206f76657277726974652061646d696e0000000081525060200191505060405180910390fd5b615b338261713c565b600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160106101000a81548163ffffffff021916908363ffffffff16021790555063ffffffff600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a81548163ffffffff021916908363ffffffff160217905550600c80549050600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160006101000a81548161ffff021916908361ffff160217905550600c829080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160026101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600115158273ffffffffffffffffffffffffffffffffffffffff167f18dd09695e4fbdae8d1a5edb11221eb04564269c29a089b9753a6535c54ba92e60405160405180910390a38073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f0c5055390645c15a4be9a21b3f8d019153dcb4a0c125685da6eb84048e2fe90460405160405180910390a35050565b6000826fffffffffffffffffffffffffffffffff16826fffffffffffffffffffffffffffffffff161115615e7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b600082840390508091505092915050565b600082821115615f08576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b600082840390508091505092915050565b600060096000600760049054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200190815260200160002060000154905090565b6000600760049054906101000a900463ffffffff1663ffffffff16905090565b6000600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1680615fdc5750600e60009054906101000a900460ff16155b905092915050565b600060096000600760049054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200190815260200160002060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff16905090565b600080600960008463ffffffff1663ffffffff16815260200190815260200160002060010160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1611156160ae5761609182616e6c565b80156160a7575060006160a484846145f7565b51145b90506160d1565b6160b883836171f9565b80156160ce575060006160cb84846145f7565b51145b90505b92915050565b6000806000806000806000806000600960008063ffffffff16815260200190815260200160002090506000600860008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000600760009054906101000a900463ffffffff1663ffffffff168260000160189054906101000a900463ffffffff1663ffffffff16148061619d575061619b600760009054906101000a900463ffffffff16616e6c565b155b90506161ba600760009054906101000a900463ffffffff16616ac4565b80156161c35750805b15616249576161f46001600760009054906101000a900463ffffffff1663ffffffff1661645b90919063ffffffff16565b9950600960008b63ffffffff1663ffffffff1681526020019081526020016000209250600460009054906101000a90046fffffffffffffffffffffffffffffffff1693506162428c8b6171f9565b9a506162cc565b600760009054906101000a900463ffffffff169950600960008b63ffffffff1663ffffffff1681526020019081526020016000209250600a60008b63ffffffff1663ffffffff168152602001908152602001600020600101600c9054906101000a90046fffffffffffffffffffffffffffffffff1693506162c98a616e6c565b9a505b60006162d88d8c6145f7565b51146162e35760009a505b8a8a83600101548560010160009054906101000a900467ffffffffffffffff16600a60008f63ffffffff1663ffffffff16815260200190815260200160002060010160089054906101000a900463ffffffff16600d60000160009054906101000a90046fffffffffffffffffffffffffffffffff166163606129bc565b8a8363ffffffff1693509a509a509a509a509a509a509a509a50505050919395975091939597565b600080600960008463ffffffff1663ffffffff16815260200190815260200160002060010160009054906101000a900467ffffffffffffffff1690506000600a60008563ffffffff1663ffffffff16815260200190815260200160002060010160089054906101000a900463ffffffff16905060008267ffffffffffffffff1611801561641b575060008163ffffffff16115b80156164525750426164468263ffffffff168467ffffffffffffffff1661728e90919063ffffffff16565b67ffffffffffffffff16105b92505050919050565b60008082840190508363ffffffff168163ffffffff1610156164e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b6164f881616b20565b616501576166aa565b6000600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160059054906101000a900463ffffffff1663ffffffff169050600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160019054906101000a900463ffffffff1663ffffffff1681018263ffffffff1611806165cc5750600081145b61663e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f6d7573742064656c61792072657175657374730000000000000000000000000081525060200191505060405180910390fd5b61664782616b63565b81600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160056101000a81548163ffffffff021916908363ffffffff160217905550505b50565b60008060008060006166bd617e8d565b600960008863ffffffff1663ffffffff168152602001908152602001600020604051806080016040529081600082015481526020016001820160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020016001820160089054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020016001820160109054906101000a900463ffffffff1663ffffffff1663ffffffff168152505090506000816060015163ffffffff161180156167a857506167a78769ffffffffffffffffffff1661732a565b5b6040518060400160405280600f81526020017f4e6f20646174612070726573656e74000000000000000000000000000000000081525090616884576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561684957808201518184015260208101905061682e565b50505050905090810190601f1680156168765780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b508681600001518260200151836040015184606001518267ffffffffffffffff1692508167ffffffffffffffff1691508063ffffffff169050955095509550955095505091939590929450565b60006168dc8261732a565b1561690b57600960008363ffffffff1663ffffffff168152602001908152602001600020600001549050616910565b600090505b919050565b60006169208261732a565b1561696d57600960008363ffffffff1663ffffffff16815260200190815260200160002060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff169050616972565b600090505b919050565b60008060008060006169a0600760049054906101000a900463ffffffff1663ffffffff1661386f565b945094509450945094509091929394565b60008163ffffffff166169d460018563ffffffff1661645b90919063ffffffff16565b63ffffffff16148015616a2757506000600960008463ffffffff1663ffffffff16815260200190815260200160002060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff16145b905092915050565b60008263ffffffff168263ffffffff161115616ab3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b600082840390508091505092915050565b600080600960008463ffffffff1663ffffffff16815260200190815260200160002060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff161180616b195750616b1882616388565b5b9050919050565b6000616b4e6001600760009054906101000a900463ffffffff1663ffffffff1661645b90919063ffffffff16565b63ffffffff168263ffffffff16149050919050565b616b85616b8060018363ffffffff16616a2f90919063ffffffff16565b61733d565b80600760006101000a81548163ffffffff021916908363ffffffff160217905550616bae617ecf565b6040518060a00160405280600067ffffffffffffffff81118015616bd157600080fd5b50604051908082528060200260200182016040528015616c005781602001602082028036833780820191505090505b508152602001600460109054906101000a900463ffffffff1663ffffffff168152602001600460149054906101000a900463ffffffff1663ffffffff1681526020016004601c9054906101000a900463ffffffff1663ffffffff168152602001600460009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16815250905080600a60008463ffffffff1663ffffffff1681526020019081526020016000206000820151816000019080519060200190616cd2929190617f22565b5060208201518160010160006101000a81548163ffffffff021916908363ffffffff16021790555060408201518160010160046101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160086101000a81548163ffffffff021916908363ffffffff160217905550608082015181600101600c6101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555090505042600960008463ffffffff1663ffffffff16815260200190815260200160002060010160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff168263ffffffff167f0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271600960008663ffffffff1663ffffffff16815260200190815260200160002060010160009054906101000a900467ffffffffffffffff16604051808267ffffffffffffffff16815260200191505060405180910390a35050565b600080600a60008463ffffffff1663ffffffff16815260200190815260200160002060010160009054906101000a900463ffffffff1663ffffffff1614159050919050565b60008151600010616f2a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f6c697374206d757374206e6f7420626520656d7074790000000000000000000081525060200191505060405180910390fd5b600082519050600060028281616f3c57fe5b049050600060028381616f4b57fe5b061415616f8657600080616f69866000600187036001870387617511565b8092508193505050616f7b82826175fe565b945050505050616f9b565b616f96846000600185038461769b565b925050505b919050565b6000808284019050836fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161015617042576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60008083141561705f57600090506170cc565b600082840290508284828161707057fe5b04146170c7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180617fb66021913960400191505060405180910390fd5b809150505b92915050565b600063ffffffff8016600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160149054906101000a900463ffffffff1663ffffffff16149050919050565b600080600760009054906101000a900463ffffffff16905060008163ffffffff16141580156171c85750600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160149054906101000a900463ffffffff1663ffffffff168163ffffffff16145b156171d657809150506171f4565b6171f060018263ffffffff1661645b90919063ffffffff16565b9150505b919050565b600080600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001601c9054906101000a900463ffffffff1663ffffffff169050600460189054906101000a900463ffffffff1663ffffffff1681018363ffffffff1611806172855750600081145b91505092915050565b60008082840190508367ffffffffffffffff168167ffffffffffffffff161015617320576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600063ffffffff80168211159050919050565b61734681616388565b61734f5761750e565b600061736b60018363ffffffff16616a2f90919063ffffffff16565b9050600960008263ffffffff1663ffffffff16815260200190815260200160002060000154600960008463ffffffff1663ffffffff16815260200190815260200160002060000181905550600960008263ffffffff1663ffffffff16815260200190815260200160002060010160109054906101000a900463ffffffff16600960008463ffffffff1663ffffffff16815260200190815260200160002060010160106101000a81548163ffffffff021916908363ffffffff16021790555042600960008463ffffffff1663ffffffff16815260200190815260200160002060010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600a60008363ffffffff1663ffffffff168152602001908152602001600020600080820160006174a29190617e6c565b6001820160006101000a81549063ffffffff02191690556001820160046101000a81549063ffffffff02191690556001820160086101000a81549063ffffffff021916905560018201600c6101000a8154906fffffffffffffffffffffffffffffffff02191690555050505b50565b60008082841061752057600080fd5b8386111580156175305750848411155b61753957600080fd5b8286111580156175495750848311155b61755257600080fd5b5b6001156175f3576007868603101561757b576175728787878787617735565b915091506175f4565b6000617588888888617ca9565b9050808411617599578095506175ed565b848110156175ac576001810196506175ec565b8085111580156175bb57508381105b6175c157fe5b6175cd8888838861769b565b92506175de8860018301888761769b565b9150828292509250506175f4565b5b50617553565b5b9550959350505050565b6000808312801561760f5750600082135b8061762657506000831380156176255750600082125b5b156176465760026176378484617da0565b8161763e57fe5b059050617695565b6000600280848161765357fe5b076002868161765e57fe5b07018161766757fe5b05905061769161768b6002868161767a57fe5b056002868161768557fe5b05617da0565b82617da0565b9150505b92915050565b6000818411156176aa57600080fd5b828211156176b757600080fd5b5b8284101561771657600784840310156176eb5760006176da8686868687617735565b80925081935050508191505061772d565b60006176f8868686617ca9565b905080831161770957809350617710565b6001810194505b506176b8565b84848151811061772257fe5b602002602001015190505b949350505050565b60008060008660018701039050600088600089018151811061775357fe5b6020026020010151905060008260011061778d577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6177a5565b8960018a018151811061779c57fe5b60200260200101515b90506000836002106177d7577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6177ef565b8a60028b01815181106177e657fe5b60200260200101515b9050600084600310617821577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff617839565b8b60038c018151811061783057fe5b60200260200101515b905060008560041061786b577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff617883565b8c60048d018151811061787a57fe5b60200260200101515b90506000866005106178b5577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6178cd565b8d60058e01815181106178c457fe5b60200260200101515b90506000876006106178ff577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff617917565b8e60068f018151811061790e57fe5b60200260200101515b90508587131561792c57858780975081985050505b8385131561793f57838580955081965050505b8183131561795257818380935081945050505b8487131561796557848780965081985050505b8386131561797857838680955081975050505b8083131561798b57808380925081945050505b8486131561799e57848680965081975050505b808213156179b157808280925081935050505b828713156179c457828780945081985050505b818613156179d757818680935081975050505b808513156179ea57808580925081965050505b828613156179fd57828680945081975050505b80841315617a1057808480925081955050505b82851315617a2357828580945081965050505b81841315617a3657818480935081955050505b82841315617a4957828480945081955050505b60008e8d0390506000811415617a6157879a50617b3b565b6001811415617a7257869a50617b3a565b6002811415617a8357859a50617b39565b6003811415617a9457849a50617b38565b6004811415617aa557839a50617b37565b6005811415617ab657829a50617b36565b6006811415617ac757819a50617b35565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f6b31206f7574206f6620626f756e64730000000000000000000000000000000081525060200191505060405180910390fd5b5b5b5b5b5b5b60008f8d0390508c8e1415617b5f578b8c9b509b5050505050505050505050617c9f565b6000811415617b7d578b899b509b5050505050505050505050617c9f565b6001811415617b9b578b889b509b5050505050505050505050617c9f565b6002811415617bb9578b879b509b5050505050505050505050617c9f565b6003811415617bd7578b869b509b5050505050505050505050617c9f565b6004811415617bf5578b859b509b5050505050505050505050617c9f565b6005811415617c13578b849b509b5050505050505050505050617c9f565b6006811415617c31578b839b509b5050505050505050505050617c9f565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f6b32206f7574206f6620626f756e64730000000000000000000000000000000081525060200191505060405180910390fd5b9550959350505050565b60008084600284860181617cb957fe5b0481518110617cc457fe5b602002602001015190506001840393506001830192505b600115617d97575b60018401935080858581518110617cf657fe5b602002602001015112617ce3575b60018303925080858481518110617d1757fe5b602002602001015113617d045782841015617d8957848381518110617d3857fe5b6020026020010151858581518110617d4c57fe5b6020026020010151868681518110617d6057fe5b60200260200101878681518110617d7357fe5b6020026020010182815250828152505050617d92565b82915050617d99565b617cdb565b505b9392505050565b600080828401905060008312158015617db95750838112155b80617dcf5750600083128015617dce57508381125b5b617e24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180617f956021913960400191505060405180910390fd5b8091505092915050565b604051806040016040528060006fffffffffffffffffffffffffffffffff16815260200160006fffffffffffffffffffffffffffffffff1681525090565b5080546000825590600052602060002090810190617e8a9190617f6f565b50565b604051806080016040528060008152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600063ffffffff1681525090565b6040518060a0016040528060608152602001600063ffffffff168152602001600063ffffffff168152602001600063ffffffff16815260200160006fffffffffffffffffffffffffffffffff1681525090565b828054828255906000526020600020908101928215617f5e579160200282015b82811115617f5d578251825591602001919060010190617f42565b5b509050617f6b9190617f6f565b5090565b617f9191905b80821115617f8d576000816000905550600101617f75565b5090565b9056fe5369676e6564536166654d6174683a206164646974696f6e206f766572666c6f77536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a26469706673582212203a648420c98021dfe39787881be80ceea9e624f98cad1e6c764135615d564fc064736f6c63430006060033