Contract Overview
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0xcd3ee5e7de07fca4d7171140a0d80ab0fed437f2
Contract Name:
AccessControlledAggregator
Compiler Version
v0.6.6+commit.6c089d02
Contract Source Code (Solidity)
/** *Submitted for verification at polygonscan.com on 2021-08-24 */ // Sources flattened with hardhat v2.4.3 https://hardhat.org // File v3.sol /** *Submitted for verification at Etherscan.io on 2020-10-16 */ pragma solidity 0.6.6; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { 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; } } 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); } } 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; } } /** * @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"); _; } } /** * @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; } } /** * @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; } } /** * @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; } } 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); } 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 ); } interface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface { } interface AggregatorValidatorInterface { function validate( uint256 previousRoundId, int256 previousAnswer, uint256 currentRoundId, int256 currentAnswer ) external returns (bool); } 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); } /** * @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 SafeMath 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 view returns (bool) { return _roundId <= ROUND_MAX; } } interface AccessControllerInterface { function hasAccess(address user, bytes calldata data) external view returns (bool); } /** * @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"); _; } } /** * @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; } } /** * @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); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_link","type":"address"},{"internalType":"uint128","name":"_paymentAmount","type":"uint128"},{"internalType":"uint32","name":"_timeout","type":"uint32"},{"internalType":"address","name":"_validator","type":"address"},{"internalType":"int256","name":"_minSubmissionValue","type":"int256"},{"internalType":"int256","name":"_maxSubmissionValue","type":"int256"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"string","name":"_description","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"}],"name":"AddedAccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"int256","name":"current","type":"int256"},{"indexed":true,"internalType":"uint256","name":"roundId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"updatedAt","type":"uint256"}],"name":"AnswerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AvailableFundsUpdated","type":"event"},{"anonymous":false,"inputs":[],"name":"CheckAccessDisabled","type":"event"},{"anonymous":false,"inputs":[],"name":"CheckAccessEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"roundId","type":"uint256"},{"indexed":true,"internalType":"address","name":"startedBy","type":"address"},{"indexed":false,"internalType":"uint256","name":"startedAt","type":"uint256"}],"name":"NewRound","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oracle","type":"address"},{"indexed":false,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"OracleAdminUpdateRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oracle","type":"address"},{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"}],"name":"OracleAdminUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oracle","type":"address"},{"indexed":true,"internalType":"bool","name":"whitelisted","type":"bool"}],"name":"OraclePermissionsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"}],"name":"RemovedAccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"requester","type":"address"},{"indexed":false,"internalType":"bool","name":"authorized","type":"bool"},{"indexed":false,"internalType":"uint32","name":"delay","type":"uint32"}],"name":"RequesterPermissionsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint128","name":"paymentAmount","type":"uint128"},{"indexed":true,"internalType":"uint32","name":"minSubmissionCount","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"maxSubmissionCount","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"restartDelay","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"timeout","type":"uint32"}],"name":"RoundDetailsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"int256","name":"submission","type":"int256"},{"indexed":true,"internalType":"uint32","name":"round","type":"uint32"},{"indexed":true,"internalType":"address","name":"oracle","type":"address"}],"name":"SubmissionReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previous","type":"address"},{"indexed":true,"internalType":"address","name":"current","type":"address"}],"name":"ValidatorUpdated","type":"event"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"}],"name":"acceptAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"addAccess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"allocatedFunds","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"availableFunds","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_removed","type":"address[]"},{"internalType":"address[]","name":"_added","type":"address[]"},{"internalType":"address[]","name":"_addedAdmins","type":"address[]"},{"internalType":"uint32","name":"_minSubmissions","type":"uint32"},{"internalType":"uint32","name":"_maxSubmissions","type":"uint32"},{"internalType":"uint32","name":"_restartDelay","type":"uint32"}],"name":"changeOracles","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"checkEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disableAccessCheck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableAccessCheck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"}],"name":"getAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_roundId","type":"uint256"}],"name":"getAnswer","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOracles","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint80","name":"_roundId","type":"uint80"}],"name":"getRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_roundId","type":"uint256"}],"name":"getTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"hasAccess","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestAnswer","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRound","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"linkToken","outputs":[{"internalType":"contract LinkTokenInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSubmissionCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSubmissionValue","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minSubmissionCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minSubmissionValue","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"onTokenTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"oracleCount","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"uint32","name":"_queriedRoundId","type":"uint32"}],"name":"oracleRoundState","outputs":[{"internalType":"bool","name":"_eligibleToSubmit","type":"bool"},{"internalType":"uint32","name":"_roundId","type":"uint32"},{"internalType":"int256","name":"_latestSubmission","type":"int256"},{"internalType":"uint64","name":"_startedAt","type":"uint64"},{"internalType":"uint64","name":"_timeout","type":"uint64"},{"internalType":"uint128","name":"_availableFunds","type":"uint128"},{"internalType":"uint8","name":"_oracleCount","type":"uint8"},{"internalType":"uint128","name":"_paymentAmount","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paymentAmount","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"removeAccess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requestNewRound","outputs":[{"internalType":"uint80","name":"","type":"uint80"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"restartDelay","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_requester","type":"address"},{"internalType":"bool","name":"_authorized","type":"bool"},{"internalType":"uint32","name":"_delay","type":"uint32"}],"name":"setRequesterPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newValidator","type":"address"}],"name":"setValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_roundId","type":"uint256"},{"internalType":"int256","name":"_submission","type":"int256"}],"name":"submit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"timeout","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"address","name":"_newAdmin","type":"address"}],"name":"transferAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateAvailableFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"_paymentAmount","type":"uint128"},{"internalType":"uint32","name":"_minSubmissions","type":"uint32"},{"internalType":"uint32","name":"_maxSubmissions","type":"uint32"},{"internalType":"uint32","name":"_restartDelay","type":"uint32"},{"internalType":"uint32","name":"_timeout","type":"uint32"}],"name":"updateFutureRounds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"validator","outputs":[{"internalType":"contract AggregatorValidatorInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawPayment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"}],"name":"withdrawablePayment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60c06040523480156200001157600080fd5b50604051620068b8380380620068b883398181016040526101008110156200003857600080fd5b815160208301516040808501516060860151608087015160a088015160c089015160e08a0180519651989a9799959894979396929591949391820192846401000000008211156200008857600080fd5b9083019060208201858111156200009e57600080fd5b8251640100000000811182820188101715620000b957600080fd5b82525081516020918201929091019080838360005b83811015620000e8578181015183820152602001620000ce565b50505050905090810190601f168015620001165780820380516001836020036101000a031916815260200191505b50604052505060008054336001600160a01b0319918216178255600280549091166001600160a01b038c1617905589915088908890889088908890889088906200016590889080808a62000244565b62000179856001600160e01b036200062216565b608084905260a08390526005805460ff191660ff84161790558051620001a790600690602084019062000806565b50620001c88663ffffffff1642620006ec60201b620045e91790919060201c565b6000805260096020527fec8156718a8372b1db44bb411437d0870f3e3790d4a08526d024ce1b0b668f6c80546001600160401b03929092166801000000000000000002600160401b600160801b03199092169190911790555050600e805460ff1916600117905550620008a89c50505050505050505050505050565b6000546001600160a01b03163314620002a4576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b6000620002b96001600160e01b036200074f16565b60ff1690508463ffffffff168463ffffffff16101562000320576040805162461bcd60e51b815260206004820152601960248201527f6d6178206d75737420657175616c2f657863656564206d696e00000000000000604482015290519081900360640190fd5b8363ffffffff168163ffffffff16101562000382576040805162461bcd60e51b815260206004820152601760248201527f6d61782063616e6e6f742065786365656420746f74616c000000000000000000604482015290519081900360640190fd5b63ffffffff81161580620003a157508263ffffffff168163ffffffff16115b620003f3576040805162461bcd60e51b815260206004820152601960248201527f64656c61792063616e6e6f742065786365656420746f74616c00000000000000604482015290519081900360640190fd5b620004106001600160801b0387166001600160e01b036200075616565b600d546001600160801b0316101562000470576040805162461bcd60e51b815260206004820152601e60248201527f696e73756666696369656e742066756e647320666f72207061796d656e740000604482015290519081900360640190fd5b6000620004856001600160e01b036200074f16565b60ff161115620004eb5760008563ffffffff1611620004eb576040805162461bcd60e51b815260206004820152601a60248201527f6d696e206d7573742062652067726561746572207468616e2030000000000000604482015290519081900360640190fd5b85600460006101000a8154816001600160801b0302191690836001600160801b0316021790555084600460146101000a81548163ffffffff021916908363ffffffff16021790555083600460106101000a81548163ffffffff021916908363ffffffff16021790555082600460186101000a81548163ffffffff021916908363ffffffff160217905550816004601c6101000a81548163ffffffff021916908363ffffffff1602179055508363ffffffff168563ffffffff16600460009054906101000a90046001600160801b03166001600160801b03167f56800c9d1ed723511246614d15e58cfcde15b6a33c245b5c961b689c1890fd8f8686604051808363ffffffff1663ffffffff1681526020018263ffffffff1663ffffffff1681526020019250505060405180910390a4505050505050565b6000546001600160a01b0316331462000682576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b6003546001600160a01b039081169082168114620006e857600380546001600160a01b0319166001600160a01b0384811691821790925560405190918316907fcfac5dc75b8d9a7e074162f59d9adcd33da59f0fe8dfb21580db298fc0fdad0d90600090a35b5050565b60008282111562000744576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b508082035b92915050565b600c545b90565b60006200074960026200078d620007756001600160e01b036200074f16565b60ff1685620007a160201b620052fd1790919060201c565b620007a160201b620052fd1790919060201c565b600082620007b25750600062000749565b82820282848281620007c057fe5b0414620007ff5760405162461bcd60e51b8152600401808060200182810382526021815260200180620068976021913960400191505060405180910390fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200084957805160ff191683800117855562000879565b8280016001018555821562000879579182015b82811115620008795782518255916020019190600101906200085c565b50620008879291506200088b565b5090565b6200075391905b8082111562000887576000815560010162000892565b60805160a051615fc1620008d660003980610ec55280611238525080610e3652806123e15250615fc16000f3fe608060405234801561001057600080fd5b50600436106103155760003560e01c806370dea79a116101a7578063a4c0ed36116100ee578063d4cc54e411610097578063e9ee6eeb11610071578063e9ee6eeb14610baa578063f2fde38b14610be5578063feaf968c14610c1857610315565b8063d4cc54e414610b67578063dc7f012414610b6f578063e2e4031714610b7757610315565b8063c1075329116100c8578063c107532914610b1e578063c35905c614610b57578063c937450014610b5f57610315565b8063a4c0ed3614610a52578063b5ab58dc14610ae4578063b633620c14610b0157610315565b80638823da6c1161015057806398e5b12a1161012a57806398e5b12a146109905780639a6fc8f5146109b7578063a118f24914610a1f57610315565b80638823da6c146108ac57806388aa80e7146108df5780638da5cb5b1461098857610315565b80637c2b0b21116101815780637c2b0b21146108945780638038e4a11461089c5780638205bf6a146108a457610315565b806370dea79a146108075780637284e4161461080f57806379ba50971461088c57610315565b806340884c521161026b57806358609e441161021457806364efb22b116101ee57806364efb22b146106f5578063668a0f02146107285780636b14daf81461073057610315565b806358609e44146106b2578063613d8fcc146106ba578063628806ef146106c257610315565b806350d25bcd1161024557806350d25bcd1461069a57806354fd4d50146106a257806357970e93146106aa57610315565b806340884c521461060d57806346fcff4c146106655780634f8fc3b51461069257610315565b8063313ce567116102cd5780633969c20f116102a75780633969c20f1461046d5780633a5381b5146105995780633d3d7714146105ca57610315565b8063313ce567146103db578063357ebb02146103f957806338aa4c721461041a57610315565b8063202ee0ed116102fe578063202ee0ed1461035757806320ed02751461037a57806323ca2903146103c157610315565b80630a7569831461031a5780631327d3d814610324575b600080fd5b610322610c20565b005b6103226004803603602081101561033a57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610d05565b6103226004803603604081101561036d57600080fd5b5080359060200135610e26565b6103226004803603606081101561039057600080fd5b50803573ffffffffffffffffffffffffffffffffffffffff169060208101351515906040013563ffffffff16611046565b6103c9611236565b60408051918252519081900360200190f35b6103e361125a565b6040805160ff9092168252519081900360200190f35b610401611263565b6040805163ffffffff9092168252519081900360200190f35b610322600480360360a081101561043057600080fd5b506fffffffffffffffffffffffffffffffff8135169063ffffffff602082013581169160408101358216916060820135811691608001351661128b565b610322600480360360c081101561048357600080fd5b81019060208101813564010000000081111561049e57600080fd5b8201836020820111156104b057600080fd5b803590602001918460208302840111640100000000831117156104d257600080fd5b9193909290916020810190356401000000008111156104f057600080fd5b82018360208201111561050257600080fd5b8035906020019184602083028401116401000000008311171561052457600080fd5b91939092909160208101903564010000000081111561054257600080fd5b82018360208201111561055457600080fd5b8035906020019184602083028401116401000000008311171561057657600080fd5b919350915063ffffffff813581169160208101358216916040909101351661171f565b6105a16119a7565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b610322600480360360608110156105e057600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356119c3565b610615611c94565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610651578181015183820152602001610639565b505050509050019250505060405180910390f35b61066d611d04565b604080516fffffffffffffffffffffffffffffffff9092168252519081900360200190f35b610322611d1c565b6103c9611e99565b6103c9611f54565b6105a1611f59565b610401611f75565b6103e3611f95565b610322600480360360208110156106d857600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611f9b565b6105a16004803603602081101561070b57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166120e3565b6103c961211a565b6107f36004803603604081101561074657600080fd5b73ffffffffffffffffffffffffffffffffffffffff823516919081019060408101602082013564010000000081111561077e57600080fd5b82018360208201111561079057600080fd5b803590602001918460018302840111640100000000831117156107b257600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506121d0945050505050565b604080519115158252519081900360200190f35b610401612205565b610817612231565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610851578181015183820152602001610839565b50505050905090810190601f16801561087e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103226122dd565b6103c96123df565b610322612403565b6103c96124e9565b610322600480360360208110156108c257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661259f565b61091e600480360360408110156108f557600080fd5b50803573ffffffffffffffffffffffffffffffffffffffff16906020013563ffffffff166126d7565b60408051981515895263ffffffff90971660208901528787019590955267ffffffffffffffff93841660608801529190921660808601526fffffffffffffffffffffffffffffffff91821660a086015260ff1660c08501521660e083015251908190036101000190f35b6105a1612890565b6109986128ac565b6040805169ffffffffffffffffffff9092168252519081900360200190f35b6109e0600480360360208110156109cd57600080fd5b503569ffffffffffffffffffff16612a05565b6040805169ffffffffffffffffffff96871681526020810195909552848101939093526060840191909152909216608082015290519081900360a00190f35b61032260048036036020811015610a3557600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612ad4565b61032260048036036060811015610a6857600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691602081013591810190606081016040820135640100000000811115610aa557600080fd5b820183602082011115610ab757600080fd5b80359060200191846001830284011164010000000083111715610ad957600080fd5b509092509050612c0d565b6103c960048036036020811015610afa57600080fd5b5035612c88565b6103c960048036036020811015610b1757600080fd5b5035612d3f565b61032260048036036040811015610b3457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135612df6565b61066d61303c565b610401613054565b61066d613078565b6107f36130a4565b6103c960048036036020811015610b8d57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166130ad565b61032260048036036040811015610bc057600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166130e7565b61032260048036036020811015610bfb57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661321d565b6109e0613319565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ca657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b600e5460ff1615610d0357600e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040517f3be8a977a014527b50ae38adda80b56911c267328965c98ddc385d248f53963890600090a15b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d8b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b60035473ffffffffffffffffffffffffffffffffffffffff9081169082168114610e2257600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84811691821790925560405190918316907fcfac5dc75b8d9a7e074162f59d9adcd33da59f0fe8dfb21580db298fc0fdad0d90600090a35b5050565b6060610e3233846133e6565b90507f0000000000000000000000000000000000000000000000000000000000000000821215610ec357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f76616c75652062656c6f77206d696e5375626d697373696f6e56616c75650000604482015290519081900360640190fd5b7f0000000000000000000000000000000000000000000000000000000000000000821315610f5257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f76616c75652061626f7665206d61785375626d697373696f6e56616c75650000604482015290519081900360640190fd5b8051819015610ff9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610fbe578181015183820152602001610fa6565b50505050905090810190601f168015610feb5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50611003836136f4565b61100d82846137e5565b60008061101985613905565b9150915061102685613ab5565b61102f85613c78565b811561103f5761103f8582613cef565b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146110cc57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602052604090205460ff161515821515141561110557611231565b811561118d5773ffffffffffffffffffffffffffffffffffffffff83166000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016831515177fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010063ffffffff8416021790556111d9565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000001690555b60408051831515815263ffffffff83166020820152815173ffffffffffffffffffffffffffffffffffffffff8616927fc3df5a754e002718f2e10804b99e6605e7c701d95cec9552c7680ca2b6f2820a928290030190a25b505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60055460ff1681565b6004547801000000000000000000000000000000000000000000000000900463ffffffff1681565b60005473ffffffffffffffffffffffffffffffffffffffff16331461131157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b600061131b611f95565b60ff1690508463ffffffff168463ffffffff16101561139b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f6d6178206d75737420657175616c2f657863656564206d696e00000000000000604482015290519081900360640190fd5b8363ffffffff168163ffffffff16101561141657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f6d61782063616e6e6f742065786365656420746f74616c000000000000000000604482015290519081900360640190fd5b63ffffffff8116158061143457508263ffffffff168163ffffffff16115b61149f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f64656c61792063616e6e6f742065786365656420746f74616c00000000000000604482015290519081900360640190fd5b6114ba866fffffffffffffffffffffffffffffffff16613e28565b600d546fffffffffffffffffffffffffffffffff16101561153c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f696e73756666696369656e742066756e647320666f72207061796d656e740000604482015290519081900360640190fd5b6000611546611f95565b60ff1611156115c45760008563ffffffff16116115c457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d696e206d7573742062652067726561746572207468616e2030000000000000604482015290519081900360640190fd5b85600460006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555084600460146101000a81548163ffffffff021916908363ffffffff16021790555083600460106101000a81548163ffffffff021916908363ffffffff16021790555082600460186101000a81548163ffffffff021916908363ffffffff160217905550816004601c6101000a81548163ffffffff021916908363ffffffff1602179055508363ffffffff168563ffffffff16600460009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff167f56800c9d1ed723511246614d15e58cfcde15b6a33c245b5c961b689c1890fd8f8686604051808363ffffffff1663ffffffff1681526020018263ffffffff1663ffffffff1681526020019250505060405180910390a4505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146117a557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b60005b888110156117e9576117e18a8a838181106117bf57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff16613e56565b6001016117a8565b5085841461185857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f6e6565642073616d65206f7261636c6520616e642061646d696e20636f756e74604482015290519081900360640190fd5b604d61187587611866611f95565b60ff169063ffffffff61410616565b11156118e257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f6d6178206f7261636c657320616c6c6f77656400000000000000000000000000604482015290519081900360640190fd5b60005b8681101561194f576119478888838181106118fc57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1687878481811061192557fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff1661417a565b6001016118e5565b5060045461199c906fffffffffffffffffffffffffffffffff8116908590859085907c0100000000000000000000000000000000000000000000000000000000900463ffffffff1661128b565b505050505050505050565b60035473ffffffffffffffffffffffffffffffffffffffff1681565b73ffffffffffffffffffffffffffffffffffffffff838116600090815260086020526040902060020154620100009004163314611a6157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6f6e6c792063616c6c61626c652062792061646d696e00000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff831660009081526008602052604090205481906fffffffffffffffffffffffffffffffff908116908216811015611b0e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f696e73756666696369656e7420776974686472617761626c652066756e647300604482015290519081900360640190fd5b611b306fffffffffffffffffffffffffffffffff82168363ffffffff61454e16565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260086020526040902080547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff928316179055600d54611bb391700100000000000000000000000000000000909104168361454e565b600d80546fffffffffffffffffffffffffffffffff92831670010000000000000000000000000000000002908316179055600254604080517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff888116600483015293861660248201529051929091169163a9059cbb916044808201926020929091908290030181600087803b158015611c6257600080fd5b505af1158015611c76573d6000803e3d6000fd5b505050506040513d6020811015611c8c57600080fd5b505161103f57fe5b6060600c805480602002602001604051908101604052809291908181526020018280548015611cf957602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611cce575b505050505090505b90565b600d546fffffffffffffffffffffffffffffffff1690565b611d24615e5a565b50604080518082018252600d546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000090910416602080830182905260025484517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015294519394600094611e11949373ffffffffffffffffffffffffffffffffffffffff909316926370a082319260248082019391829003018186803b158015611dd957600080fd5b505afa158015611ded573d6000803e3d6000fd5b505050506040513d6020811015611e0357600080fd5b50519063ffffffff6145e916565b82519091506fffffffffffffffffffffffffffffffff168114610e2257600d80547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff831617905560405181907ffe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234f90600090a25050565b6000611edc336000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506121d092505050565b611f4757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b611f4f61465a565b905090565b600381565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b600454700100000000000000000000000000000000900463ffffffff1681565b600c5490565b73ffffffffffffffffffffffffffffffffffffffff81811660009081526008602052604090206003015416331461203357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f6f6e6c792063616c6c61626c652062792070656e64696e672061646d696e0000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff81166000818152600860205260408082206003810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905560020180547fffffffffffffffffffff0000000000000000000000000000000000000000ffff16336201000081029190911790915590519092917f0c5055390645c15a4be9a21b3f8d019153dcb4a0c125685da6eb84048e2fe90491a350565b73ffffffffffffffffffffffffffffffffffffffff808216600090815260086020526040902060020154620100009004165b919050565b600061215d336000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506121d092505050565b6121c857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b611f4f61467d565b60006121dc8383614691565b806121fc575073ffffffffffffffffffffffffffffffffffffffff831632145b90505b92915050565b6004547c0100000000000000000000000000000000000000000000000000000000900463ffffffff1681565b6006805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156122d55780601f106122aa576101008083540402835291602001916122d5565b820191906000526020600020905b8154815290600101906020018083116122b857829003601f168201915b505050505081565b60015473ffffffffffffffffffffffffffffffffffffffff16331461236357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015290519081900360640190fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b7f000000000000000000000000000000000000000000000000000000000000000081565b60005473ffffffffffffffffffffffffffffffffffffffff16331461248957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b600e5460ff16610d0357600e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040517faebf329500988c6488a0074e5a0a9ff304561fc5c6fc877aeb1d59c8282c348090600090a1565b600061252c336000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506121d092505050565b61259757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b611f4f6146ce565b60005473ffffffffffffffffffffffffffffffffffffffff16331461262557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600f602052604090205460ff16156126d45773ffffffffffffffffffffffffffffffffffffffff81166000818152600f602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055815192835290517f3d68a6fce901d20453d1a7aa06bf3950302a735948037deb182a8db66df2a0d19281900390910190a15b50565b60008080808080808033321461274e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6f66662d636861696e2072656164696e67206f6e6c7900000000000000000000604482015290519081900360640190fd5b63ffffffff8916156128695763ffffffff89166000908152600960209081526040808320600a9092529091206127848c8c61470a565b73ffffffffffffffffffffffffffffffffffffffff8d1660009081526008602052604090206001908101548482015491840154600d548f9367ffffffffffffffff169168010000000000000000900463ffffffff16906fffffffffffffffffffffffffffffffff166127f4611f95565b600189015467ffffffffffffffff16612821576004546fffffffffffffffffffffffffffffffff16612849565b60018801546c0100000000000000000000000090046fffffffffffffffffffffffffffffffff165b8363ffffffff169350995099509950995099509950995099505050612883565b6128728a614760565b975097509750975097509750975097505b9295985092959890939650565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b336000908152600b602052604081205460ff1661292a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6e6f7420617574686f72697a6564207265717565737465720000000000000000604482015290519081900360640190fd5b60075463ffffffff1660008181526009602052604090206001015468010000000000000000900467ffffffffffffffff1615158061296c575061296c81614977565b6129d757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f7072657620726f756e64206d75737420626520737570657273656461626c6500604482015290519081900360640190fd5b60006129ee63ffffffff80841690600190614a0a16565b90506129f981614a87565b63ffffffff1691505090565b6000806000806000612a4e336000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506121d092505050565b612ab957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b612ac286614b8f565b939a9299509097509550909350915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612b5a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600f602052604090205460ff166126d45773ffffffffffffffffffffffffffffffffffffffff81166000818152600f602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055815192835290517f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db49281900390910190a150565b8015612c7a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f7472616e7366657220646f65736e2774206163636570742063616c6c64617461604482015290519081900360640190fd5b612c82611d1c565b50505050565b6000612ccb336000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506121d092505050565b612d3657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6121ff82614d05565b6000612d82336000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506121d092505050565b612ded57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6121ff82614d39565b60005473ffffffffffffffffffffffffffffffffffffffff163314612e7c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b600d546004546fffffffffffffffffffffffffffffffff918216918391612eb491612ea79116613e28565b839063ffffffff6145e916565b1015612f2157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f696e73756666696369656e7420726573657276652066756e6473000000000000604482015290519081900360640190fd5b600254604080517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152602482018690529151919092169163a9059cbb9160448083019260209291908290030181600087803b158015612f9d57600080fd5b505af1158015612fb1573d6000803e3d6000fd5b505050506040513d6020811015612fc757600080fd5b505161303457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f6b656e207472616e73666572206661696c65640000000000000000000000604482015290519081900360640190fd5b611231611d1c565b6004546fffffffffffffffffffffffffffffffff1681565b60045474010000000000000000000000000000000000000000900463ffffffff1681565b600d5470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690565b600e5460ff1681565b73ffffffffffffffffffffffffffffffffffffffff166000908152600860205260409020546fffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff82811660009081526008602052604090206002015462010000900416331461318557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6f6e6c792063616c6c61626c652062792061646d696e00000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff82811660008181526008602090815260409182902060030180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169486169485179055815133815290810193909352805191927fb79bf2e89c2d70dde91d2991fb1ea69b7e478061ad7c04ed5b02b96bc52b8104929081900390910190a25050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146132a357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000806000806000613362336000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506121d092505050565b6133cd57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f4e6f206163636573730000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6133d5614d7e565b945094509450945094509091929394565b73ffffffffffffffffffffffffffffffffffffffff821660009081526008602052604090205460075460609163ffffffff7001000000000000000000000000000000009091048116911681613474576040518060400160405280601281526020017f6e6f7420656e61626c6564206f7261636c650000000000000000000000000000815250925050506121ff565b8363ffffffff168263ffffffff1611156134c7576040518060400160405280601681526020017f6e6f742079657420656e61626c6564206f7261636c6500000000000000000000815250925050506121ff565b73ffffffffffffffffffffffffffffffffffffffff851660009081526008602052604090205463ffffffff80861674010000000000000000000000000000000000000000909204161015613554576040518060400160405280601881526020017f6e6f206c6f6e67657220616c6c6f776564206f7261636c650000000000000000815250925050506121ff565b73ffffffffffffffffffffffffffffffffffffffff851660009081526008602052604090205463ffffffff808616780100000000000000000000000000000000000000000000000090920416106135e4576040518060400160405280602081526020017f63616e6e6f74207265706f7274206f6e2070726576696f757320726f756e6473815250925050506121ff565b8063ffffffff168463ffffffff1614158015613620575061361063ffffffff80831690600190614a0a16565b63ffffffff168463ffffffff1614155b801561363357506136318482614da7565b155b15613677576040518060400160405280601781526020017f696e76616c696420726f756e6420746f207265706f7274000000000000000000815250925050506121ff565b8363ffffffff166001141580156136a857506136a66136a163ffffffff80871690600190614e0d16565b614e8a565b155b156136ec576040518060400160405280601f81526020017f70726576696f757320726f756e64206e6f7420737570657273656461626c6500815250925050506121ff565b505092915050565b6136fd81614eca565b613706576126d4565b3360009081526008602052604090205460045463ffffffff7c01000000000000000000000000000000000000000000000000000000009092048216917801000000000000000000000000000000000000000000000000909104811682019083161180159061377357508015155b1561377e57506126d4565b61378782614efb565b50336000908152600860205260409020805463ffffffff83167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90911617905550565b6137ee8161518a565b61385957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f726f756e64206e6f7420616363657074696e67207375626d697373696f6e7300604482015290519081900360640190fd5b63ffffffff81166000818152600a602090815260408083208054600180820183559185528385200187905533808552600890935281842080547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000008702178155018690555190929185917f92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68c9190a45050565b63ffffffff8082166000908152600a60205260408120600181015490549192839264010000000090920416111561394157506000905080613ab0565b63ffffffff83166000908152600a6020908152604080832080548251818502810185019093528083526139a79383018282801561399d57602002820191906000526020600020905b815481526020019060010190808311613989575b50505050506151aa565b63ffffffff851660008181526009602090815260409182902084815560010180547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff16680100000000000000004267ffffffffffffffff811691909102919091177fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff16700100000000000000000000000000000000860217909155600780547fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff16640100000000860217905582519081529151939450919284927f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f928290030190a36001925090505b915091565b63ffffffff81166000908152600a60205260409020600101546c0100000000000000000000000090046fffffffffffffffffffffffffffffffff16613af8615e5a565b5060408051808201909152600d546fffffffffffffffffffffffffffffffff808216808452700100000000000000000000000000000000909204166020830152613b48908363ffffffff61454e16565b6fffffffffffffffffffffffffffffffff90811682526020820151613b7491168363ffffffff61527416565b6fffffffffffffffffffffffffffffffff90811660208084018290528351600d80547001000000000000000000000000000000009094029185167fffffffffffffffffffffffffffffffff000000000000000000000000000000009094169390931784161790915533600090815260089091526040902054613bfd91168363ffffffff61527416565b3360009081526008602052604080822080547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff948516179055835190519216917ffe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234f9190a2505050565b63ffffffff8082166000908152600a602052604090206001810154905491161115613ca2576126d4565b63ffffffff81166000908152600a6020526040812090613cc28282615e71565b5060010180547fffffffff0000000000000000000000000000000000000000000000000000000016905550565b60035473ffffffffffffffffffffffffffffffffffffffff1680613d135750610e22565b6000613d2a63ffffffff80861690600190614e0d16565b63ffffffff80821660009081526009602090815260408083206001810154905482517fbeed9b5100000000000000000000000000000000000000000000000000000000815270010000000000000000000000000000000090920486166004830181905260248301829052958b166044830152606482018a905291519596509394909373ffffffffffffffffffffffffffffffffffffffff88169363beed9b5193620186a093608480850194929391928390030190829088803b158015613def57600080fd5b5087f193505050508015613e1557506040513d6020811015613e1057600080fd5b505160015b613e1e57613e20565b505b505050505050565b60006121ff6002613e4a613e3a611f95565b859060ff1663ffffffff6152fd16565b9063ffffffff6152fd16565b613e5f81615370565b613eca57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6f7261636c65206e6f7420656e61626c65640000000000000000000000000000604482015290519081900360640190fd5b600754613ee39063ffffffff90811690600190614a0a16565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600860205260408120805463ffffffff9390931674010000000000000000000000000000000000000000027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff90931692909217909155600c613f736001613f64611f95565b60ff169063ffffffff6145e916565b81548110613f7d57fe5b60009182526020808320919091015473ffffffffffffffffffffffffffffffffffffffff85811680855260089093526040808520600290810180549390941680875291862001805461ffff9093167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009384168117909155939094528154169055600c805492935090918391908390811061401357fe5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600c80548061406657fe5b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8516907f18dd09695e4fbdae8d1a5edb11221eb04564269c29a089b9753a6535c54ba92e908390a3505050565b6000828201838110156121fc57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b61418382615370565b156141ef57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6f7261636c6520616c726561647920656e61626c656400000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff811661427157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f63616e6e6f74207365742061646d696e20746f20300000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600860205260409020600201546201000090041615806142e0575073ffffffffffffffffffffffffffffffffffffffff8281166000908152600860205260409020600201546201000090048116908216145b61434b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6f776e65722063616e6e6f74206f76657277726974652061646d696e00000000604482015290519081900360640190fd5b614354826153b9565b73ffffffffffffffffffffffffffffffffffffffff80841660008181526008602052604080822080547fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff63ffffffff97909716700100000000000000000000000000000000027fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff909116179590951677ffffffff0000000000000000000000000000000000000000178555600c80546002909601805461ffff9097167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909716969096178655805460018181019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70180547fffffffffffffffffffffffff00000000000000000000000000000000000000001685179055838352855494871662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff909516949094179094559251919290917f18dd09695e4fbdae8d1a5edb11221eb04564269c29a089b9753a6535c54ba92e9190a38073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f0c5055390645c15a4be9a21b3f8d019153dcb4a0c125685da6eb84048e2fe90460405160405180910390a35050565b6000826fffffffffffffffffffffffffffffffff16826fffffffffffffffffffffffffffffffff1611156145e357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6000828211156145e357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b600754640100000000900463ffffffff1660009081526009602052604090205490565b600754640100000000900463ffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600f602052604081205460ff16806121fc575050600e5460ff161592915050565b600754640100000000900463ffffffff1660009081526009602052604090206001015468010000000000000000900467ffffffffffffffff1690565b63ffffffff811660009081526009602052604081206001015467ffffffffffffffff16156147565761473b8261518a565b801561474f575061474c83836133e6565b51155b90506121ff565b61473b8383615441565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600860205260408120600754815483928392839283928392839283927fec8156718a8372b1db44bb411437d0870f3e3790d4a08526d024ce1b0b668f6b929091849163ffffffff90811678010000000000000000000000000000000000000000000000009092041614806147ff57506007546147fd9063ffffffff1661518a565b155b6007549091506148149063ffffffff16614e8a565b801561481d5750805b1561487f5760075461483b9063ffffffff90811690600190614a0a16565b63ffffffff81166000908152600960205260409020600454919b506fffffffffffffffffffffffffffffffff909116945092506148788c8b615441565b9a506148db565b60075463ffffffff166000818152600960209081526040808320600a90925290912060010154919b506c010000000000000000000000009091046fffffffffffffffffffffffffffffffff16945092506148d88a61518a565b9a505b6148e58c8b6133e6565b51156148f05760009a505b6001808301548482015463ffffffff808e166000908152600a6020526040902090930154600d548f948f949367ffffffffffffffff169268010000000000000000900416906fffffffffffffffffffffffffffffffff1661494f611f95565b8a8363ffffffff1693509a509a509a509a509a509a509a509a50505050919395975091939597565b63ffffffff8082166000908152600960209081526040808320600190810154600a9093529083200154919267ffffffffffffffff909116916801000000000000000090041681158015906149d1575060008163ffffffff16115b8015614a025750426149f667ffffffffffffffff841663ffffffff808516906154c616565b67ffffffffffffffff16105b949350505050565b600082820163ffffffff80851690821610156121fc57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b614a9081614eca565b614a99576126d4565b336000908152600b602052604090205463ffffffff6501000000000082048116916101009004811682019083161180614ad0575080155b614b3b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f6d7573742064656c617920726571756573747300000000000000000000000000604482015290519081900360640190fd5b614b4482614efb565b50336000908152600b60205260409020805463ffffffff831665010000000000027fffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffff90911617905550565b6000806000806000614b9f615e8f565b5063ffffffff80871660009081526009602090815260409182902082516080810184528154815260019091015467ffffffffffffffff808216938301939093526801000000000000000081049092169281019290925270010000000000000000000000000000000090049091166060820181905215801590614c315750614c318769ffffffffffffffffffff16615547565b6040518060400160405280600f81526020017f4e6f20646174612070726573656e74000000000000000000000000000000000081525090614ccd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201818152835160248401528351909283926044909101919085019080838360008315610fbe578181015183820152602001610fa6565b508051602082015160408301516060909301519899919867ffffffffffffffff91821698509216955063ffffffff9091169350915050565b6000614d1082615547565b15614d31575063ffffffff8116600090815260096020526040902054612115565b506000919050565b6000614d4482615547565b15614d31575063ffffffff811660009081526009602052604090206001015468010000000000000000900467ffffffffffffffff16612115565b60008060008060006133d5600760049054906101000a900463ffffffff1663ffffffff16612a05565b60008163ffffffff16614dca60018563ffffffff16614a0a90919063ffffffff16565b63ffffffff161480156121fc57505063ffffffff1660009081526009602052604090206001015468010000000000000000900467ffffffffffffffff1615919050565b60008263ffffffff168263ffffffff1611156145e357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b63ffffffff811660009081526009602052604081206001015468010000000000000000900467ffffffffffffffff161515806121ff57506121ff82614977565b600754600090614ee69063ffffffff90811690600190614a0a16565b63ffffffff168263ffffffff16149050919050565b614f18614f1363ffffffff80841690600190614e0d16565b615551565b600780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8316179055614f50615eb6565b5060408051600060a0820181815260c083018452825260045463ffffffff700100000000000000000000000000000000820481166020808601919091527401000000000000000000000000000000000000000083048216858701527c01000000000000000000000000000000000000000000000000000000008304821660608601526fffffffffffffffffffffffffffffffff909216608085015285168252600a8152929020815180519293849361500b9284920190615ee4565b506020828101516001928301805460408087015160608801516080909801517fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000090931663ffffffff958616177fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff1664010000000091861691909102177fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff166801000000000000000097851697909702969096177fffffffff00000000000000000000000000000000ffffffffffffffffffffffff166c010000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055851660008181526009835284902090920180547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000164267ffffffffffffffff9081169190911791829055845191168152925133937f0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac6027192908290030190a35050565b63ffffffff9081166000908152600a602052604090206001015416151590565b6000815160001061521c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6c697374206d757374206e6f7420626520656d70747900000000000000000000604482015290519081900360640190fd5b8151600281046001821661525b5760008061524186600060018703600187038761566a565b90925090506152508282615748565b945050505050612115565b61526b84600060018503846157b6565b92505050612115565b60008282016fffffffffffffffffffffffffffffffff80851690821610156121fc57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60008261530c575060006121ff565b8282028284828161531957fe5b04146121fc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615f6b6021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff1660009081526008602052604090205463ffffffff7401000000000000000000000000000000000000000090910481161490565b60075460009063ffffffff168015801590615419575073ffffffffffffffffffffffffffffffffffffffff831660009081526008602052604090205463ffffffff8281167401000000000000000000000000000000000000000090920416145b15615425579050612115565b61543a63ffffffff80831690600190614a0a16565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff821660009081526008602052604081205460045463ffffffff7c01000000000000000000000000000000000000000000000000000000009092048216917801000000000000000000000000000000000000000000000000909104811682019084161180614a025750159392505050565b600082820167ffffffffffffffff80851690821610156121fc57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b63ffffffff101590565b61555a81614977565b615563576126d4565b600061557a63ffffffff80841690600190614e0d16565b63ffffffff818116600090815260096020908152604080832080548886168552828520908155600191820154910180547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff1670010000000000000000000000000000000092839004909616909102949094177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff16680100000000000000004267ffffffffffffffff160217909355600a905290812091925061563c8282615e71565b5060010180547fffffffff000000000000000000000000000000000000000000000000000000001690555050565b60008082841061567957600080fd5b8386111580156156895750848411155b61569257600080fd5b8286111580156156a25750848311155b6156ab57600080fd5b600786860310156156cc576156c38787878787615847565b9150915061573e565b60006156d9888888615cfe565b90508084116156ea57809550615738565b848110156156fd57806001019650615738565b80851115801561570c57508381105b61571257fe5b61571e888883886157b6565b925061572f888260010188876157b6565b915061573e9050565b506156ab565b9550959350505050565b600080831280156157595750600082135b8061576f575060008313801561576f5750600082125b1561578f5760026157808484615ddb565b8161578757fe5b0590506121ff565b6000600280850781850701059050614a026157b06002860560028605615ddb565b82615ddb565b6000818411156157c557600080fd5b828211156157d257600080fd5b8284101561582957600784840310156157fe5760006157f48686868687615847565b509150614a029050565b600061580b868686615cfe565b905080831161581c57809350615823565b8060010194505b506157d2565b84848151811061583557fe5b60200260200101519050949350505050565b60008060008686600101039050600088886000018151811061586557fe5b6020026020010151905060008260011061589f577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6158b7565b8989600101815181106158ae57fe5b60200260200101515b90506000836002106158e9577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff615901565b8a8a600201815181106158f857fe5b60200260200101515b9050600084600310615933577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61594b565b8b8b6003018151811061594257fe5b60200260200101515b905060008560041061597d577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff615995565b8c8c6004018151811061598c57fe5b60200260200101515b90506000866005106159c7577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6159df565b8d8d600501815181106159d657fe5b60200260200101515b9050600087600610615a11577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff615a29565b8e8e60060181518110615a2057fe5b60200260200101515b905085871315615a37579495945b83851315615a43579293925b81831315615a4f579091905b84871315615a5b579395935b83861315615a67579294925b80831315615a7157915b84861315615a7d579394935b80821315615a8757905b82871315615a93579195915b81861315615a9f579094905b80851315615aa957935b82861315615ab5579194915b80841315615abf57925b82851315615acb579193915b81841315615ad7579092905b82841315615ae3579192915b8d8c0380615af357879a50615bc0565b8060011415615b0457869a50615bc0565b8060021415615b1557859a50615bc0565b8060031415615b2657849a50615bc0565b8060041415615b3757839a50615bc0565b8060051415615b4857829a50615bc0565b8060061415615b5957819a50615bc0565b604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6b31206f7574206f6620626f756e647300000000000000000000000000000000604482015290519081900360640190fd5b8e8c038d8d1415615bde57508a995061573e98505050505050505050565b80615bf5575096985061573e975050505050505050565b8060011415615c10575095985061573e975050505050505050565b8060021415615c2b575094985061573e975050505050505050565b8060031415615c46575093985061573e975050505050505050565b8060041415615c61575092985061573e975050505050505050565b8060051415615c7c575091985061573e975050505050505050565b8060061415615c97575090985061573e975050505050505050565b604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6b32206f7574206f6620626f756e647300000000000000000000000000000000604482015290519081900360640190fd5b6000808460028585010481518110615d1257fe5b602002602001015190506001840393506001830192505b60018401935080858581518110615d3c57fe5b602002602001015112615d29575b60018303925080858481518110615d5d57fe5b602002602001015113615d4a5782841015615dcd57848381518110615d7e57fe5b6020026020010151858581518110615d9257fe5b6020026020010151868681518110615da657fe5b60200260200101878681518110615db957fe5b602090810291909101019190915252615dd6565b8291505061543a565b615d29565b6000828201818312801590615df05750838112155b80615e055750600083128015615e0557508381125b6121fc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180615f4a6021913960400191505060405180910390fd5b604080518082019091526000808252602082015290565b50805460008255906000526020600020908101906126d49190615f2f565b60408051608081018252600080825260208201819052918101829052606081019190915290565b6040805160a08101825260608082526000602083018190529282018390528101829052608081019190915290565b828054828255906000526020600020908101928215615f1f579160200282015b82811115615f1f578251825591602001919060010190615f04565b50615f2b929150615f2f565b5090565b611d0191905b80821115615f2b5760008155600101615f3556fe5369676e6564536166654d6174683a206164646974696f6e206f766572666c6f77536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a26469706673582212203dfd5ae52fef7bbe05a195d698b0b1b8be56378daa346eaccbc52d24f39c30af64736f6c63430006060033536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77000000000000000000000000b0897686c545045afc77cf20ec7a532e3120e0f100000000000000000000000000000000000000000000000000038d7ea4c68000000000000000000000000000000000000000000000000000000000000002a300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000989680000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000009434f50202f205553440000000000000000000000000000000000000000000000
Deployed ByteCode Sourcemap
64512:7542:0:-:0;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;64512:7542:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;9;2:12;63020:168:0;;;:::i;:::-;;50899:295;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;50899:295:0;;;;:::i;33871:706::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;33871:706:0;;;;;;;:::i;48578:450::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;48578:450:0;;;;;;;;;;;;;;;;;;:::i;29915:42::-;;;:::i;:::-;;;;;;;;;;;;;;;;29792:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;29735:26;;;:::i;:::-;;;;;;;;;;;;;;;;;;;36540:1055;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;36540:1055:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;35339:747::-;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;35339:747:0;;;;;;;;27:11:-1;11:28;;8:2;;;52:1;49;42:12;8:2;35339:747:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;35339:747:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;35339:747:0;;;;;;;;;;;27:11:-1;11:28;;8:2;;;52:1;49;42:12;8:2;35339:747:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;35339:747:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;35339:747:0;;;;;;;;;;;27:11:-1;11:28;;8:2;;;52:1;49;42:12;8:2;35339:747:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;35339:747:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;35339:747:0;;-1:-1:-1;35339:747:0;-1:-1:-1;35339:747:0;;;;;;;;;;;;;;;;;;;;:::i;29549:45::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;45337:628;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;45337:628:0;;;;;;;;;;;;;;;;;;:::i;38693:98::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;38693:98:0;;;;;;;;;;;;;;;;;37885:119;;;:::i;:::-;;;;;;;;;;;;;;;;;;;38091:339;;;:::i;69390:144::-;;;:::i;29964:44::-;;;:::i;29509:35::-;;;:::i;29661:32::-;;;:::i;38494:100::-;;;:::i;47451:298::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;47451:298:0;;;;:::i;46673:127::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;46673:127:0;;;;:::i;69976:143::-;;;:::i;64077:220::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;64077:220:0;;;;;;;;;;;;;;;;27:11:-1;11:28;;8:2;;;52:1;49;42:12;8:2;64077:220:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;64077:220:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;64077:220:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;64077:220:0;;-1:-1:-1;64077:220:0;;-1:-1:-1;;;;;64077:220:0:i;:::-;;;;;;;;;;;;;;;;;;29766:21;;;:::i;29827:34::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;29827:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14320:264;;;:::i;29868:42::-;;;:::i;62786:166::-;;;:::i;70562:151::-;;;:::i;62536:184::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;62536:184:0;;;;:::i;49739:978::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;49739:978:0;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13661:20;;;:::i;47825:405::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;67065:294;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;67065:294:0;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62242:179;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;62242:179:0;;;;:::i;49315:186::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;49315:186:0;;;;;;;;;;;;;;;;;;;;27:11:-1;11:28;;8:2;;;52:1;49;42:12;8:2;49315:186:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;49315:186:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;49315:186:0;;-1:-1:-1;49315:186:0;-1:-1:-1;49315:186:0;:::i;71199:162::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;71199:162:0;;:::i;71880:169::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;71880:169:0;;:::i;46155:370::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;46155:370:0;;;;;;;;;:::i;29628:28::-;;;:::i;29698:32::-;;;:::i;37682:119::-;;;:::i;61559:24::-;;;:::i;44891:145::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;44891:145:0;;;;:::i;47006:280::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;47006:280:0;;;;;;;;;;;:::i;14069:157::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;14069:157:0;;;;:::i;68673:277::-;;;:::i;63020:168::-;14724:5;;;;14710:10;:19;14702:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63095:12:::1;::::0;::::1;;63091:92;;;63118:12;:20:::0;;;::::1;::::0;;63154:21:::1;::::0;::::1;::::0;63133:5:::1;::::0;63154:21:::1;63091:92;63020:168::o:0;50899:295::-;14724:5;;;;14710:10;:19;14702:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51010:9:::1;::::0;::::1;::::0;;::::1;::::0;51033:25;::::1;::::0;::::1;51029:160;;51069:9;:55:::0;;;::::1;;::::0;;::::1;::::0;;::::1;::::0;;;51140:41:::1;::::0;51069:55;;51140:41;::::1;::::0;::::1;::::0;-1:-1:-1;;51140:41:0::1;51029:160;14763:1;50899:295:::0;:::o;33871:706::-;33949:18;33970:49;33990:10;34009:8;33970:19;:49::i;:::-;33949:70;;34049:18;34034:11;:33;;34026:76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34132:18;34117:11;:33;;34109:76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34200:12;;:5;;:17;34192:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;34192:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34242:42;34274:8;34242:24;:42::i;:::-;34291:47;34308:11;34328:8;34291:16;:47::i;:::-;34346:12;34360:16;34380:35;34405:8;34380:17;:35::i;:::-;34345:70;;;;34422:27;34439:8;34422:9;:27::i;:::-;34456:36;34482:8;34456:18;:36::i;:::-;34503:7;34499:73;;;34521:43;34543:8;34554:9;34521:14;:43::i;:::-;33871:706;;;;;:::o;48578:450::-;14724:5;;;;14710:10;:19;14702:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48709:22:::1;::::0;::::1;;::::0;;;:10:::1;:22;::::0;;;;:33;::::1;;:48;;::::0;::::1;;;48705:61;;;48759:7;;48705:61;48778:11;48774:179;;;48800:22;::::0;::::1;;::::0;;;:10:::1;:22;::::0;;;;:47;;;::::1;::::0;::::1;;;48856:37:::0;::::1;48800:47;48856:37;::::0;::::1;;;::::0;;48774:179:::1;;;48923:22;::::0;::::1;;::::0;;;:10:::1;:22;::::0;;;;48916:29;;;;;;48774:179:::1;48966:56;::::0;;;::::1;;::::0;;::::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;::::1;::::0;;;;;;::::1;14763:1;48578:450:::0;;;:::o;29915:42::-;;;:::o;29792:30::-;;;;;;:::o;29735:26::-;;;;;;;;;:::o;36540:1055::-;14724:5;;;;14710:10;:19;14702:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36748:16:::1;36767:13;:11;:13::i;:::-;36748:32;;;;36839:15;36820:34;;:15;:34;;;;36812:72;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;36912:15;36899:28;;:9;:28;;;;36891:64;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;36970:14;::::0;::::1;::::0;;:43:::1;;;37000:13;36988:25;;:9;:25;;;36970:43;36962:81;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;37085:31;37101:14;37085:31;;:15;:31::i;:::-;37058:13;:23:::0;::::1;;:58;;37050:101;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;37178:1;37162:13;:11;:13::i;:::-;:17;;;37158:98;;;37216:1;37198:15;:19;;;37190:58;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;37280:14;37264:13;;:30;;;;;;;;;;;;;;;;;;37322:15;37301:18;;:36;;;;;;;;;;;;;;;;;;37365:15;37344:18;;:36;;;;;;;;;;;;;;;;;;37402:13;37387:12;;:28;;;;;;;;;;;;;;;;;;37432:8;37422:7;;:18;;;;;;;;;;;;;;;;;;37528:15;37454:135;;37504:15;37454:135;;37482:13;;;;;;;;;;;37454:135;;;37552:13;37574:8;37454:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14763:1;36540:1055:::0;;;;;:::o;35339:747::-;14724:5;;;;14710:10;:19;14702:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35602:9:::1;35597:88;35617:19:::0;;::::1;35597:88;;;35652:25;35665:8;;35674:1;35665:11;;;;;;;;;;;;;;;35652:12;:25::i;:::-;35638:3;;35597:88;;;-1:-1:-1::0;35701:36:0;;::::1;35693:81;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;;;;;;;::::1;::::0;;;;;;;;;;;;;::::1;;30480:2;35789:41;35816:6:::0;35797:13:::1;:11;:13::i;:::-;35789:22;;::::0;:41:::1;:26;:41;:::i;:::-;:61;;35781:93;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;35888:9;35883:98;35903:17:::0;;::::1;35883:98;;;35936:37;35946:6;;35953:1;35946:9;;;;;;;;;;;;;;;35957:12;;35970:1;35957:15;;;;;;;;;;;;;;;35936:9;:37::i;:::-;35922:3;;35883:98;;;-1:-1:-1::0;36008:13:0::1;::::0;35989:91:::1;::::0;36008:13:::1;::::0;::::1;::::0;36023:15;;36040;;36057:13;;36072:7;;::::1;;;35989:18;:91::i;:::-;35339:747:::0;;;;;;;;;:::o;29549:45::-;;;;;;:::o;45337:628::-;45448:36;:16;;;;;;;:7;:16;;;;;:22;;;;;;;45474:10;45448:36;45440:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45666:16;;;45606:14;45666:16;;;:7;:16;;;;;:29;45631:7;;45666:29;;;;;45710:19;;;;;45702:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45806:21;:13;;;45820:6;45806:21;:13;:21;:::i;:::-;45774:16;;;;;;;:7;:16;;;;;:53;;;;;;;;;;;45860:13;:23;:35;;:23;;;;;45888:6;45860:27;:35::i;:::-;45834:13;:61;;;;;;;;;;;;;;45911:9;;:47;;;;;;:9;:47;;;;;;;45942:15;;;45911:47;;;;;;:9;;;;;:18;;:47;;;;;;;;;;;;;;;45834:23;45911:9;:47;;;2:2:-1;;;;27:1;24;17:12;2:2;45911:47:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;45911:47:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;45911:47:0;45904:55;;;38693:98;38738:16;38770:15;38763:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38693:98;;:::o;37885:119::-;37975:13;:23;;;37885:119;:::o;38091:339::-;38145:18;;:::i;:::-;-1:-1:-1;38145:34:0;;;;;;;;38166:13;38145:34;;;;;;;;;;;;;;;;;;;38211:9;;:34;;;;;38239:4;38211:34;;;;;;38145;;-1:-1:-1;;38211:55:0;;38145:34;38211:9;;;;;:19;;:34;;;;;;;;;;;:9;:34;;;2:2:-1;;;;27:1;24;17:12;2:2;38211:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;38211:34:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;38211:34:0;;:55;:38;:55;:::i;:::-;38279:15;;38188:78;;-1:-1:-1;38279:31:0;;;;38275:150;;38321:13;:47;;;;;;;;;;38382:35;;38321:47;;38382:35;;-1:-1:-1;;38382:35:0;38091:339;;:::o;69390:144::-;69483:6;63300:31;63310:10;63322:8;;63300:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;63300:9:0;;-1:-1:-1;;;63300:31:0:i;:::-;63292:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69508:20:::1;:18;:20::i;:::-;69501:27;;69390:144:::0;:::o;29964:44::-;30007:1;29964:44;:::o;29509:35::-;;;;;;:::o;29661:32::-;;;;;;;;;:::o;38494:100::-;38565:15;:22;38494:100;:::o;47451:298::-;47521:43;:16;;;;;;;:7;:16;;;;;:29;;;;47554:10;47521:43;47513:86;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47606:16;;;47646:1;47606:16;;;:7;:16;;;;;;:29;;;:42;;;;;;47655:22;;:35;;;;47680:10;47655:35;;;;;;;;;;47704:39;;47680:10;;47606:16;47704:39;;;47451:298;:::o;46673:127::-;46772:16;;;;46746:7;46772:16;;;:7;:16;;;;;:22;;;;;;;46673:127;;;;:::o;69976:143::-;70068:7;63300:31;63310:10;63322:8;;63300:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;63300:9:0;;-1:-1:-1;;;63300:31:0:i;:::-;63292:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70094:19:::1;:17;:19::i;64077:220::-:0;64213:4;64236:33;64252:5;64259:9;64236:15;:33::i;:::-;:55;;;-1:-1:-1;64273:18:0;;;64282:9;64273:18;64236:55;64229:62;;64077:220;;;;;:::o;29766:21::-;;;;;;;;;:::o;29827:34::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14320:264::-;14393:12;;;;14379:10;:26;14371:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14441:16;14460:5;;14480:10;14472:18;;;;;;;;-1:-1:-1;14497:25:0;;;;;;;14536:42;;14460:5;;;;;14480:10;;14460:5;;14536:42;;;14320:264;:::o;29868:42::-;;;:::o;62786:166::-;14724:5;;;;14710:10;:19;14702:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62861:12:::1;::::0;::::1;;62856:91;;62884:12;:19:::0;;;::::1;62899:4;62884:19;::::0;;62919:20:::1;::::0;::::1;::::0;62884:12:::1;::::0;62919:20:::1;62786:166::o:0;70562:151::-;70658:7;63300:31;63310:10;63322:8;;63300:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;63300:9:0;;-1:-1:-1;;;63300:31:0:i;:::-;63292:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70684:23:::1;:21;:23::i;62536:184::-:0;14724:5;;;;14710:10;:19;14702:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62618:17:::1;::::0;::::1;;::::0;;;:10:::1;:17;::::0;;;;;::::1;;62614:101;;;62646:17;::::0;::::1;62666:5;62646:17:::0;;;:10:::1;:17;::::0;;;;;;;;:25;;;::::1;::::0;;62687:20;;;;;;;::::1;::::0;;;;;;;;::::1;62614:101;62536:184:::0;:::o;49739:978::-;49852:22;;;;;;;;50097:10;50111:9;50097:23;50089:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50160:19;;;;50156:556;;50212:23;;;50190:19;50212:23;;;:6;:23;;;;;;;;50275:7;:24;;;;;;50326:50;50351:7;50219:15;50326:24;:50::i;:::-;50413:16;;;;;;;:7;:16;;;;;:33;;;;;50457:15;;;;50483;;;;50509:13;:23;50387:15;;50457;;;50483;;;;;;50509:23;;50543:13;:11;:13::i;:::-;50568:15;;;;;;:59;;50614:13;;;;50568:59;;;50590:21;;;;;;;;;50568:59;50308:329;;;;;;;;;;;;;;;;;;;;;;;;;50156:556;50667:37;50696:7;50667:28;:37::i;:::-;50660:44;;;;;;;;;;;;;;;;50156:556;49739:978;;;;;;;;;;;:::o;13661:20::-;;;;;;:::o;47825:405::-;47917:10;47880:6;47906:22;;;:10;:22;;;;;:33;;;47898:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47994:16;;;;47977:14;48025:15;;;:6;:15;;;;;47994:16;48025:25;;;;;;;:29;;;:50;;;48058:17;48067:7;48058:8;:17::i;:::-;48017:94;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48120:17;48140:14;:11;;;;;48152:1;;48140:11;:14;:::i;:::-;48120:34;;48161:39;48189:10;48161:27;:39::i;:::-;48207:17;;;-1:-1:-1;;47825:405:0;:::o;67065:294::-;67181:14;67204:13;67226:17;67252;67278:22;63300:31;63310:10;63322:8;;63300:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;63300:9:0;;-1:-1:-1;;;63300:31:0:i;:::-;63292:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67325:28:::1;67344:8;67325:18;:28::i;:::-;67318:35:::0;;;;-1:-1:-1;67318:35:0;;-1:-1:-1;67318:35:0;-1:-1:-1;67318:35:0;;-1:-1:-1;67065:294:0;-1:-1:-1;;67065:294:0:o;62242:179::-;14724:5;;;;14710:10;:19;14702:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62322:17:::1;::::0;::::1;;::::0;;;:10:::1;:17;::::0;;;;;::::1;;62317:99;;62350:17;::::0;::::1;;::::0;;;:10:::1;:17;::::0;;;;;;;;:24;;;::::1;62370:4;62350:24;::::0;;62390:18;;;;;;;::::1;::::0;;;;;;;;::::1;62242:179:::0;:::o;49315:186::-;49412:17;;49404:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49473:22;:20;:22::i;:::-;49315:186;;;;:::o;71199:162::-;71305:6;63300:31;63310:10;63322:8;;63300:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;63300:9:0;;-1:-1:-1;;;63300:31:0:i;:::-;63292:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71330:25:::1;71346:8;71330:15;:25::i;71880:169::-:0;71989:7;63300:31;63310:10;63322:8;;63300:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;63300:9:0;;-1:-1:-1;;;63300:31:0:i;:::-;63292:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72015:28:::1;72034:8;72015:18;:28::i;46155:370::-:0;14724:5;;;;14710:10;:19;14702:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46284:13:::1;:23:::0;46353:13:::1;::::0;46284:23:::1;::::0;;::::1;::::0;46372:7;;46323:45:::1;::::0;46337:30:::1;::::0;46353:13:::1;46337:15;:30::i;:::-;46323:9:::0;;:45:::1;:13;:45;:::i;:::-;:56;;46315:95;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;46425:9;::::0;:39:::1;::::0;;;;;:9:::1;:39:::0;;::::1;;::::0;::::1;::::0;;;;;;;;;:9;;;::::1;::::0;:18:::1;::::0;:39;;;;;::::1;::::0;;;;;;;;:9:::1;::::0;:39;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;2:2;46425:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;46425:39:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;46425:39:0;46417:73:::1;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;46497:22;:20;:22::i;29628:28::-:0;;;;;;:::o;29698:32::-;;;;;;;;;:::o;37682:119::-;37772:13;:23;;;;;;;37682:119::o;61559:24::-;;;;;;:::o;44891:145::-;45001:16;;44975:7;45001:16;;;:7;:16;;;;;:29;;;;44891:145::o;47006:280::-;47097:36;:16;;;;;;;:7;:16;;;;;:22;;;;;;;47123:10;47097:36;47089:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47167:16;;;;;;;;:7;:16;;;;;;;;;:29;;:41;;;;;;;;;;;;47222:58;;47258:10;47222:58;;;;;;;;;;;47167:16;;47222:58;;;;;;;;;;;47006:280;;:::o;14069:157::-;14724:5;;;;14710:10;:19;14702:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14150:12:::1;:18:::0;;;::::1;;::::0;;::::1;::::0;;::::1;::::0;;;-1:-1:-1;14209:5:0;;14182:38:::1;::::0;14150:18;;14209:5:::1;::::0;14182:38:::1;::::0;-1:-1:-1;14182:38:0::1;14069:157:::0;:::o;68673:277::-;68777:14;68800:13;68822:17;68848;68874:22;63300:31;63310:10;63322:8;;63300:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;63300:9:0;;-1:-1:-1;;;63300:31:0:i;:::-;63292:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68921:23:::1;:21;:23::i;:::-;68914:30;;;;;;;;;;68673:277:::0;;;;;:::o;59292:798::-;59467:16;;;59444:20;59467:16;;;:7;:16;;;;;:30;59518:16;;59392:12;;59467:30;;;;;;;;59518:16;59547:18;59543:51;;59567:27;;;;;;;;;;;;;;;;;;;;;;;59543:51;59621:8;59605:24;;:13;:24;;;59601:61;;;59631:31;;;;;;;;;;;;;;;;;;;;;;;59601:61;59673:16;;;;;;;:7;:16;;;;;:28;:39;;;;:28;;;;;:39;59669:78;;;59714:33;;;;;;;;;;;;;;;;;;;;;;;59669:78;59758:16;;;;;;;:7;:16;;;;;:34;:46;;;;:34;;;;;:46;59754:93;;59806:41;;;;;;;;;;;;;;;;;;;;;;;59754:93;59870:4;59858:16;;:8;:16;;;;:43;;;;-1:-1:-1;59890:11:0;:8;;;;;59899:1;;59890:8;:11;:::i;:::-;59878:23;;:8;:23;;;;59858:43;:92;;;;;59906:44;59935:8;59945:4;59906:28;:44::i;:::-;59905:45;59858:92;59854:130;;;59952:32;;;;;;;;;;;;;;;;;;;;;;;59854:130;59995:8;:13;;60007:1;59995:13;;:47;;;;-1:-1:-1;60013:29:0;60026:15;:12;;;;;60039:1;;60026:12;:15;:::i;:::-;60013:12;:29::i;:::-;60012:30;59995:47;59991:93;;;60044:40;;;;;;;;;;;;;;;;;;;;;;;59991:93;59292:798;;;;;;:::o;51733:369::-;51812:18;51821:8;51812;:18::i;:::-;51807:32;;51832:7;;51807:32;51875:10;51845:19;51867;;;:7;:19;;;;;:36;51963:12;;51867:36;;;;;;;;51963:12;;;;;;51949:26;;51937:38;;;;;;;:58;;-1:-1:-1;51979:16:0;;;51937:58;51933:71;;;51997:7;;;51933:71;52012:28;52031:8;52012:18;:28::i;:::-;-1:-1:-1;52057:10:0;52049:19;;;;:7;:19;;;;;:47;;;;;;;;;;;;;;51733:369;:::o;56547:401::-;56641:30;56662:8;56641:20;:30::i;:::-;56633:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56716:17;;;;;;;:7;:17;;;;;;;;27:10:-1;;39:1;23:18;;;45:23;;56716:47:0;;;;;;;;;;56778:10;56770:19;;;:7;:19;;;;;;:48;;;;;;;;;;56825:36;:50;;;56889:53;56778:10;;56716:17;:47;;56889:53;;56716:17;56889:53;56547:401;;:::o;54872:562::-;55011:17;;;;54944:4;55011:17;;;:7;:17;;;;;:32;;;;54972:36;;54944:4;;;;55011:32;;;;;-1:-1:-1;54968:111:0;;;-1:-1:-1;55062:5:0;;-1:-1:-1;55062:5:0;55054:17;;54968:111;55130:17;;;55087:16;55130:17;;;:7;:17;;;;;;;;55106:54;;;;;;;;;;;;;;;;;;;;;55130:17;55106:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:23;:54::i;:::-;55167:16;;;;;;;:6;:16;;;;;;;;;:35;;;55209:26;;:52;;;;;55245:15;55209:52;;;;;;;;;;;55268:43;;;;;;;;;55318:13;:24;;;;;;;;;;55356:39;;;;;;;55167:35;;-1:-1:-1;55167:16:0;;:35;;55356:39;;;;;;;;55412:4;;-1:-1:-1;55418:9:0;-1:-1:-1;54872:562:0;;;;:::o;56113:428::-;56190:17;;;56172:15;56190:17;;;:7;:17;;;;;:31;;;;;;;;56228:18;;:::i;:::-;-1:-1:-1;56228:34:0;;;;;;;;;56249:13;56228:34;;;;;;;;;;;;;;;;;56287:28;;56307:7;56287:28;:19;:28;:::i;:::-;56269:46;;;;;;56340:15;;;;:28;;:19;56360:7;56340:28;:19;:28;:::i;:::-;56322:46;;;;:15;;;;:46;;;56375:21;;:13;:21;;;;;;;;;;;;;;;;;;;;;;;56446:10;56375:21;56438:19;;;:7;:19;;;;;;:32;:45;;:32;56475:7;56438:45;:36;:45;:::i;:::-;56411:10;56403:19;;;;:7;:19;;;;;;:80;;;;;;;;;;;56519:15;;56497:38;;;;;;;56403:19;56497:38;56113:428;;;:::o;56954:190::-;57065:17;;;;;;;;:7;:17;;;;;:32;;;;57026:36;;57065:32;;-1:-1:-1;57022:84:0;;;57099:7;;57022:84;57121:17;;;;;;;:7;:17;;;;;;57114:24;57121:17;;57114:24;:::i;:::-;-1:-1:-1;57114:24:0;;;;;;;;56954:190;:::o;55440:667::-;55572:9;;;;55615:25;55611:38;;55642:7;;;55611:38;55657:16;55676:15;:12;;;;;55689:1;;55676:12;:15;:::i;:::-;55725:17;;;;55698:24;55725:17;;;:6;:17;;;;;;;;:33;;;;55790:24;;55960:130;;;;;55725:33;;;;;;55960:130;;;;;;;;;;;;;;;;;;;;;;;;;;;55657:34;;-1:-1:-1;55725:33:0;;55790:24;;55960:11;;;;;;30582:6;;55960:130;;;;;55725:17;;55960:130;;;;;;;;;:11;:130;;;2:2:-1;;;;27:1;24;17:12;2:2;55960:130:0;;;;;;;;;;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;55960:130:0;;;55956:146;;;;;;;55440:667;;;;;;:::o;57936:157::-;58015:7;58041:46;30430:1;58041:26;58053:13;:11;:13::i;:::-;58041:7;;:26;;;:11;:26;:::i;:::-;:30;:46;:30;:46;:::i;58792:494::-;58872:22;58886:7;58872:13;:22::i;:::-;58864:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58957:16;;:23;;:16;;;;;58978:1;;58957:20;:23;:::i;:::-;58926:16;;;;;;;:7;:16;;;;;:54;;;;;;;;;;;;;;;;;;;;59002:15;59018:29;-1:-1:-1;59026:13:0;:11;:13::i;:::-;59018:22;;;:29;:26;:29;:::i;:::-;59002:46;;;;;;;;;;;;;;;;;;;;;;59070:16;;;;;;:7;:16;;;;;;;:22;;;;;;59002:46;;;;59099:13;;;;;;:19;:27;;59070:22;;;;59099:27;;;;;;;;;59140:16;;;;59133:29;;;;;59169:15;:22;;59002:46;;-1:-1:-1;59070:22:0;;59002:46;;59169:15;59070:22;;59169;;;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;59205:15;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59240:40;;59205:21;59240:40;;;;;59205:21;;59240:40;58792:494;;;:::o;1001:167::-;1059:7;1087:5;;;1107:6;;;;1099:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58099:687;58198:22;58212:7;58198:13;:22::i;:::-;58197:23;58189:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58264:20;;;58256:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58325:36;:16;;;58359:1;58325:16;;;:7;:16;;;;;:22;;;;;;;:36;;:72;;-1:-1:-1;58365:32:0;:16;;;;;;;:7;:16;;;;;:22;;;;;;;;:32;;;;58325:72;58317:113;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58472:25;58489:7;58472:16;:25::i;:::-;58439:16;;;;;;;;:7;:16;;;;;;:58;;58504:40;58439:58;;;;;;;;;;;;58504:40;;;;;;;;58583:15;:22;;58551;;;;:55;;;;;;;;;;;;;;;;27:10:-1;;-1:-1;23:18;;;45:23;;;58613:29:0;;;;;;;;;;58649:16;;;:31;;;;;;;;;;;;;;;;;;58694:39;;-1:-1:-1;;58439:16:0;;58694:39;;58439:16;58694:39;58773:6;58745:35;;58764:7;58745:35;;;;;;;;;;;;58099:687;;:::o;16146:170::-;16204:7;16233:1;16228:6;;:1;:6;;;;16220:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16288:5:0;;;16146:170::o;1431:::-;1489:7;1518:1;1513;:6;;1505:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39167:146;39286:13;;;;;;;39254:6;39279:21;;;:6;:21;;;;;:28;;39167:146::o;40220:131::-;40332:13;;;;;;;;40220:131::o;61946:189::-;62095:17;;;62072:4;62095:17;;;:10;:17;;;;;;;;;:34;;-1:-1:-1;;62117:12:0;;;;62116:13;;61946:189;-1:-1:-1;;61946:189:0:o;39692:153::-;39815:13;;;;;;;39782:7;39808:21;;;:6;:21;;;;;:31;;;;;;;;;39692:153::o;52901:432::-;53043:23;;;53013:14;53043:23;;;:6;:23;;;;;:33;;;;;:37;53039:289;;53098:37;53119:15;53098:20;:37::i;:::-;:98;;;;;53139:45;53159:7;53168:15;53139:19;:45::i;:::-;:52;:57;53098:98;53091:105;;;;53039:289;53226:33;53234:7;53243:15;53226:7;:33::i;53339:1527::-;53744:16;;;53439:22;53744:16;;;:7;53698:9;53744:16;53698:9;53744:16;;53820;;53792:24;;53439:22;;;;;;;;;;;;;;53698:9;;53744:16;;53439:22;;53698:9;53820:16;;;53792:24;;;;;:44;;:87;;-1:-1:-1;53862:16:0;;53841:38;;53862:16;;53841:20;:38::i;:::-;53840:39;53792:87;54103:16;;53769:110;;-1:-1:-1;54090:30:0;;54103:16;;54090:12;:30::i;:::-;:49;;;;;54124:15;54090:49;54086:436;;;54161:16;;:23;;:16;;;;;54182:1;;54161:20;:23;:::i;:::-;54201:16;;;;;;;:6;:16;;;;;54245:13;;54150:34;;-1:-1:-1;54245:13:0;;;;;-1:-1:-1;54201:16:0;-1:-1:-1;54287:26:0;54295:7;54150:34;54287:7;:26::i;:::-;54267:46;;54086:436;;;54347:16;;;;;54380;;;:6;:16;;;;;;;;54424:7;:17;;;;;;54347:16;54424:31;;54347:16;;-1:-1:-1;54424:31:0;;;;;;;-1:-1:-1;54380:16:0;-1:-1:-1;54484:30:0;54347:16;54484:20;:30::i;:::-;54464:50;;54086:436;54534:38;54554:7;54563:8;54534:19;:38::i;:::-;:45;:50;54530:98;;54615:5;54595:25;;54530:98;54695:23;;;;;54727:15;;;;54751:17;;;;54727:15;54751:17;;;:7;:17;;;;;:25;;;;54785:13;:23;54652:17;;54678:8;;54695:23;54727:15;;;54751:25;;;;;54785:23;;54817:13;:11;:13::i;:::-;54839:14;54636:224;;;;;;;;;;;;;;;;;;;;;;;;53339:1527;;;;;;;;;:::o;57150:289::-;57257:16;;;;57222:4;57257:16;;;:6;:16;;;;;;;;:26;;;;;57312:7;:17;;;;;;:25;;57222:4;;57257:26;;;;;57312:25;;;;57351:13;;;;;:33;;;57383:1;57368:12;:16;;;57351:33;:82;;;;-1:-1:-1;57418:15:0;57388:27;:13;;;:27;;;;;:13;:27;:::i;:::-;:45;;;57351:82;57344:89;57150:289;-1:-1:-1;;;;57150:289:0:o;19277:163::-;19333:6;19359:5;;;19379:6;;;;;;;;;19371:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52108:413;52190:18;52199:8;52190;:18::i;:::-;52185:32;;52210:7;;52185:32;52256:10;52223:19;52245:22;;;:10;:22;;;;;:39;;;;;;;;;52347:28;;;;52333:42;;52322:53;;;;;:73;;-1:-1:-1;52379:16:0;;52322:73;52314:105;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52428:28;52447:8;52428:18;:28::i;:::-;-1:-1:-1;52476:10:0;52465:22;;;;:10;:22;;;;;:50;;;;;;;;;;;;;;52108:413;:::o;42731:500::-;42841:14;42864:13;42886:17;42912;42938:22;42978:14;;:::i;:::-;-1:-1:-1;42995:24:0;;;;;;;;:6;:24;;;;;;;;;42978:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43036:21;;;;:47;;;43061:22;43074:8;43061:22;;:12;:22::i;:::-;43085:16;;;;;;;;;;;;;;;;;43028:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27:10:-1;;8:100;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;43028:74:0;-1:-1:-1;43144:8:0;;43161:11;;;;43181;;;;43201:17;;;;;43127:8;;43144;;43111:114;;;;;-1:-1:-1;43111:114:0;;;-1:-1:-1;43111:114:0;;;;;-1:-1:-1;42731:500:0;-1:-1:-1;;42731:500:0:o;40773:221::-;40873:6;40895:22;40908:8;40895:12;:22::i;:::-;40891:83;;;-1:-1:-1;40935:24:0;;;;;;;:6;:24;;;;;:31;40928:38;;40891:83;-1:-1:-1;40987:1:0;40773:221;;;:::o;41449:228::-;41552:7;41575:22;41588:8;41575:12;:22::i;:::-;41571:86;;;-1:-1:-1;41615:24:0;;;;;;;:6;:24;;;;;:34;;;;;;;;41608:41;;44519:275;44617:14;44640:13;44662:17;44688;44714:22;44761:27;44774:13;;;;;;;;;;;44761:27;;:12;:27::i;57739:191::-;57845:4;57887:5;57868:24;;:15;57881:1;57868:8;:12;;;;:15;;;;:::i;:::-;:24;;;:56;;;;-1:-1:-1;;57896:13:0;;;;;;:6;:13;;;;;:23;;;;;;;;:28;;57739:191;-1:-1:-1;57739:191:0:o;19703:166::-;19759:6;19787:1;19782:6;;:1;:6;;;;19774:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60096:157;60195:16;;;60172:4;60195:16;;;:6;:16;;;;;:26;;;;;;;;:30;;;:52;;;60229:18;60238:8;60229;:18::i;60810:136::-;60917:16;;60882:4;;60917:23;;:16;;;;;60938:1;;60917:20;:23;:::i;:::-;60905:35;;:8;:35;;;60898:42;;60810:136;;;:::o;51232:495::-;51300:40;51324:15;:12;;;;;51337:1;;51324:12;:15;:::i;:::-;51300:23;:40::i;:::-;51349:16;:27;;;;;;;;;;51383:31;;:::i;:::-;-1:-1:-1;51417:135:0;;;-1:-1:-1;51417:135:0;;;51438:15;;;;;;;;51417:135;;51462:18;;;;;;;;51417:135;;;;;;;;51489:18;;;;;51417:135;;;;51516:7;;;;;-1:-1:-1;;;51417:135:0;51532:13;;;;51417:135;;;;51559:17;;;;:7;:17;;;;;:31;;;;51417:135;;;;51559:31;;:17;;:31;;;:::i;:::-;-1:-1:-1;51559:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51597:16;;-1:-1:-1;51597:16:0;;;:6;:16;;;;;:26;;;:52;;;;51633:15;51597:52;;;;;;;;;;;;51663:58;;51694:26;;51663:58;;;;51682:10;;51663:58;;;;;;;;;51232:495;;:::o;60412:150::-;60519:17;;;;60496:4;60519:17;;;:7;:17;;;;;:32;;;;:37;;;60412:150::o;6525:522::-;6611:6;6641:4;:11;6637:1;:15;6629:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6700:11;;6746:1;6740:7;;6758;;;6754:288;;6781:14;6804;6848:62;6863:4;6869:1;6878;6872:3;:7;6895:1;6881:11;:15;6898:11;6848:14;:62::i;:::-;6827:83;;-1:-1:-1;6827:83:0;-1:-1:-1;6926:36:0;6827:83;;6926:18;:36::i;:::-;6919:43;;;;;;;;6754:288;6992:42;7004:4;7010:1;7019;7013:3;:7;7022:11;6992;:42::i;:::-;6985:49;;;;;;15716:167;15774:7;15802:5;;;15822:6;;;;;;;;;15814:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1840:430;1898:7;2126:6;2122:37;;-1:-1:-1;2150:1:0;2143:8;;2122:37;2179:5;;;2183:1;2179;:5;:1;2199:5;;;;;:10;2191:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60259:147;60359:16;;60336:4;60359:16;;;:7;:16;;;;;:28;30523:7;60359:28;;;;;;:41;;60259:147::o;57445:288::-;57565:16;;57525:6;;57565:16;;57592:17;;;;;:65;;-1:-1:-1;57629:16:0;;;;;;;:7;:16;;;;;:28;;57613:44;;;57629:28;;;;;57613:44;57592:65;57588:107;;;57675:12;-1:-1:-1;57668:19:0;;57588:107;57708:19;:16;;;;;57725:1;;57708:16;:19;:::i;:::-;57701:26;57445:288;-1:-1:-1;;;57445:288:0:o;60568:236::-;60694:16;;;60656:4;60694:16;;;:7;:16;;;;;:33;60766:12;;60694:33;;;;;;;;60766:12;;;;;;60752:26;;60741:37;;;;;:57;;-1:-1:-1;60782:16:0;;60734:64;-1:-1:-1;;;60568:236:0:o;22819:163::-;22875:6;22901:5;;;22921:6;;;;;;;;;22913:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60952:127;30523:7;-1:-1:-1;61052:21:0;;60952:127::o;52527:368::-;52605:18;52614:8;52605;:18::i;:::-;52600:32;;52625:7;;52600:32;52640:13;52656:15;:12;;;;;52669:1;;52656:12;:15;:::i;:::-;52704:14;;;;;;;;:6;:14;;;;;;;;:21;;52678:16;;;;;;;;:47;;;52767:30;;;;;52732:32;;:65;;;;52767:30;;;;;;;;52732:65;;;;;;;52804:52;;;52840:15;52804:52;;;;;;;52872:7;:17;;;;;52704:14;;-1:-1:-1;52865:24:0;52872:17;52704:14;52865:24;:::i;:::-;-1:-1:-1;52865:24:0;;;;;;;;-1:-1:-1;52527:368:0;:::o;10716:831::-;10893:11;10906;10942:2;10937;:7;10929:16;;12:1:-1;9;2:12;10929:16:0;10966:2;10960;:8;;:20;;;;;10978:2;10972;:8;;10960:20;10952:29;;12:1:-1;9;2:12;10952:29:0;11002:2;10996;:8;;:20;;;;;11014:2;11008;:8;;10996:20;10988:29;;12:1:-1;9;2:12;10988:29:0;7180:1;11057:2;11052;:7;:35;11048:105;;;11107:36;11122:4;11128:2;11132;11136;11140;11107:14;:36::i;:::-;11100:43;;;;;;11048:105;11161:16;11180:23;11190:4;11196:2;11200;11180:9;:23::i;:::-;11161:42;;11222:8;11216:2;:14;11212:323;;11248:8;11243:13;;11212:323;;;11287:2;11276:8;:13;11272:263;;;11307:8;11318:1;11307:12;11302:17;;11272:263;;;11359:8;11353:2;:14;;:31;;;;;11382:2;11371:8;:13;11353:31;11346:39;;;;11403:35;11415:4;11421:2;11425:8;11435:2;11403:11;:35::i;:::-;11396:42;;11456:39;11468:4;11474:8;11485:1;11474:12;11488:2;11492;11456:11;:39::i;:::-;11449:46;-1:-1:-1;11506:19:0;;-1:-1:-1;11506:19:0;11272:263;11026:516;;;;10716:831;;;;;;;;:::o;5490:277::-;5563:6;5591:1;5586:2;:6;:16;;;;;5601:1;5596:2;:6;5586:16;5585:40;;;;5613:1;5608:2;:6;:16;;;;;5623:1;5618:2;:6;5608:16;5581:85;;;5657:1;5643:11;5647:2;5651;5643:3;:11::i;:::-;:15;;;;;;5636:22;;;;5581:85;5672:16;5711:1;5692:6;;;5701;;;5692:15;5691:21;;-1:-1:-1;5726:35:0;5730:19;5739:1;5734:2;:6;5747:1;5742:2;:6;5730:3;:19::i;:::-;5751:9;5726:3;:35::i;9744:798::-;9859:10;9895:1;9889:2;:7;;9881:16;;12:1:-1;9;2:12;9881:16:0;9917:2;9912:1;:7;;9904:16;;12:1:-1;9;2:12;9904:16:0;9939:2;9934;:7;9927:588;;;7180:1;9961:2;9956;:7;:35;9952:157;;;10004:13;10044:34;10059:4;10065:2;10069;10073:1;10076;10044:14;:34::i;:::-;-1:-1:-1;10028:50:0;-1:-1:-1;10089:10:0;;-1:-1:-1;10089:10:0;9952:157;10117:18;10138:23;10148:4;10154:2;10158;10138:9;:23::i;:::-;10117:44;;10179:10;10174:1;:15;10170:338;;10324:10;10319:15;;10170:338;;;10484:10;10497:1;10484:14;10479:19;;10170:338;9927:588;;;;10528:4;10533:2;10528:8;;;;;;;;;;;;;;10521:15;;9744:798;;;;;;:::o;7324:2258::-;7485:11;7498;7757;7780:2;7771;7776:1;7771:6;:11;7757:25;;7789:9;7801:4;7806:2;7811:1;7806:6;7801:12;;;;;;;;;;;;;;7789:24;;7820:9;7836:3;7832:1;:7;:32;;5858:8;7832:32;;;7842:4;7847:2;7852:1;7847:6;7842:12;;;;;;;;;;;;;;7832:32;7820:44;;7871:9;7887:3;7883:1;:7;:32;;5858:8;7883:32;;;7893:4;7898:2;7903:1;7898:6;7893:12;;;;;;;;;;;;;;7883:32;7871:44;;7922:9;7938:3;7934:1;:7;:32;;5858:8;7934:32;;;7944:4;7949:2;7954:1;7949:6;7944:12;;;;;;;;;;;;;;7934:32;7922:44;;7973:9;7989:3;7985:1;:7;:32;;5858:8;7985:32;;;7995:4;8000:2;8005:1;8000:6;7995:12;;;;;;;;;;;;;;7985:32;7973:44;;8024:9;8040:3;8036:1;:7;:32;;5858:8;8036:32;;;8046:4;8051:2;8056:1;8051:6;8046:12;;;;;;;;;;;;;;8036:32;8024:44;;8075:9;8091:3;8087:1;:7;:32;;5858:8;8087:32;;;8097:4;8102:2;8107:1;8102:6;8097:12;;;;;;;;;;;;;;8087:32;8075:44;;8137:2;8132;:7;8128:35;;;8154:2;;8158;8128:35;8178:2;8173;:7;8169:35;;;8195:2;;8199;8169:35;8219:2;8214;:7;8210:35;;;8236:2;;8240;8210:35;8260:2;8255;:7;8251:35;;;8277:2;;8281;8251:35;8301:2;8296;:7;8292:35;;;8318:2;;8322;8292:35;8342:2;8337;:7;8333:35;;;8359:2;8333:35;8383:2;8378;:7;8374:35;;;8400:2;;8404;8374:35;8424:2;8419;:7;8415:35;;;8441:2;8415:35;8465:2;8460;:7;8456:35;;;8482:2;;8486;8456:35;8506:2;8501;:7;8497:35;;;8523:2;;8527;8497:35;8547:2;8542;:7;8538:35;;;8564:2;8538:35;8588:2;8583;:7;8579:35;;;8605:2;;8609;8579:35;8629:2;8624;:7;8620:35;;;8646:2;8620:35;8670:2;8665;:7;8661:35;;;8687:2;;8691;8661:35;8711:2;8706;:7;8702:35;;;8728:2;;8732;8702:35;8752:2;8747;:7;8743:35;;;8769:2;;8773;8743:35;8803:7;;;8821:11;8817:309;;8842:2;8835:9;;8817:309;;;8861:6;8871:1;8861:11;8857:269;;;8882:2;8875:9;;8857:269;;;8901:6;8911:1;8901:11;8897:229;;;8922:2;8915:9;;8897:229;;;8941:6;8951:1;8941:11;8937:189;;;8962:2;8955:9;;8937:189;;;8981:6;8991:1;8981:11;8977:149;;;9002:2;8995:9;;8977:149;;;9021:6;9031:1;9021:11;9017:109;;;9042:2;9035:9;;9017:109;;;9061:6;9071:1;9061:11;9057:69;;;9082:2;9075:9;;9057:69;;;9098:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9057:69;9151:7;;;9169:8;;;9165:412;;;-1:-1:-1;9188:4:0;;-1:-1:-1;9180:19:0;;-1:-1:-1;;;;;;;;;9180:19:0;9165:412;9216:11;9212:365;;-1:-1:-1;9244:2:0;;-1:-1:-1;9230:17:0;;-1:-1:-1;;;;;;;;9230:17:0;9212:365;9264:6;9274:1;9264:11;9260:317;;;-1:-1:-1;9292:2:0;;-1:-1:-1;9278:17:0;;-1:-1:-1;;;;;;;;9278:17:0;9260:317;9312:6;9322:1;9312:11;9308:269;;;-1:-1:-1;9340:2:0;;-1:-1:-1;9326:17:0;;-1:-1:-1;;;;;;;;9326:17:0;9308:269;9360:6;9370:1;9360:11;9356:221;;;-1:-1:-1;9388:2:0;;-1:-1:-1;9374:17:0;;-1:-1:-1;;;;;;;;9374:17:0;9356:221;9408:6;9418:1;9408:11;9404:173;;;-1:-1:-1;9436:2:0;;-1:-1:-1;9422:17:0;;-1:-1:-1;;;;;;;;9422:17:0;9404:173;9456:6;9466:1;9456:11;9452:125;;;-1:-1:-1;9484:2:0;;-1:-1:-1;9470:17:0;;-1:-1:-1;;;;;;;;9470:17:0;9452:125;9504:6;9514:1;9504:11;9500:77;;;-1:-1:-1;9532:2:0;;-1:-1:-1;9518:17:0;;-1:-1:-1;;;;;;;;9518:17:0;9500:77;9549:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11879:1256;11981:7;;12153:4;12170:1;12159:7;;;12158:13;12153:19;;;;;;;;;;;;;;12138:34;;12185:1;12179:7;;;;12242:1;12236:7;;;;12250:880;12292:1;12286:7;;;;12322:5;12311:4;12316:2;12311:8;;;;;;;;;;;;;;:16;12272:57;;12337;12357:1;12351:7;;;;12387:5;12376:4;12381:2;12376:8;;;;;;;;;;;;;;:16;12337:57;;12411:2;12406;:7;12402:721;;;12450:4;12455:2;12450:8;;;;;;;;;;;;;;12460:4;12465:2;12460:8;;;;;;;;;;;;;;12427:4;12432:2;12427:8;;;;;;;;;;;;;12437:4;12442:2;12437:8;;;;;;;;;;;;;;;;;12426:43;;;;;12402:721;;;13111:2;13104:9;;;;;12402:721;12250:880;;5052:201;5108:6;5134:5;;;5155:6;;;;;;:16;;;5170:1;5165;:6;;5155:16;5154:38;;;;5181:1;5177;:5;:14;;;;;5190:1;5186;:5;5177:14;5146:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64512:7542;;;;;;;;;;-1:-1:-1;64512:7542:0;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;64512:7542:0;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;-1:-1:-1;64512:7542:0;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;64512:7542:0;;;-1:-1:-1;64512:7542:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;
Swarm Source
ipfs://3dfd5ae52fef7bbe05a195d698b0b1b8be56378daa346eaccbc52d24f39c30af
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.