More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 3,687 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Claim | 14678367 | 939 days ago | IN | 0 ETH | 0.00182233 | ||||
Swap | 14678366 | 939 days ago | IN | 0 ETH | 0.00580072 | ||||
Fill_pool | 14678341 | 939 days ago | IN | 0 ETH | 0.01130555 | ||||
Claim | 14678183 | 939 days ago | IN | 0 ETH | 0.00165945 | ||||
Swap | 14678182 | 939 days ago | IN | 0 ETH | 0.0042509 | ||||
Fill_pool | 14678171 | 939 days ago | IN | 0 ETH | 0.01019234 | ||||
Claim | 14677953 | 939 days ago | IN | 0 ETH | 0.00220089 | ||||
Swap | 14677952 | 939 days ago | IN | 0 ETH | 0.00565441 | ||||
Fill_pool | 14677944 | 939 days ago | IN | 0 ETH | 0.01071545 | ||||
Destruct | 14677883 | 939 days ago | IN | 0 ETH | 0.00314507 | ||||
Claim | 14677881 | 939 days ago | IN | 0 ETH | 0.00273212 | ||||
Swap | 14677879 | 939 days ago | IN | 0 ETH | 0.00559035 | ||||
Fill_pool | 14677871 | 939 days ago | IN | 0 ETH | 0.01115523 | ||||
Destruct | 14677853 | 939 days ago | IN | 0 ETH | 0.00396161 | ||||
Claim | 14677852 | 939 days ago | IN | 0 ETH | 0.00319361 | ||||
Swap | 14677851 | 939 days ago | IN | 0 ETH | 0.00681617 | ||||
Fill_pool | 14677837 | 939 days ago | IN | 0 ETH | 0.00942215 | ||||
Claim | 12539095 | 1272 days ago | IN | 0 ETH | 0.00099761 | ||||
Claim | 12515158 | 1276 days ago | IN | 0 ETH | 0.00193852 | ||||
Claim | 12508012 | 1277 days ago | IN | 0 ETH | 0.00193852 | ||||
Swap | 12505136 | 1278 days ago | IN | 0 ETH | 0.00112295 | ||||
Swap | 12501077 | 1278 days ago | IN | 0 ETH | 0.00356961 | ||||
Withdraw | 12473651 | 1282 days ago | IN | 0 ETH | 0.00181845 | ||||
Claim | 12468253 | 1283 days ago | IN | 0 ETH | 0.01290635 | ||||
Claim | 12468226 | 1283 days ago | IN | 0 ETH | 0.01369949 |
Loading...
Loading
Contract Name:
HappyTokenPool
Compiler Version
v0.8.1+commit.df193b15
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-04-27 */ // Sources flattened with hardhat v2.2.0 https://hardhat.org // File @openzeppelin/contracts/token/ERC20/[email protected] // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File @openzeppelin/contracts/utils/[email protected] pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File @openzeppelin/contracts/token/ERC20/utils/[email protected] pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File @openzeppelin/contracts/utils/math/[email protected] pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // 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 (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @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) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @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) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards 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). * * 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, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * 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, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } } // File @openzeppelin/contracts/utils/introspection/[email protected] pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File contracts/IQLF.sol /** * @author Yisi Liu * @contact [email protected] * @author_time 01/06/2021 **/ pragma solidity >= 0.8.0; abstract contract IQLF is IERC165 { /** * @dev Returns if the given address is qualified, implemented on demand. */ function ifQualified (address account) virtual external view returns (bool); /** * @dev Logs if the given address is qualified, implemented on demand. */ function logQualified (address account, uint256 ito_start_time) virtual external returns (bool); /** * @dev Ensure that custom contract implements `ifQualified` amd `logQualified` correctly. */ function supportsInterface(bytes4 interfaceId) virtual external override pure returns (bool) { return interfaceId == this.supportsInterface.selector || interfaceId == (this.ifQualified.selector ^ this.logQualified.selector); } /** * @dev Emit when `ifQualified` is called to decide if the given `address` * is `qualified` according to the preset rule by the contract creator and * the current block `number` and the current block `timestamp`. */ event Qualification(address account, bool qualified, uint256 blockNumber, uint256 timestamp); } // File contracts/ito.sol /** * @author Yisi Liu * @contact [email protected] * @author_time 01/06/2021 * @maintainer Hancheng Zhou, Yisi Liu * @maintain_time 04/15/2021 **/ pragma solidity >= 0.8.0; contract HappyTokenPool { struct Pool { uint256 packed1; // qualification_address(160) the smart contract address to verify qualification // hash(40) start_time_delta(28) // expiration_time_delta(28) BIG ENDIAN uint256 packed2; // total_tokens(128) limit(128) uint48 unlock_time; // unlock_time + base_time = real_time address creator; address token_address; // the target token address address[] exchange_addrs; // a list of ERC20 addresses for swapping uint128[] exchanged_tokens; // a list of amounts of swapped tokens uint128[] ratios; // a list of swap ratios // length = 2 * exchange_addrs.length // [address1, target, address2, target, ...] // e.g. [1, 10] // represents 1 tokenA to swap 10 target token // note: each ratio pair needs to be coprime mapping(address => uint256) swapped_map; // swapped amount of an address } struct Packed { uint256 packed1; uint256 packed2; } // swap pool filling success event event FillSuccess ( uint256 total, bytes32 id, address creator, uint256 creation_time, address token_address, string message ); // swap success event event SwapSuccess ( bytes32 id, address swapper, address from_address, address to_address, uint256 from_value, uint256 to_value ); // claim success event event ClaimSuccess ( bytes32 id, address claimer, uint256 timestamp, uint256 to_value, address token_address ); // swap pool destruct success event event DestructSuccess ( bytes32 id, address token_address, uint256 remaining_balance, uint128[] exchanged_values ); // single token withdrawl from a swap pool success even event WithdrawSuccess ( bytes32 id, address token_address, uint256 withdraw_balance ); modifier creatorOnly { require(msg.sender == contract_creator, "Contract Creator Only"); _; } using SafeERC20 for IERC20; uint32 nonce; uint224 base_time; // timestamp = base_time + delta to save gas address public contract_creator; mapping(bytes32 => Pool) pool_by_id; // maps an id to a Pool instance string constant private magic = "Prince Philip, Queen Elizabeth II's husband, has died aged 99, \ Buckingham Palace has announced. A statement issued by the palace just after midday spoke of the \ Queen's deep sorrow following his death at Windsor Castle on Friday morning. The Duke of Edinbur"; bytes32 private seed; address DEFAULT_ADDRESS = 0x0000000000000000000000000000000000000000; // a universal address constructor() { contract_creator = msg.sender; seed = keccak256(abi.encodePacked(magic, block.timestamp, contract_creator)); base_time = 1616976000; // 00:00:00 03/30/2021 GMT(UTC+0) } /** * @dev * fill_pool() creates a swap pool with specific parameters from input * _hash sha3-256(password) * _start start time delta, real start time = base_time + _start * _end end time delta, real end time = base_time + _end * message swap pool creation message, only stored in FillSuccess event * _exchange_addrs swap token list (0x0 for ETH, only supports ETH and ERC20 now) * _ratios swap pair ratio list * _unlock_time unlock time delta real unlock time = base_time + _unlock_time * _token_addr swap target token address * _total_tokens target token total swap amount * _limit target token single swap limit * _qualification the qualification contract address based on IQLF to determine qualification * This function takes the above parameters and creates the pool. _total_tokens of the target token * will be successfully transferred to this contract securely on a successful run of this function. **/ function fill_pool (bytes32 _hash, uint256 _start, uint256 _end, string memory message, address[] memory _exchange_addrs, uint128[] memory _ratios, uint256 _unlock_time, address _token_addr, uint256 _total_tokens, uint256 _limit, address _qualification) public payable { nonce ++; require(_start < _end, "Start time should be earlier than end time."); require(_end < _unlock_time || _unlock_time == 0, "End time should be earlier than unlock time"); require(_limit <= _total_tokens, "Limit needs to be less than or equal to the total supply"); require(_total_tokens < 2 ** 128, "No more than 2^128 tokens(incluidng decimals) allowed"); require(IERC20(_token_addr).allowance(msg.sender, address(this)) >= _total_tokens, "Insuffcient allowance"); require(_exchange_addrs.length > 0, "Exchange token addresses need to be set"); require(_ratios.length == 2 * _exchange_addrs.length, "Size of ratios = 2 * size of exchange_addrs"); bytes32 _id = keccak256(abi.encodePacked(msg.sender, block.timestamp, nonce, seed)); Pool storage pool = pool_by_id[_id]; pool.packed1 = wrap1(_qualification, _hash, _start, _end); // 256 bytes detail in wrap1() pool.packed2 = wrap2(_total_tokens, _limit); // 256 bytes detail in wrap2() pool.unlock_time = uint48(_unlock_time); // 48 bytes unlock_time 0 -> unlocked pool.creator = msg.sender; // 160 bytes pool creator pool.exchange_addrs = _exchange_addrs; // 160 bytes target token pool.token_address = _token_addr; // 160 bytes target token address // Init each token swapped amount to 0 for (uint256 i = 0; i < _exchange_addrs.length; i++) { if (_exchange_addrs[i] != DEFAULT_ADDRESS) { // TODO: Is there a better way to validate an ERC20? require(IERC20(_exchange_addrs[i]).totalSupply() > 0, "Not a valid ERC20"); } pool.exchanged_tokens.push(0); } // Make sure each ratio is co-prime to prevent overflow for (uint256 i = 0; i < _ratios.length; i+= 2) { uint256 divA = SafeMath.div(_ratios[i], _ratios[i+1]); // Non-zero checked by SafteMath.div uint256 divB = SafeMath.div(_ratios[i+1], _ratios[i]); // Non-zero checked by SafteMath.div if (_ratios[i] == 1) { require(divB == _ratios[i+1]); } else if (_ratios[i+1] == 1) { require(divA == _ratios[i]); } else { // if a and b are co-prime, then a / b * b != a and b / a * a != b require(divA * _ratios[i+1] != _ratios[i]); require(divB * _ratios[i] != _ratios[i+1]); } } pool.ratios = _ratios; // 256 * k IERC20(_token_addr).safeTransferFrom(msg.sender, address(this), _total_tokens); emit FillSuccess(_total_tokens, _id, msg.sender, block.timestamp, _token_addr, message); } /** * @dev * swap() allows users to swap tokens in a swap pool * id swap pool id * verification sha3-256(sha3-256(password)[:40]+swapper_address) * validation sha3-256(swapper_address) * exchange_addr_i the index of the exchange address of the list * input_total the input amount of the specific token * This function is called by the swapper who approves the specific ERC20 or directly transfer the ETH * first and wants to swap the desired amount of the target token. The swapped amount is calculated * based on the pool ratio. After swap successfully, the same account can not swap the same pool again. **/ function swap (bytes32 id, bytes32 verification, bytes32 validation, uint256 exchange_addr_i, uint128 input_total) public payable returns (uint256 swapped) { Pool storage pool = pool_by_id[id]; Packed memory packed = Packed(pool.packed1, pool.packed2); require ( IQLF( address( uint160(unbox(packed.packed1, 0, 160))) ).logQualified(msg.sender, uint256(unbox(packed.packed1, 200, 28) + base_time) ) == true, "Not Qualified" ); require (unbox(packed.packed1, 200, 28) + base_time < block.timestamp, "Not started."); require (unbox(packed.packed1, 228, 28) + base_time > block.timestamp, "Expired."); // sha3(sha3(passowrd)[:40] + msg.sender) so that the raw password will never appear in the contract require (verification == keccak256(abi.encodePacked(unbox(packed.packed1, 160, 40), msg.sender)), 'Wrong Password'); // sha3(msg.sender) to protect from front runs (but this is kinda naive since the contract is open sourced) require (validation == keccak256(abi.encodePacked(msg.sender)), "Validation Failed"); uint256 total_tokens = unbox(packed.packed2, 0, 128); // revert if the pool is empty require (total_tokens > 0, "Out of Stock"); address exchange_addr = pool.exchange_addrs[exchange_addr_i]; uint256 ratioA = pool.ratios[exchange_addr_i*2]; uint256 ratioB = pool.ratios[exchange_addr_i*2 + 1]; // check if the input is enough for the desired transfer if (exchange_addr == DEFAULT_ADDRESS) { require(msg.value == input_total, 'No enough ether.'); } else { uint256 allowance = IERC20(exchange_addr).allowance(msg.sender, address(this)); require(allowance >= input_total, 'No enough allowance.'); } uint256 swapped_tokens; // this calculation won't be overflow thanks to the SafeMath and the co-prime test swapped_tokens = SafeMath.div(SafeMath.mul(input_total, ratioB), ratioA); // 2^256=10e77 >> 10e18 * 10e18 require(swapped_tokens > 0, "Better not draw water with a sieve"); uint256 limit = unbox(packed.packed2, 128, 128); if (swapped_tokens > limit) { // don't be greedy - you can only get at most limit tokens swapped_tokens = limit; input_total = uint128(SafeMath.div(SafeMath.mul(limit, ratioA), ratioB)); // Update input_total } else if (swapped_tokens > total_tokens) { // if the left tokens are not enough swapped_tokens = total_tokens; input_total = uint128(SafeMath.div(SafeMath.mul(total_tokens, ratioA), ratioB)); // Update input_total // return the eth if (exchange_addr == DEFAULT_ADDRESS) payable(msg.sender).transfer(msg.value - input_total); } require(swapped_tokens <= limit); // make sure again pool.exchanged_tokens[exchange_addr_i] = uint128(SafeMath.add(pool.exchanged_tokens[exchange_addr_i], input_total)); // update exchanged // penalize greedy attackers by placing duplication check at the very last require (pool.swapped_map[msg.sender] == 0, "Already swapped"); // update the remaining tokens and swapped token mapping pool.packed2 = rewriteBox(packed.packed2, 0, 128, SafeMath.sub(total_tokens, swapped_tokens)); pool.swapped_map[msg.sender] = swapped_tokens; // transfer the token after state changing // ETH comes with the tx, but ERC20 does not - INPUT if (exchange_addr != DEFAULT_ADDRESS) { IERC20(exchange_addr).safeTransferFrom(msg.sender, address(this), input_total); } // Swap success event emit SwapSuccess(id, msg.sender, exchange_addr, pool.token_address, input_total, swapped_tokens); // if unlock_time == 0, transfer the swapped tokens to the recipient address (msg.sender) - OUTPUT // if not, claim() needs to be called to get the token if (pool.unlock_time == 0) { transfer_token(pool.token_address, address(this), msg.sender, swapped_tokens); emit ClaimSuccess(id, msg.sender, block.timestamp, swapped_tokens, pool.token_address); } return swapped_tokens; } /** * check_availability() returns a bunch of pool info given a pool id * id swap pool id * this function returns 1. exchange_addrs that can be used to determine the index * 2. remaining target tokens * 3. if started * 4. if ended * 5. swapped amount of the query address * 5. exchanged amount of each token **/ function check_availability (bytes32 id) external view returns (address[] memory exchange_addrs, uint256 remaining, bool started, bool expired, bool unlocked, uint256 unlock_time, uint256 swapped, uint128[] memory exchanged_tokens) { Pool storage pool = pool_by_id[id]; return ( pool.exchange_addrs, // exchange_addrs 0x0 means destructed unbox(pool.packed2, 0, 128), // remaining block.timestamp > unbox(pool.packed1, 200, 28) + base_time, // started block.timestamp > unbox(pool.packed1, 228, 28) + base_time, // expired block.timestamp > pool.unlock_time + base_time, // unlocked pool.unlock_time + base_time, // unlock_time pool.swapped_map[msg.sender], // swapped number pool.exchanged_tokens // exchanged tokens ); } function claim(bytes32[] memory ito_ids) public { uint256 claimed_amount; for (uint256 i = 0; i < ito_ids.length; i++) { Pool storage pool = pool_by_id[ito_ids[i]]; if (pool.unlock_time + base_time > block.timestamp) continue; claimed_amount = pool.swapped_map[msg.sender]; if (claimed_amount == 0) continue; pool.swapped_map[msg.sender] = 0; transfer_token(pool.token_address, address(this), msg.sender, claimed_amount); emit ClaimSuccess(ito_ids[i], msg.sender, block.timestamp, claimed_amount, pool.token_address); } } function setUnlockTime(bytes32 id, uint256 _unlock_time) public { Pool storage pool = pool_by_id[id]; require(pool.creator == msg.sender, "Pool Creator Only"); pool.unlock_time = uint48(_unlock_time); } /** * destruct() destructs the given pool given the pool id * id swap pool id * this function can only be called by the pool creator. after validation, it transfers all the remaining token * (if any) and all the swapped tokens to the pool creator. it will then destruct the pool by reseting almost * all the variables to zero to get the gas refund. * note that this function may not work if a pool needs to transfer over ~200 tokens back to the address due to * the block gas limit. we have another function withdraw() to help the pool creator to withdraw a single token **/ function destruct (bytes32 id) public { Pool storage pool = pool_by_id[id]; require(msg.sender == pool.creator, "Only the pool creator can destruct."); uint256 expiration = unbox(pool.packed1, 228, 28) + base_time; uint256 remaining_tokens = unbox(pool.packed2, 0, 128); // only after expiration or the pool is empty require(expiration <= block.timestamp || remaining_tokens == 0, "Not expired yet"); // if any left in the pool if (remaining_tokens != 0) { transfer_token(pool.token_address, address(this), msg.sender, remaining_tokens); } // transfer the swapped tokens accordingly // note this loop may exceed the block gas limit so if >200 exchange_addrs this may not work for (uint256 i = 0; i < pool.exchange_addrs.length; i++) { if (pool.exchanged_tokens[i] > 0) { // ERC20 if (pool.exchange_addrs[i] != DEFAULT_ADDRESS) transfer_token(pool.exchange_addrs[i], address(this), msg.sender, pool.exchanged_tokens[i]); // ETH else payable(msg.sender).transfer(pool.exchanged_tokens[i]); } } emit DestructSuccess(id, pool.token_address, remaining_tokens, pool.exchanged_tokens); // Gas Refund pool.packed1 = 0; pool.packed2 = 0; pool.creator = DEFAULT_ADDRESS; for (uint256 i = 0; i < pool.exchange_addrs.length; i++) { pool.exchange_addrs[i] = DEFAULT_ADDRESS; pool.exchanged_tokens[i] = 0; pool.ratios[i*2] = 0; pool.ratios[i*2+1] = 0; } } /** * withdraw() transfers out a single token after a pool is expired or empty * id swap pool id * addr_i withdraw token index * this function can only be called by the pool creator. after validation, it transfers the addr_i th token * out to the pool creator address. **/ function withdraw (bytes32 id, uint256 addr_i) public { Pool storage pool = pool_by_id[id]; require(msg.sender == pool.creator, "Only the pool creator can withdraw."); uint256 withdraw_balance = pool.exchanged_tokens[addr_i]; require(withdraw_balance > 0, "None of this token left"); uint256 expiration = unbox(pool.packed1, 228, 28) + base_time; uint256 remaining_tokens = unbox(pool.packed2, 0, 128); // only after expiration or the pool is empty require(expiration <= block.timestamp || remaining_tokens == 0, "Not expired yet"); address token_address = pool.exchange_addrs[addr_i]; // ERC20 if (token_address != DEFAULT_ADDRESS) transfer_token(token_address, address(this), msg.sender, withdraw_balance); // ETH else payable(msg.sender).transfer(withdraw_balance); // clear the record pool.exchanged_tokens[addr_i] = 0; emit WithdrawSuccess(id, token_address, withdraw_balance); } // helper functions TODO: migrate this to a helper file /** * _qualification the smart contract address to verify qualification 160 * _hash sha3-256(password) 40 * _start start time delta 28 * _end end time delta 28 * wrap1() inserts the above variables into a 32-word block **/ function wrap1 (address _qualification, bytes32 _hash, uint256 _start, uint256 _end) internal pure returns (uint256 packed1) { uint256 _packed1 = 0; _packed1 |= box(0, 160, uint256(uint160(_qualification))); // _qualification = 160 bits _packed1 |= box(160, 40, uint256(_hash) >> 216); // hash = 40 bits (safe?) _packed1 |= box(200, 28, _start); // start_time = 28 bits _packed1 |= box(228, 28, _end); // expiration_time = 28 bits return _packed1; } /** * _total_tokens target remaining 128 * _limit single swap limit 128 * wrap2() inserts the above variables into a 32-word block **/ function wrap2 (uint256 _total_tokens, uint256 _limit) internal pure returns (uint256 packed2) { uint256 _packed2 = 0; _packed2 |= box(0, 128, _total_tokens); // total_tokens = 128 bits ~= 3.4e38 _packed2 |= box(128, 128, _limit); // limit = 128 bits return _packed2; } /** * position position in a memory block * size data size * data data * box() inserts the data in a 256bit word with the given position and returns it * data is checked by validRange() to make sure it is not over size **/ function box (uint16 position, uint16 size, uint256 data) internal pure returns (uint256 boxed) { require(validRange(size, data), "Value out of range BOX"); assembly { // data << position boxed := shl(position, data) } } /** * position position in a memory block * size data size * base base data * unbox() extracts the data out of a 256bit word with the given position and returns it * base is checked by validRange() to make sure it is not over size **/ function unbox (uint256 base, uint16 position, uint16 size) internal pure returns (uint256 unboxed) { require(validRange(256, base), "Value out of range UNBOX"); assembly { // (((1 << size) - 1) & base >> position) unboxed := and(sub(shl(size, 1), 1), shr(position, base)) } } /** * size data size * data data * validRange() checks if the given data is over the specified data size **/ function validRange (uint16 size, uint256 data) internal pure returns(bool ifValid) { assembly { // 2^size > data or size ==256 ifValid := or(eq(size, 256), gt(shl(size, 1), data)) } } /** * _box 32byte data to be modified * position position in a memory block * size data size * data data to be inserted * rewriteBox() updates a 32byte word with a data at the given position with the specified size **/ function rewriteBox (uint256 _box, uint16 position, uint16 size, uint256 data) internal pure returns (uint256 boxed) { assembly { // mask = ~((1 << size - 1) << position) // _box = (mask & _box) | ()data << position) boxed := or( and(_box, not(shl(position, sub(shl(size, 1), 1)))), shl(position, data)) } } /** * token_address ERC20 address * sender_address sender address * recipient_address recipient address * amount transfer amount * transfer_token() transfers a given amount of ERC20 from the sender address to the recipient address **/ function transfer_token (address token_address, address sender_address, address recipient_address, uint256 amount) internal { require(IERC20(token_address).balanceOf(sender_address) >= amount, "Balance not enough"); IERC20(token_address).safeTransfer(recipient_address, amount); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"claimer","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"to_value","type":"uint256"},{"indexed":false,"internalType":"address","name":"token_address","type":"address"}],"name":"ClaimSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"token_address","type":"address"},{"indexed":false,"internalType":"uint256","name":"remaining_balance","type":"uint256"},{"indexed":false,"internalType":"uint128[]","name":"exchanged_values","type":"uint128[]"}],"name":"DestructSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"total","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"creator","type":"address"},{"indexed":false,"internalType":"uint256","name":"creation_time","type":"uint256"},{"indexed":false,"internalType":"address","name":"token_address","type":"address"},{"indexed":false,"internalType":"string","name":"message","type":"string"}],"name":"FillSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"swapper","type":"address"},{"indexed":false,"internalType":"address","name":"from_address","type":"address"},{"indexed":false,"internalType":"address","name":"to_address","type":"address"},{"indexed":false,"internalType":"uint256","name":"from_value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"to_value","type":"uint256"}],"name":"SwapSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"token_address","type":"address"},{"indexed":false,"internalType":"uint256","name":"withdraw_balance","type":"uint256"}],"name":"WithdrawSuccess","type":"event"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"check_availability","outputs":[{"internalType":"address[]","name":"exchange_addrs","type":"address[]"},{"internalType":"uint256","name":"remaining","type":"uint256"},{"internalType":"bool","name":"started","type":"bool"},{"internalType":"bool","name":"expired","type":"bool"},{"internalType":"bool","name":"unlocked","type":"bool"},{"internalType":"uint256","name":"unlock_time","type":"uint256"},{"internalType":"uint256","name":"swapped","type":"uint256"},{"internalType":"uint128[]","name":"exchanged_tokens","type":"uint128[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"ito_ids","type":"bytes32[]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contract_creator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"destruct","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"},{"internalType":"string","name":"message","type":"string"},{"internalType":"address[]","name":"_exchange_addrs","type":"address[]"},{"internalType":"uint128[]","name":"_ratios","type":"uint128[]"},{"internalType":"uint256","name":"_unlock_time","type":"uint256"},{"internalType":"address","name":"_token_addr","type":"address"},{"internalType":"uint256","name":"_total_tokens","type":"uint256"},{"internalType":"uint256","name":"_limit","type":"uint256"},{"internalType":"address","name":"_qualification","type":"address"}],"name":"fill_pool","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"uint256","name":"_unlock_time","type":"uint256"}],"name":"setUnlockTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"bytes32","name":"verification","type":"bytes32"},{"internalType":"bytes32","name":"validation","type":"bytes32"},{"internalType":"uint256","name":"exchange_addr_i","type":"uint256"},{"internalType":"uint128","name":"input_total","type":"uint128"}],"name":"swap","outputs":[{"internalType":"uint256","name":"swapped","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"uint256","name":"addr_i","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052600480546001600160a01b03191690553480156200002157600080fd5b50600180546001600160a01b03191633179055604080516101408101909152610108808252620031cc602083013960015460405162000072929142916001600160a01b0390911690602001620000a9565b60408051808303601f1901815291905280516020909101206003556000805463ffffffff16676061188000000000179055620000fd565b60008451815b81811015620000cb5760208188018101518583015201620000af565b81811115620000da5782828501525b50919091019283525060601b6001600160601b0319166020820152603401919050565b6130bf806200010d6000396000f3fe60806040526004361061007b5760003560e01c8063c6d898341161004e578063c6d8983414610121578063cc0cab4c14610141578063ec0e3d9a14610161578063ef65dc7e146101815761007b565b8063040cf020146100805780636bfdaece146100a2578063b391c508146100df578063bf5c2920146100ff575b600080fd5b34801561008c57600080fd5b506100a061009b3660046123b3565b610194565b005b3480156100ae57600080fd5b506100c26100bd366004612353565b6103e4565b6040516100d6989796959493929190612646565b60405180910390f35b3480156100eb57600080fd5b506100a06100fa3660046122a3565b610605565b34801561010b57600080fd5b50610114610776565b6040516100d691906125db565b61013461012f36600461236b565b610785565b6040516100d69190612ea3565b34801561014d57600080fd5b506100a061015c366004612353565b610f3d565b34801561016d57600080fd5b506100a061017c3660046123b3565b611448565b6100a061018f3660046123d4565b6114ad565b600082815260026020819052604090912090810154600160301b90046001600160a01b031633146101e05760405162461bcd60e51b81526004016101d790612d4f565b60405180910390fd5b600081600501838154811061020557634e487b7160e01b600052603260045260246000fd5b6000918252602090912060028204015460019091166010026101000a90046001600160801b031690508061024b5760405162461bcd60e51b81526004016101d790612a7a565b600080548354600160201b9091046001600160e01b0316906102709060e4601c611bfa565b61027a9190612f84565b9050600061028f846001015460006080611bfa565b9050428211158061029e575080155b6102ba5760405162461bcd60e51b81526004016101d790612a06565b60008460040186815481106102df57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546004546001600160a01b0391821692501681146103135761030e81303387611c35565b610342565b604051339085156108fc029086906000818181858888f19350505050158015610340573d6000803e3d6000fd5b505b600085600501878154811061036757634e487b7160e01b600052603260045260246000fd5b90600052602060002090600291828204019190066010026101000a8154816001600160801b0302191690836001600160801b031602179055507fab5315d16ef405a1f4e8c34017af486f59f27097e003d2a1981ae682c2f367318782866040516103d393929190612723565b60405180910390a150505050505050565b606060008060008060008060606000600260008b815260200190815260200160002090508060040161041d826001015460006080611bfa565b6000548354600160201b9091046001600160e01b0316906104419060c8601c611bfa565b61044b9190612f84565b4211600060049054906101000a90046001600160e01b03166001600160e01b031661047d856000015460e4601c611bfa565b6104879190612f84565b60005460028601544292909211916104b791600160201b90046001600160e01b03169065ffffffffffff16612f59565b60005460028701546001600160e01b039283164211926104e792600160201b9004169065ffffffffffff16612f59565b336000908152600788016020908152604091829020548854835181840281018401909452808452909260058b019290918a9183018282801561055257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610534575b50505050509750826001600160e01b03169250808054806020026020016040519081016040528092919081815260200182805480156105e257602002820191906000526020600020906000905b82829054906101000a90046001600160801b03166001600160801b031681526020019060100190602082600f0104928301926001038202915080841161059f5790505b505050505090509850985098509850985098509850985050919395975091939597565b6000805b82518110156107715760006002600085848151811061063857634e487b7160e01b600052603260045260246000fd5b6020908102919091018101518252810191909152604001600090812090546002820154919250429161068291600160201b90046001600160e01b03169065ffffffffffff16612f59565b6001600160e01b03161115610697575061075f565b3360009081526007820160205260409020549250826106b6575061075f565b33600081815260078301602052604081205560038201546106e5916001600160a01b0390911690309086611c35565b7f0b8bdb11ddec1f8dd879bd98afac7c33c30ce590fcbc26ed559df98f9a38111984838151811061072657634e487b7160e01b600052603260045260246000fd5b6020908102919091010151600383015460405161075592913391429189916001600160a01b039091169061281a565b60405180910390a1505b806107698161301e565b915050610609565b505050565b6001546001600160a01b031681565b600085815260026020908152604080832081518083019092528054808352600182015493830193909352916107bc908460a0611bfa565b6001600160a01b0316637938037233600060049054906101000a90046001600160e01b03166001600160e01b03166107fb856000015160c8601c611bfa565b6108059190612f84565b6040518363ffffffff1660e01b815260040161082292919061262d565b602060405180830381600087803b15801561083c57600080fd5b505af1158015610850573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108749190612333565b15156001146108955760405162461bcd60e51b81526004016101d790612dbc565b60005481514291600160201b90046001600160e01b0316906108ba9060c8601c611bfa565b6108c49190612f84565b106108e15760405162461bcd60e51b81526004016101d790612c95565b60005481514291600160201b90046001600160e01b0316906109069060e4601c611bfa565b6109109190612f84565b1161092d5760405162461bcd60e51b81526004016101d790612c43565b805161093c9060a06028611bfa565b3360405160200161094e9291906125c0565b6040516020818303038152906040528051906020012087146109825760405162461bcd60e51b81526004016101d790612ab1565b336040516020016109939190612555565b6040516020818303038152906040528051906020012086146109c75760405162461bcd60e51b81526004016101d790612e2d565b60006109da826020015160006080611bfa565b9050600081116109fc5760405162461bcd60e51b81526004016101d790612b1f565b6000836004018781548110610a2157634e487b7160e01b600052603260045260246000fd5b60009182526020822001546001600160a01b0316915060068501610a46896002612fbc565b81548110610a6457634e487b7160e01b600052603260045260246000fd5b90600052602060002090600291828204019190066010029054906101000a90046001600160801b03166001600160801b03169050600085600601896002610aab9190612fbc565b610ab6906001612f84565b81548110610ad457634e487b7160e01b600052603260045260246000fd5b6000918252602090912060028204015460045460019092166010026101000a90046001600160801b031691506001600160a01b039081169084161415610b4157876001600160801b03163414610b3c5760405162461bcd60e51b81526004016101d790612d92565b610bef565b604051636eb1769f60e11b81526000906001600160a01b0385169063dd62ed3e90610b7290339030906004016125ef565b60206040518083038186803b158015610b8a57600080fd5b505afa158015610b9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc291906124bb565b9050886001600160801b0316811015610bed5760405162461bcd60e51b81526004016101d790612b74565b505b6000610c0d610c078a6001600160801b031684611ceb565b84611cfe565b905060008111610c2f5760405162461bcd60e51b81526004016101d790612890565b6000610c418760200151608080611bfa565b905080821115610c6257809150610c5b610c078286611ceb565b9950610cd4565b85821115610cd457859150610c7a610c078786611ceb565b600454909a506001600160a01b0386811691161415610cd457336108fc610caa6001600160801b038d1634612fdb565b6040518115909202916000818181858888f19350505050158015610cd2573d6000803e3d6000fd5b505b80821115610ce157600080fd5b610d48886005018c81548110610d0757634e487b7160e01b600052603260045260246000fd5b90600052602060002090600291828204019190066010029054906101000a90046001600160801b03166001600160801b03168b6001600160801b0316611d0a565b886005018c81548110610d6b57634e487b7160e01b600052603260045260246000fd5b90600052602060002090600291828204019190066010026101000a8154816001600160801b0302191690836001600160801b03160217905550876007016000336001600160a01b03166001600160a01b0316815260200190815260200160002054600014610deb5760405162461bcd60e51b81526004016101d7906129dd565b610e06876020015160006080610e018a87611d16565b611d22565b600189015533600090815260078901602052604090208290556004546001600160a01b03868116911614610e5257610e526001600160a01b03861633306001600160801b038e16611d39565b7fa6a9350e3cb78ab6117ff3f716716cb2a1c40e92008df3c4f60e976ee6d56edc8e33878b60030160009054906101000a90046001600160a01b03168e87604051610ea2969594939291906126e6565b60405180910390a1600288015465ffffffffffff16610f2c576003880154610ed5906001600160a01b0316303385611c35565b7f0b8bdb11ddec1f8dd879bd98afac7c33c30ce590fcbc26ed559df98f9a3811198e3342858c60030160009054906101000a90046001600160a01b0316604051610f2395949392919061281a565b60405180910390a15b509c9b505050505050505050505050565b600081815260026020819052604090912090810154600160301b90046001600160a01b03163314610f805760405162461bcd60e51b81526004016101d7906128d2565b600080548254600160201b9091046001600160e01b031690610fa59060e4601c611bfa565b610faf9190612f84565b90506000610fc4836001015460006080611bfa565b90504282111580610fd3575080155b610fef5760405162461bcd60e51b81526004016101d790612a06565b801561100f57600383015461100f906001600160a01b0316303384611c35565b60005b60048401548110156111f857600084600501828154811061104357634e487b7160e01b600052603260045260246000fd5b6000918252602090912060028204015460019091166010026101000a90046001600160801b031611156111e6576004805490850180546001600160a01b0390921691839081106110a357634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b031614611157576111528460040182815481106110e357634e487b7160e01b600052603260045260246000fd5b9060005260206000200160009054906101000a90046001600160a01b0316303387600501858154811061112657634e487b7160e01b600052603260045260246000fd5b6000918252602090912060028204015460019091166010026101000a90046001600160801b0316611c35565b6111e6565b336001600160a01b03166108fc85600501838154811061118757634e487b7160e01b600052603260045260246000fd5b90600052602060002090600291828204019190066010029054906101000a90046001600160801b03166001600160801b03169081150290604051600060405180830381858888f193505050501580156111e4573d6000803e3d6000fd5b505b806111f08161301e565b915050611012565b5060038301546040517f01a1fd9d8a4231d7bd8926ce16b753ba03e0310e0a776f13eba8e0c3cba7ea899161123f9187916001600160a01b03169085906005890190612742565b60405180910390a16000808455600184018190556004546002850180546601000000000000600160d01b0319166001600160a01b03909216600160301b029190911790555b6004840154811015611441576004805490850180546001600160a01b0390921691839081106112c357634e487b7160e01b600052603260045260246000fd5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600084600501828154811061131657634e487b7160e01b600052603260045260246000fd5b90600052602060002090600291828204019190066010026101000a8154816001600160801b0302191690836001600160801b031602179055506000846006018260026113629190612fbc565b8154811061138057634e487b7160e01b600052603260045260246000fd5b90600052602060002090600291828204019190066010026101000a8154816001600160801b0302191690836001600160801b031602179055506000846006018260026113cc9190612fbc565b6113d7906001612f84565b815481106113f557634e487b7160e01b600052603260045260246000fd5b90600052602060002090600291828204019190066010026101000a8154816001600160801b0302191690836001600160801b0316021790555080806114399061301e565b915050611284565b5050505050565b600082815260026020819052604090912090810154600160301b90046001600160a01b0316331461148b5760405162461bcd60e51b81526004016101d790612c18565b600201805465ffffffffffff191665ffffffffffff9290921691909117905550565b6000805463ffffffff1690806114c283613039565b91906101000a81548163ffffffff021916908363ffffffff16021790555050888a106115005760405162461bcd60e51b81526004016101d790612a2f565b8489108061150c575084155b6115285760405162461bcd60e51b81526004016101d790612e58565b828211156115485760405162461bcd60e51b81526004016101d790612cf2565b600160801b831061156b5760405162461bcd60e51b81526004016101d79061295c565b604051636eb1769f60e11b815283906001600160a01b0386169063dd62ed3e9061159b90339030906004016125ef565b60206040518083038186803b1580156115b357600080fd5b505afa1580156115c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115eb91906124bb565b10156116095760405162461bcd60e51b81526004016101d790612b45565b600087511161162a5760405162461bcd60e51b81526004016101d790612915565b8651611637906002612fbc565b8651146116565760405162461bcd60e51b81526004016101d790612ba2565b60008054600354604051611679923392429263ffffffff9092169160200161256d565b60408051601f1981840301815291815281516020928301206000818152600290935291209091506116ac838e8e8e611d91565b81556116b88585611de1565b600182015560028101805465ffffffffffff191665ffffffffffff8916176601000000000000600160d01b03191633600160301b02179055885161170590600483019060208c019061200d565b506003810180546001600160a01b0319166001600160a01b03881617905560005b8951811015611877576004548a516001600160a01b03909116908b908390811061176057634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03161461182d5760008a828151811061179857634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156117d857600080fd5b505afa1580156117ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181091906124bb565b1161182d5760405162461bcd60e51b81526004016101d790612bed565b600582018054600180820183556000928352602090922060028204018054929091166010026101000a6001600160801b03021990911690558061186f8161301e565b915050611726565b5060005b8851811015611b7e5760006118fc8a83815181106118a957634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b03168b8460016118c89190612f84565b815181106118e657634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b0316611cfe565b9050600061195e8b61190f856001612f84565b8151811061192d57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b03168c85815181106118e657634e487b7160e01b600052603260045260246000fd5b90508a838151811061198057634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b0316600114156119e4578a6119a5846001612f84565b815181106119c357634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b031681146119df57600080fd5b611b69565b8a6119f0846001612f84565b81518110611a0e57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b031660011415611a63578a8381518110611a4757634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b031682146119df57600080fd5b8a8381518110611a8357634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b03168b846001611aa29190612f84565b81518110611ac057634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b031683611adc9190612fbc565b1415611ae757600080fd5b8a611af3846001612f84565b81518110611b1157634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b03168b8481518110611b4257634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b031682611b5e9190612fbc565b1415611b6957600080fd5b50611b779050600282612f84565b905061187b565b508751611b9490600683019060208b0190612072565b50611baa6001600160a01b038716333088611d39565b7f67851705247ee2eaa9bf5ce64c064ee80704743e80b401abb46b36318f7be5cf858333428a8f604051611be396959493929190612eac565b60405180910390a150505050505050505050505050565b6000611c0861010085611e05565b611c245760405162461bcd60e51b81526004016101d790612859565b50600019600190911b0191901c1690565b6040516370a0823160e01b815281906001600160a01b038616906370a0823190611c639087906004016125db565b60206040518083038186803b158015611c7b57600080fd5b505afa158015611c8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb391906124bb565b1015611cd15760405162461bcd60e51b81526004016101d7906129b1565b611ce56001600160a01b0385168383611e14565b50505050565b6000611cf78284612fbc565b9392505050565b6000611cf78284612f9c565b6000611cf78284612f84565b6000611cf78284612fdb565b821b600190911b6000190190911b19919091161790565b611ce5846323b872dd60e01b858585604051602401611d5a93929190612609565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611e33565b600080611da98160a06001600160a01b038916611ec2565b17611dbb60a0602860d888901c611ec2565b17611dc960c8601c86611ec2565b17611dd760e4601c85611ec2565b1795945050505050565b600080611df081608086611ec2565b17611dfd60808085611ec2565b179392505050565b6101008214600190921b111790565b6107718363a9059cbb60e01b8484604051602401611d5a92919061262d565b6000611e88826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611ef39092919063ffffffff16565b8051909150156107715780806020019051810190611ea69190612333565b6107715760405162461bcd60e51b81526004016101d790612de3565b6000611ece8383611e05565b611eea5760405162461bcd60e51b81526004016101d790612c65565b5090911b919050565b6060611f028484600085611f0a565b949350505050565b606082471015611f2c5760405162461bcd60e51b81526004016101d790612ad9565b611f3585611fca565b611f515760405162461bcd60e51b81526004016101d790612cbb565b600080866001600160a01b03168587604051611f6d91906125a4565b60006040518083038185875af1925050503d8060008114611faa576040519150601f19603f3d011682016040523d82523d6000602084013e611faf565b606091505b5091509150611fbf828286611fd4565b979650505050505050565b803b15155b919050565b60608315611fe3575081611cf7565b825115611ff35782518084602001fd5b8160405162461bcd60e51b81526004016101d79190612846565b828054828255906000526020600020908101928215612062579160200282015b8281111561206257825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019061202d565b5061206e929150612121565b5090565b828054828255906000526020600020906001016002900481019282156120625791602002820160005b838211156120e557835183826101000a8154816001600160801b0302191690836001600160801b031602179055509260200192601001602081600f0104928301926001030261209b565b80156121185782816101000a8154906001600160801b030219169055601001602081600f010492830192600103026120e5565b505061206e9291505b5b8082111561206e5760008155600101612122565b80356001600160a01b0381168114611fcf57600080fd5b600082601f83011261215d578081fd5b8135602061217261216d83612f29565b612ef8565b828152818101908583018385028701840188101561218e578586fd5b855b858110156121b3576121a182612136565b84529284019290840190600101612190565b5090979650505050505050565b600082601f8301126121d0578081fd5b813560206121e061216d83612f29565b82815281810190858301838502870184018810156121fc578586fd5b855b858110156121b35761220f8261228c565b845292840192908401906001016121fe565b600082601f830112612231578081fd5b813567ffffffffffffffff81111561224b5761224b613073565b61225e601f8201601f1916602001612ef8565b818152846020838601011115612272578283fd5b816020850160208301379081016020019190915292915050565b80356001600160801b0381168114611fcf57600080fd5b600060208083850312156122b5578182fd5b823567ffffffffffffffff8111156122cb578283fd5b8301601f810185136122db578283fd5b80356122e961216d82612f29565b8181528381019083850185840285018601891015612305578687fd5b8694505b83851015612327578035835260019490940193918501918501612309565b50979650505050505050565b600060208284031215612344578081fd5b81518015158114611cf7578182fd5b600060208284031215612364578081fd5b5035919050565b600080600080600060a08688031215612382578081fd5b853594506020860135935060408601359250606086013591506123a76080870161228c565b90509295509295909350565b600080604083850312156123c5578182fd5b50508035926020909101359150565b60008060008060008060008060008060006101608c8e0312156123f5578586fd5b8b359a5060208c0135995060408c0135985067ffffffffffffffff8060608e01351115612420578687fd5b6124308e60608f01358f01612221565b98508060808e01351115612442578687fd5b6124528e60808f01358f0161214d565b97508060a08e01351115612464578687fd5b506124758d60a08e01358e016121c0565b955060c08c0135945061248a60e08d01612136565b93506101008c013592506101208c013591506124a96101408d01612136565b90509295989b509295989b9093969950565b6000602082840312156124cc578081fd5b5051919050565b6000815180845260208085019450808401835b8381101561250b5781516001600160801b0316875295820195908201906001016124e6565b509495945050505050565b15159052565b60008151808452612534816020860160208601612ff2565b601f01601f19169290920160200192915050565b6001600160801b03169052565b60609190911b6001600160601b031916815260140190565b60609490941b6001600160601b0319168452601484019290925260e01b6001600160e01b0319166034830152603882015260580190565b600082516125b6818460208701612ff2565b9190910192915050565b91825260601b6001600160601b031916602082015260340190565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6101008082528951908201819052600090610120830190602090818d01845b8281101561268a5781516001600160a01b031685529383019390830190600101612665565b50505083018a905261269f604084018a612516565b6126ac6060840189612516565b6126b96080840188612516565b8560a08401528460c084015282810360e08401526126d781856124d3565b9b9a5050505050505050505050565b9586526001600160a01b0394851660208701529284166040860152921660608401526001600160801b03909116608083015260a082015260c00190565b9283526001600160a01b03919091166020830152604082015260600190565b60006080808301878452602060018060a01b03881681860152604087818701528360608701528287546127758186612ea3565b915061278089612f4d565b9450865b6001828183011061279557506127ca565b86546127aa856001600160801b038316612548565b6127b8878601828b1c612548565b50959095019491830191600201612784565b945494818110156127f0576127e8836001600160801b038816612548565b918401916001015b81811015612809576128048387891c612548565b918401915b50909b9a5050505050505050505050565b9485526001600160a01b0393841660208601526040850192909252606084015216608082015260a00190565b600060208252611cf7602083018461251c565b60208082526018908201527f56616c7565206f7574206f662072616e676520554e424f580000000000000000604082015260600190565b60208082526022908201527f426574746572206e6f7420647261772077617465722077697468206120736965604082015261766560f01b606082015260800190565b60208082526023908201527f4f6e6c792074686520706f6f6c2063726561746f722063616e2064657374727560408201526231ba1760e91b606082015260800190565b60208082526027908201527f45786368616e676520746f6b656e20616464726573736573206e65656420746f604082015266081899481cd95d60ca1b606082015260800190565b60208082526035908201527f4e6f206d6f7265207468616e20325e31323820746f6b656e7328696e636c7569604082015274191b99c8191958da5b585b1cca48185b1b1bddd959605a1b606082015260800190565b602080825260129082015271084c2d8c2dcc6ca40dcdee840cadcdeeaced60731b604082015260600190565b6020808252600f908201526e105b1c9958591e481cddd85c1c1959608a1b604082015260600190565b6020808252600f908201526e139bdd08195e1c1a5c9959081e595d608a1b604082015260600190565b6020808252602b908201527f53746172742074696d652073686f756c64206265206561726c6965722074686160408201526a371032b732103a34b6b29760a91b606082015260800190565b60208082526017908201527f4e6f6e65206f66207468697320746f6b656e206c656674000000000000000000604082015260600190565b6020808252600e908201526d15dc9bdb99c814185cdcdddbdc9960921b604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b6020808252600c908201526b4f7574206f662053746f636b60a01b604082015260600190565b602080825260159082015274496e737566666369656e7420616c6c6f77616e636560581b604082015260600190565b60208082526014908201527327379032b737bab3b41030b63637bbb0b731b29760611b604082015260600190565b6020808252602b908201527f53697a65206f6620726174696f73203d2032202a2073697a65206f662065786360408201526a68616e67655f616464727360a81b606082015260800190565b60208082526011908201527004e6f7420612076616c696420455243323607c1b604082015260600190565b602080825260119082015270506f6f6c2043726561746f72204f6e6c7960781b604082015260600190565b60208082526008908201526722bc3834b932b21760c11b604082015260600190565b6020808252601690820152750acc2d8eaca40deeae840decc40e4c2dcceca40849eb60531b604082015260600190565b6020808252600c908201526b2737ba1039ba30b93a32b21760a11b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b60208082526038908201527f4c696d6974206e6565647320746f206265206c657373207468616e206f72206560408201527f7175616c20746f2074686520746f74616c20737570706c790000000000000000606082015260800190565b60208082526023908201527f4f6e6c792074686520706f6f6c2063726561746f722063616e2077697468647260408201526230bb9760e91b606082015260800190565b60208082526010908201526f27379032b737bab3b41032ba3432b91760811b604082015260600190565b6020808252600d908201526c139bdd08145d585b1a599a5959609a1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60208082526011908201527015985b1a59185d1a5bdb8811985a5b1959607a1b604082015260600190565b6020808252602b908201527f456e642074696d652073686f756c64206265206561726c696572207468616e2060408201526a756e6c6f636b2074696d6560a81b606082015260800190565b90815260200190565b868152602081018690526001600160a01b038581166040830152606082018590528316608082015260c060a08201819052600090612eec9083018461251c565b98975050505050505050565b604051601f8201601f1916810167ffffffffffffffff81118282101715612f2157612f21613073565b604052919050565b600067ffffffffffffffff821115612f4357612f43613073565b5060209081020190565b60009081526020902090565b60006001600160e01b03828116848216808303821115612f7b57612f7b61305d565b01949350505050565b60008219821115612f9757612f9761305d565b500190565b600082612fb757634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615612fd657612fd661305d565b500290565b600082821015612fed57612fed61305d565b500390565b60005b8381101561300d578181015183820152602001612ff5565b83811115611ce55750506000910152565b60006000198214156130325761303261305d565b5060010190565b600063ffffffff808316818114156130535761305361305d565b6001019392505050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fdfea2646970667358221220514567ac97ce2a52346891fb1fa79398719dfc3625c962f89ef81e693295dbc764736f6c634300080100335072696e6365205068696c69702c20517565656e20456c697a616265746820494927732068757362616e642c20686173206469656420616765642039392c20202020204275636b696e6768616d2050616c6163652068617320616e6e6f756e6365642e20412073746174656d656e7420697373756564206279207468652070616c616365206a757374206166746572206d69646461792073706f6b65206f66207468652020202020517565656e2773206465657020736f72726f7720666f6c6c6f77696e67206869732064656174682061742057696e64736f7220436173746c65206f6e20467269646179206d6f726e696e672e205468652044756b65206f66204564696e627572
Deployed Bytecode
0x60806040526004361061007b5760003560e01c8063c6d898341161004e578063c6d8983414610121578063cc0cab4c14610141578063ec0e3d9a14610161578063ef65dc7e146101815761007b565b8063040cf020146100805780636bfdaece146100a2578063b391c508146100df578063bf5c2920146100ff575b600080fd5b34801561008c57600080fd5b506100a061009b3660046123b3565b610194565b005b3480156100ae57600080fd5b506100c26100bd366004612353565b6103e4565b6040516100d6989796959493929190612646565b60405180910390f35b3480156100eb57600080fd5b506100a06100fa3660046122a3565b610605565b34801561010b57600080fd5b50610114610776565b6040516100d691906125db565b61013461012f36600461236b565b610785565b6040516100d69190612ea3565b34801561014d57600080fd5b506100a061015c366004612353565b610f3d565b34801561016d57600080fd5b506100a061017c3660046123b3565b611448565b6100a061018f3660046123d4565b6114ad565b600082815260026020819052604090912090810154600160301b90046001600160a01b031633146101e05760405162461bcd60e51b81526004016101d790612d4f565b60405180910390fd5b600081600501838154811061020557634e487b7160e01b600052603260045260246000fd5b6000918252602090912060028204015460019091166010026101000a90046001600160801b031690508061024b5760405162461bcd60e51b81526004016101d790612a7a565b600080548354600160201b9091046001600160e01b0316906102709060e4601c611bfa565b61027a9190612f84565b9050600061028f846001015460006080611bfa565b9050428211158061029e575080155b6102ba5760405162461bcd60e51b81526004016101d790612a06565b60008460040186815481106102df57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546004546001600160a01b0391821692501681146103135761030e81303387611c35565b610342565b604051339085156108fc029086906000818181858888f19350505050158015610340573d6000803e3d6000fd5b505b600085600501878154811061036757634e487b7160e01b600052603260045260246000fd5b90600052602060002090600291828204019190066010026101000a8154816001600160801b0302191690836001600160801b031602179055507fab5315d16ef405a1f4e8c34017af486f59f27097e003d2a1981ae682c2f367318782866040516103d393929190612723565b60405180910390a150505050505050565b606060008060008060008060606000600260008b815260200190815260200160002090508060040161041d826001015460006080611bfa565b6000548354600160201b9091046001600160e01b0316906104419060c8601c611bfa565b61044b9190612f84565b4211600060049054906101000a90046001600160e01b03166001600160e01b031661047d856000015460e4601c611bfa565b6104879190612f84565b60005460028601544292909211916104b791600160201b90046001600160e01b03169065ffffffffffff16612f59565b60005460028701546001600160e01b039283164211926104e792600160201b9004169065ffffffffffff16612f59565b336000908152600788016020908152604091829020548854835181840281018401909452808452909260058b019290918a9183018282801561055257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610534575b50505050509750826001600160e01b03169250808054806020026020016040519081016040528092919081815260200182805480156105e257602002820191906000526020600020906000905b82829054906101000a90046001600160801b03166001600160801b031681526020019060100190602082600f0104928301926001038202915080841161059f5790505b505050505090509850985098509850985098509850985050919395975091939597565b6000805b82518110156107715760006002600085848151811061063857634e487b7160e01b600052603260045260246000fd5b6020908102919091018101518252810191909152604001600090812090546002820154919250429161068291600160201b90046001600160e01b03169065ffffffffffff16612f59565b6001600160e01b03161115610697575061075f565b3360009081526007820160205260409020549250826106b6575061075f565b33600081815260078301602052604081205560038201546106e5916001600160a01b0390911690309086611c35565b7f0b8bdb11ddec1f8dd879bd98afac7c33c30ce590fcbc26ed559df98f9a38111984838151811061072657634e487b7160e01b600052603260045260246000fd5b6020908102919091010151600383015460405161075592913391429189916001600160a01b039091169061281a565b60405180910390a1505b806107698161301e565b915050610609565b505050565b6001546001600160a01b031681565b600085815260026020908152604080832081518083019092528054808352600182015493830193909352916107bc908460a0611bfa565b6001600160a01b0316637938037233600060049054906101000a90046001600160e01b03166001600160e01b03166107fb856000015160c8601c611bfa565b6108059190612f84565b6040518363ffffffff1660e01b815260040161082292919061262d565b602060405180830381600087803b15801561083c57600080fd5b505af1158015610850573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108749190612333565b15156001146108955760405162461bcd60e51b81526004016101d790612dbc565b60005481514291600160201b90046001600160e01b0316906108ba9060c8601c611bfa565b6108c49190612f84565b106108e15760405162461bcd60e51b81526004016101d790612c95565b60005481514291600160201b90046001600160e01b0316906109069060e4601c611bfa565b6109109190612f84565b1161092d5760405162461bcd60e51b81526004016101d790612c43565b805161093c9060a06028611bfa565b3360405160200161094e9291906125c0565b6040516020818303038152906040528051906020012087146109825760405162461bcd60e51b81526004016101d790612ab1565b336040516020016109939190612555565b6040516020818303038152906040528051906020012086146109c75760405162461bcd60e51b81526004016101d790612e2d565b60006109da826020015160006080611bfa565b9050600081116109fc5760405162461bcd60e51b81526004016101d790612b1f565b6000836004018781548110610a2157634e487b7160e01b600052603260045260246000fd5b60009182526020822001546001600160a01b0316915060068501610a46896002612fbc565b81548110610a6457634e487b7160e01b600052603260045260246000fd5b90600052602060002090600291828204019190066010029054906101000a90046001600160801b03166001600160801b03169050600085600601896002610aab9190612fbc565b610ab6906001612f84565b81548110610ad457634e487b7160e01b600052603260045260246000fd5b6000918252602090912060028204015460045460019092166010026101000a90046001600160801b031691506001600160a01b039081169084161415610b4157876001600160801b03163414610b3c5760405162461bcd60e51b81526004016101d790612d92565b610bef565b604051636eb1769f60e11b81526000906001600160a01b0385169063dd62ed3e90610b7290339030906004016125ef565b60206040518083038186803b158015610b8a57600080fd5b505afa158015610b9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc291906124bb565b9050886001600160801b0316811015610bed5760405162461bcd60e51b81526004016101d790612b74565b505b6000610c0d610c078a6001600160801b031684611ceb565b84611cfe565b905060008111610c2f5760405162461bcd60e51b81526004016101d790612890565b6000610c418760200151608080611bfa565b905080821115610c6257809150610c5b610c078286611ceb565b9950610cd4565b85821115610cd457859150610c7a610c078786611ceb565b600454909a506001600160a01b0386811691161415610cd457336108fc610caa6001600160801b038d1634612fdb565b6040518115909202916000818181858888f19350505050158015610cd2573d6000803e3d6000fd5b505b80821115610ce157600080fd5b610d48886005018c81548110610d0757634e487b7160e01b600052603260045260246000fd5b90600052602060002090600291828204019190066010029054906101000a90046001600160801b03166001600160801b03168b6001600160801b0316611d0a565b886005018c81548110610d6b57634e487b7160e01b600052603260045260246000fd5b90600052602060002090600291828204019190066010026101000a8154816001600160801b0302191690836001600160801b03160217905550876007016000336001600160a01b03166001600160a01b0316815260200190815260200160002054600014610deb5760405162461bcd60e51b81526004016101d7906129dd565b610e06876020015160006080610e018a87611d16565b611d22565b600189015533600090815260078901602052604090208290556004546001600160a01b03868116911614610e5257610e526001600160a01b03861633306001600160801b038e16611d39565b7fa6a9350e3cb78ab6117ff3f716716cb2a1c40e92008df3c4f60e976ee6d56edc8e33878b60030160009054906101000a90046001600160a01b03168e87604051610ea2969594939291906126e6565b60405180910390a1600288015465ffffffffffff16610f2c576003880154610ed5906001600160a01b0316303385611c35565b7f0b8bdb11ddec1f8dd879bd98afac7c33c30ce590fcbc26ed559df98f9a3811198e3342858c60030160009054906101000a90046001600160a01b0316604051610f2395949392919061281a565b60405180910390a15b509c9b505050505050505050505050565b600081815260026020819052604090912090810154600160301b90046001600160a01b03163314610f805760405162461bcd60e51b81526004016101d7906128d2565b600080548254600160201b9091046001600160e01b031690610fa59060e4601c611bfa565b610faf9190612f84565b90506000610fc4836001015460006080611bfa565b90504282111580610fd3575080155b610fef5760405162461bcd60e51b81526004016101d790612a06565b801561100f57600383015461100f906001600160a01b0316303384611c35565b60005b60048401548110156111f857600084600501828154811061104357634e487b7160e01b600052603260045260246000fd5b6000918252602090912060028204015460019091166010026101000a90046001600160801b031611156111e6576004805490850180546001600160a01b0390921691839081106110a357634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b031614611157576111528460040182815481106110e357634e487b7160e01b600052603260045260246000fd5b9060005260206000200160009054906101000a90046001600160a01b0316303387600501858154811061112657634e487b7160e01b600052603260045260246000fd5b6000918252602090912060028204015460019091166010026101000a90046001600160801b0316611c35565b6111e6565b336001600160a01b03166108fc85600501838154811061118757634e487b7160e01b600052603260045260246000fd5b90600052602060002090600291828204019190066010029054906101000a90046001600160801b03166001600160801b03169081150290604051600060405180830381858888f193505050501580156111e4573d6000803e3d6000fd5b505b806111f08161301e565b915050611012565b5060038301546040517f01a1fd9d8a4231d7bd8926ce16b753ba03e0310e0a776f13eba8e0c3cba7ea899161123f9187916001600160a01b03169085906005890190612742565b60405180910390a16000808455600184018190556004546002850180546601000000000000600160d01b0319166001600160a01b03909216600160301b029190911790555b6004840154811015611441576004805490850180546001600160a01b0390921691839081106112c357634e487b7160e01b600052603260045260246000fd5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600084600501828154811061131657634e487b7160e01b600052603260045260246000fd5b90600052602060002090600291828204019190066010026101000a8154816001600160801b0302191690836001600160801b031602179055506000846006018260026113629190612fbc565b8154811061138057634e487b7160e01b600052603260045260246000fd5b90600052602060002090600291828204019190066010026101000a8154816001600160801b0302191690836001600160801b031602179055506000846006018260026113cc9190612fbc565b6113d7906001612f84565b815481106113f557634e487b7160e01b600052603260045260246000fd5b90600052602060002090600291828204019190066010026101000a8154816001600160801b0302191690836001600160801b0316021790555080806114399061301e565b915050611284565b5050505050565b600082815260026020819052604090912090810154600160301b90046001600160a01b0316331461148b5760405162461bcd60e51b81526004016101d790612c18565b600201805465ffffffffffff191665ffffffffffff9290921691909117905550565b6000805463ffffffff1690806114c283613039565b91906101000a81548163ffffffff021916908363ffffffff16021790555050888a106115005760405162461bcd60e51b81526004016101d790612a2f565b8489108061150c575084155b6115285760405162461bcd60e51b81526004016101d790612e58565b828211156115485760405162461bcd60e51b81526004016101d790612cf2565b600160801b831061156b5760405162461bcd60e51b81526004016101d79061295c565b604051636eb1769f60e11b815283906001600160a01b0386169063dd62ed3e9061159b90339030906004016125ef565b60206040518083038186803b1580156115b357600080fd5b505afa1580156115c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115eb91906124bb565b10156116095760405162461bcd60e51b81526004016101d790612b45565b600087511161162a5760405162461bcd60e51b81526004016101d790612915565b8651611637906002612fbc565b8651146116565760405162461bcd60e51b81526004016101d790612ba2565b60008054600354604051611679923392429263ffffffff9092169160200161256d565b60408051601f1981840301815291815281516020928301206000818152600290935291209091506116ac838e8e8e611d91565b81556116b88585611de1565b600182015560028101805465ffffffffffff191665ffffffffffff8916176601000000000000600160d01b03191633600160301b02179055885161170590600483019060208c019061200d565b506003810180546001600160a01b0319166001600160a01b03881617905560005b8951811015611877576004548a516001600160a01b03909116908b908390811061176057634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03161461182d5760008a828151811061179857634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156117d857600080fd5b505afa1580156117ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061181091906124bb565b1161182d5760405162461bcd60e51b81526004016101d790612bed565b600582018054600180820183556000928352602090922060028204018054929091166010026101000a6001600160801b03021990911690558061186f8161301e565b915050611726565b5060005b8851811015611b7e5760006118fc8a83815181106118a957634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b03168b8460016118c89190612f84565b815181106118e657634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b0316611cfe565b9050600061195e8b61190f856001612f84565b8151811061192d57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b03168c85815181106118e657634e487b7160e01b600052603260045260246000fd5b90508a838151811061198057634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b0316600114156119e4578a6119a5846001612f84565b815181106119c357634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b031681146119df57600080fd5b611b69565b8a6119f0846001612f84565b81518110611a0e57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b031660011415611a63578a8381518110611a4757634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b031682146119df57600080fd5b8a8381518110611a8357634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b03168b846001611aa29190612f84565b81518110611ac057634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b031683611adc9190612fbc565b1415611ae757600080fd5b8a611af3846001612f84565b81518110611b1157634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b03168b8481518110611b4257634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160801b031682611b5e9190612fbc565b1415611b6957600080fd5b50611b779050600282612f84565b905061187b565b508751611b9490600683019060208b0190612072565b50611baa6001600160a01b038716333088611d39565b7f67851705247ee2eaa9bf5ce64c064ee80704743e80b401abb46b36318f7be5cf858333428a8f604051611be396959493929190612eac565b60405180910390a150505050505050505050505050565b6000611c0861010085611e05565b611c245760405162461bcd60e51b81526004016101d790612859565b50600019600190911b0191901c1690565b6040516370a0823160e01b815281906001600160a01b038616906370a0823190611c639087906004016125db565b60206040518083038186803b158015611c7b57600080fd5b505afa158015611c8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb391906124bb565b1015611cd15760405162461bcd60e51b81526004016101d7906129b1565b611ce56001600160a01b0385168383611e14565b50505050565b6000611cf78284612fbc565b9392505050565b6000611cf78284612f9c565b6000611cf78284612f84565b6000611cf78284612fdb565b821b600190911b6000190190911b19919091161790565b611ce5846323b872dd60e01b858585604051602401611d5a93929190612609565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611e33565b600080611da98160a06001600160a01b038916611ec2565b17611dbb60a0602860d888901c611ec2565b17611dc960c8601c86611ec2565b17611dd760e4601c85611ec2565b1795945050505050565b600080611df081608086611ec2565b17611dfd60808085611ec2565b179392505050565b6101008214600190921b111790565b6107718363a9059cbb60e01b8484604051602401611d5a92919061262d565b6000611e88826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611ef39092919063ffffffff16565b8051909150156107715780806020019051810190611ea69190612333565b6107715760405162461bcd60e51b81526004016101d790612de3565b6000611ece8383611e05565b611eea5760405162461bcd60e51b81526004016101d790612c65565b5090911b919050565b6060611f028484600085611f0a565b949350505050565b606082471015611f2c5760405162461bcd60e51b81526004016101d790612ad9565b611f3585611fca565b611f515760405162461bcd60e51b81526004016101d790612cbb565b600080866001600160a01b03168587604051611f6d91906125a4565b60006040518083038185875af1925050503d8060008114611faa576040519150601f19603f3d011682016040523d82523d6000602084013e611faf565b606091505b5091509150611fbf828286611fd4565b979650505050505050565b803b15155b919050565b60608315611fe3575081611cf7565b825115611ff35782518084602001fd5b8160405162461bcd60e51b81526004016101d79190612846565b828054828255906000526020600020908101928215612062579160200282015b8281111561206257825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019061202d565b5061206e929150612121565b5090565b828054828255906000526020600020906001016002900481019282156120625791602002820160005b838211156120e557835183826101000a8154816001600160801b0302191690836001600160801b031602179055509260200192601001602081600f0104928301926001030261209b565b80156121185782816101000a8154906001600160801b030219169055601001602081600f010492830192600103026120e5565b505061206e9291505b5b8082111561206e5760008155600101612122565b80356001600160a01b0381168114611fcf57600080fd5b600082601f83011261215d578081fd5b8135602061217261216d83612f29565b612ef8565b828152818101908583018385028701840188101561218e578586fd5b855b858110156121b3576121a182612136565b84529284019290840190600101612190565b5090979650505050505050565b600082601f8301126121d0578081fd5b813560206121e061216d83612f29565b82815281810190858301838502870184018810156121fc578586fd5b855b858110156121b35761220f8261228c565b845292840192908401906001016121fe565b600082601f830112612231578081fd5b813567ffffffffffffffff81111561224b5761224b613073565b61225e601f8201601f1916602001612ef8565b818152846020838601011115612272578283fd5b816020850160208301379081016020019190915292915050565b80356001600160801b0381168114611fcf57600080fd5b600060208083850312156122b5578182fd5b823567ffffffffffffffff8111156122cb578283fd5b8301601f810185136122db578283fd5b80356122e961216d82612f29565b8181528381019083850185840285018601891015612305578687fd5b8694505b83851015612327578035835260019490940193918501918501612309565b50979650505050505050565b600060208284031215612344578081fd5b81518015158114611cf7578182fd5b600060208284031215612364578081fd5b5035919050565b600080600080600060a08688031215612382578081fd5b853594506020860135935060408601359250606086013591506123a76080870161228c565b90509295509295909350565b600080604083850312156123c5578182fd5b50508035926020909101359150565b60008060008060008060008060008060006101608c8e0312156123f5578586fd5b8b359a5060208c0135995060408c0135985067ffffffffffffffff8060608e01351115612420578687fd5b6124308e60608f01358f01612221565b98508060808e01351115612442578687fd5b6124528e60808f01358f0161214d565b97508060a08e01351115612464578687fd5b506124758d60a08e01358e016121c0565b955060c08c0135945061248a60e08d01612136565b93506101008c013592506101208c013591506124a96101408d01612136565b90509295989b509295989b9093969950565b6000602082840312156124cc578081fd5b5051919050565b6000815180845260208085019450808401835b8381101561250b5781516001600160801b0316875295820195908201906001016124e6565b509495945050505050565b15159052565b60008151808452612534816020860160208601612ff2565b601f01601f19169290920160200192915050565b6001600160801b03169052565b60609190911b6001600160601b031916815260140190565b60609490941b6001600160601b0319168452601484019290925260e01b6001600160e01b0319166034830152603882015260580190565b600082516125b6818460208701612ff2565b9190910192915050565b91825260601b6001600160601b031916602082015260340190565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6101008082528951908201819052600090610120830190602090818d01845b8281101561268a5781516001600160a01b031685529383019390830190600101612665565b50505083018a905261269f604084018a612516565b6126ac6060840189612516565b6126b96080840188612516565b8560a08401528460c084015282810360e08401526126d781856124d3565b9b9a5050505050505050505050565b9586526001600160a01b0394851660208701529284166040860152921660608401526001600160801b03909116608083015260a082015260c00190565b9283526001600160a01b03919091166020830152604082015260600190565b60006080808301878452602060018060a01b03881681860152604087818701528360608701528287546127758186612ea3565b915061278089612f4d565b9450865b6001828183011061279557506127ca565b86546127aa856001600160801b038316612548565b6127b8878601828b1c612548565b50959095019491830191600201612784565b945494818110156127f0576127e8836001600160801b038816612548565b918401916001015b81811015612809576128048387891c612548565b918401915b50909b9a5050505050505050505050565b9485526001600160a01b0393841660208601526040850192909252606084015216608082015260a00190565b600060208252611cf7602083018461251c565b60208082526018908201527f56616c7565206f7574206f662072616e676520554e424f580000000000000000604082015260600190565b60208082526022908201527f426574746572206e6f7420647261772077617465722077697468206120736965604082015261766560f01b606082015260800190565b60208082526023908201527f4f6e6c792074686520706f6f6c2063726561746f722063616e2064657374727560408201526231ba1760e91b606082015260800190565b60208082526027908201527f45786368616e676520746f6b656e20616464726573736573206e65656420746f604082015266081899481cd95d60ca1b606082015260800190565b60208082526035908201527f4e6f206d6f7265207468616e20325e31323820746f6b656e7328696e636c7569604082015274191b99c8191958da5b585b1cca48185b1b1bddd959605a1b606082015260800190565b602080825260129082015271084c2d8c2dcc6ca40dcdee840cadcdeeaced60731b604082015260600190565b6020808252600f908201526e105b1c9958591e481cddd85c1c1959608a1b604082015260600190565b6020808252600f908201526e139bdd08195e1c1a5c9959081e595d608a1b604082015260600190565b6020808252602b908201527f53746172742074696d652073686f756c64206265206561726c6965722074686160408201526a371032b732103a34b6b29760a91b606082015260800190565b60208082526017908201527f4e6f6e65206f66207468697320746f6b656e206c656674000000000000000000604082015260600190565b6020808252600e908201526d15dc9bdb99c814185cdcdddbdc9960921b604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b6020808252600c908201526b4f7574206f662053746f636b60a01b604082015260600190565b602080825260159082015274496e737566666369656e7420616c6c6f77616e636560581b604082015260600190565b60208082526014908201527327379032b737bab3b41030b63637bbb0b731b29760611b604082015260600190565b6020808252602b908201527f53697a65206f6620726174696f73203d2032202a2073697a65206f662065786360408201526a68616e67655f616464727360a81b606082015260800190565b60208082526011908201527004e6f7420612076616c696420455243323607c1b604082015260600190565b602080825260119082015270506f6f6c2043726561746f72204f6e6c7960781b604082015260600190565b60208082526008908201526722bc3834b932b21760c11b604082015260600190565b6020808252601690820152750acc2d8eaca40deeae840decc40e4c2dcceca40849eb60531b604082015260600190565b6020808252600c908201526b2737ba1039ba30b93a32b21760a11b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b60208082526038908201527f4c696d6974206e6565647320746f206265206c657373207468616e206f72206560408201527f7175616c20746f2074686520746f74616c20737570706c790000000000000000606082015260800190565b60208082526023908201527f4f6e6c792074686520706f6f6c2063726561746f722063616e2077697468647260408201526230bb9760e91b606082015260800190565b60208082526010908201526f27379032b737bab3b41032ba3432b91760811b604082015260600190565b6020808252600d908201526c139bdd08145d585b1a599a5959609a1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60208082526011908201527015985b1a59185d1a5bdb8811985a5b1959607a1b604082015260600190565b6020808252602b908201527f456e642074696d652073686f756c64206265206561726c696572207468616e2060408201526a756e6c6f636b2074696d6560a81b606082015260800190565b90815260200190565b868152602081018690526001600160a01b038581166040830152606082018590528316608082015260c060a08201819052600090612eec9083018461251c565b98975050505050505050565b604051601f8201601f1916810167ffffffffffffffff81118282101715612f2157612f21613073565b604052919050565b600067ffffffffffffffff821115612f4357612f43613073565b5060209081020190565b60009081526020902090565b60006001600160e01b03828116848216808303821115612f7b57612f7b61305d565b01949350505050565b60008219821115612f9757612f9761305d565b500190565b600082612fb757634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615612fd657612fd661305d565b500290565b600082821015612fed57612fed61305d565b500390565b60005b8381101561300d578181015183820152602001612ff5565b83811115611ce55750506000910152565b60006000198214156130325761303261305d565b5060010190565b600063ffffffff808316818114156130535761305361305d565b6001019392505050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fdfea2646970667358221220514567ac97ce2a52346891fb1fa79398719dfc3625c962f89ef81e693295dbc764736f6c63430008010033
Deployed Bytecode Sourcemap
24290:24315:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42938:1063;;;;;;;;;;-1:-1:-1;42938:1063:0;;;;;:::i;:::-;;:::i;:::-;;38096:1150;;;;;;;;;;-1:-1:-1;38096:1150:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;;;;;;;;39254:680;;;;;;;;;;-1:-1:-1;39254:680:0;;;;;:::i;:::-;;:::i;26923:31::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;32924:4663::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;40836:1743::-;;;;;;;;;;-1:-1:-1;40836:1743:0;;;;;:::i;:::-;;:::i;39942:234::-;;;;;;;;;;-1:-1:-1;39942:234:0;;;;;:::i;:::-;;:::i;28873:3312::-;;;;;;:::i;:::-;;:::i;42938:1063::-;43003:17;43023:14;;;:10;:14;;;;;;;;43070:12;;;;-1:-1:-1;;;43070:12:0;;-1:-1:-1;;;;;43070:12:0;43056:10;:26;43048:74;;;;-1:-1:-1;;;43048:74:0;;;;;;;:::i;:::-;;;;;;;;;43135:24;43162:4;:21;;43184:6;43162:29;;;;;;-1:-1:-1;;;43162:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;43162:29:0;;-1:-1:-1;43162:29:0;43202:56;;;;-1:-1:-1;;;43202:56:0;;;;;;;:::i;:::-;43269:18;43321:9;;43296:12;;-1:-1:-1;;;43321:9:0;;;-1:-1:-1;;;;;43321:9:0;;43290:28;;43310:3;43315:2;43290:5;:28::i;:::-;:40;;;;:::i;:::-;43269:61;;43341:24;43368:27;43374:4;:12;;;43388:1;43391:3;43368:5;:27::i;:::-;43341:54;;43483:15;43469:10;:29;;:54;;;-1:-1:-1;43502:21:0;;43469:54;43461:82;;;;-1:-1:-1;;;43461:82:0;;;;;;;:::i;:::-;43554:21;43578:4;:19;;43598:6;43578:27;;;;;;-1:-1:-1;;;43578:27:0;;;;;;;;;;;;;;;;;;;43657:15;;-1:-1:-1;;;;;43578:27:0;;;;-1:-1:-1;43657:15:0;43640:32;;43636:216;;43687:74;43702:13;43725:4;43732:10;43744:16;43687:14;:74::i;:::-;43636:216;;;43806:46;;43814:10;;43806:46;;;;;43835:16;;43806:46;;;;43835:16;43814:10;43806:46;;;;;;;;;;;;;;;;;;;;;43636:216;43924:1;43892:4;:21;;43914:6;43892:29;;;;;;-1:-1:-1;;;43892:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;:33;;;;;-1:-1:-1;;;;;43892:33:0;;;;;-1:-1:-1;;;;;43892:33:0;;;;;;43941:52;43957:2;43961:13;43976:16;43941:52;;;;;;;;:::i;:::-;;;;;;;;42938:1063;;;;;;;:::o;38096:1150::-;38170:31;38203:17;38241:12;38255;38269:13;38284:19;38323:15;38340:33;38386:17;38406:10;:14;38417:2;38406:14;;;;;;;;;;;38386:34;;38453:4;:19;;38573:27;38579:4;:12;;;38593:1;38596:3;38573:5;:27::i;:::-;38716:9;;38691:12;;-1:-1:-1;;;38716:9:0;;;-1:-1:-1;;;;;38716:9:0;;38685:28;;38705:3;38710:2;38685:5;:28::i;:::-;:40;;;;:::i;:::-;38667:15;:58;38808:9;;;;;;;;;-1:-1:-1;;;;;38808:9:0;-1:-1:-1;;;;;38777:40:0;:28;38783:4;:12;;;38797:3;38802:2;38777:5;:28::i;:::-;:40;;;;:::i;:::-;38888:9;;38869:16;;;;38759:15;:58;;;;;38869:28;;-1:-1:-1;;;38888:9:0;;-1:-1:-1;;;;;38888:9:0;;38869:16;;:28;:::i;:::-;38963:9;;38944:16;;;;-1:-1:-1;;;;;38851:46:0;;;:15;:46;;38944:28;;-1:-1:-1;;;38963:9:0;;;;38944:16;;:28;:::i;:::-;39057:10;39040:28;;;;:16;;;:28;;;;;;;;;;38431:807;;;;;;;;;;;;;;;;;39040:28;;39140:21;;;;38431:807;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;38431:807:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;38431:807:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;38431:807:0;-1:-1:-1;;;;;38431:807:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38096:1150;;;;;;;;;:::o;39254:680::-;39313:22;;39346:581;39370:7;:14;39366:1;:18;39346:581;;;39406:17;39426:10;:22;39437:7;39445:1;39437:10;;;;;;-1:-1:-1;;;39437:10:0;;;;;;;;;;;;;;;;;;;;39426:22;;;;;;;;;;-1:-1:-1;39426:22:0;;;39486:9;;39467:16;;;;39426:22;;-1:-1:-1;39498:15:0;;39467:28;;-1:-1:-1;;;39486:9:0;;-1:-1:-1;;;;;39486:9:0;;39467:16;;:28;:::i;:::-;-1:-1:-1;;;;;39467:46:0;;39463:77;;;39532:8;;;39463:77;39589:10;39572:28;;;;:16;;;:28;;;;;;;-1:-1:-1;39619:19:0;39615:50;;39657:8;;;39615:50;39697:10;39711:1;39680:28;;;:16;;;:28;;;;;:32;39742:18;;;;39727:77;;-1:-1:-1;;;;;39742:18:0;;;;39770:4;;39789:14;39727;:77::i;:::-;39826:89;39839:7;39847:1;39839:10;;;;;;-1:-1:-1;;;39839:10:0;;;;;;;;;;;;;;;;;;;39896:18;;;;39826:89;;;;39839:10;39851;;39863:15;;39880:14;;-1:-1:-1;;;;;39896:18:0;;;;39826:89;:::i;:::-;;;;;;;;39346:581;;39386:3;;;;:::i;:::-;;;;39346:581;;;;39254:680;;:::o;26923:31::-;;;-1:-1:-1;;;;;26923:31:0;;:::o;32924:4663::-;33090:15;33140:14;;;:10;:14;;;;;;;;33188:34;;;;;;;;33195:12;;33188:34;;;33209:12;;;;33188:34;;;;;;;33140:14;33317:29;;33090:15;33342:3;33317:5;:29::i;:::-;-1:-1:-1;;;;;33256:124:0;;33381:10;33434:9;;;;;;;;;-1:-1:-1;;;;;33434:9:0;-1:-1:-1;;;;;33401:42:0;:30;33407:6;:14;;;33423:3;33428:2;33401:5;:30::i;:::-;:42;;;;:::i;:::-;33256:203;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:211;;33463:4;33256:211;33233:276;;;;-1:-1:-1;;;33233:276:0;;;;;;;:::i;:::-;33562:9;;33535:14;;33574:15;;-1:-1:-1;;;33562:9:0;;-1:-1:-1;;;;;33562:9:0;;33529:30;;33551:3;33556:2;33529:5;:30::i;:::-;:42;;;;:::i;:::-;:60;33520:86;;;;-1:-1:-1;;;33520:86:0;;;;;;;:::i;:::-;33659:9;;33632:14;;33671:15;;-1:-1:-1;;;33659:9:0;;-1:-1:-1;;;;;33659:9:0;;33626:30;;33648:3;33653:2;33626:5;:30::i;:::-;:42;;;;:::i;:::-;:60;33617:82;;;;-1:-1:-1;;;33617:82:0;;;;;;;:::i;:::-;33878:14;;33872:30;;33894:3;33899:2;33872:5;:30::i;:::-;33904:10;33855:60;;;;;;;;;:::i;:::-;;;;;;;;;;;;;33845:71;;;;;;33829:12;:87;33820:134;;;;-1:-1:-1;;;33820:134:0;;;;;;;:::i;:::-;34132:10;34115:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;34105:39;;;;;;34091:10;:53;34082:84;;;;-1:-1:-1;;;34082:84:0;;;;;;;:::i;:::-;34179:20;34202:29;34208:6;:14;;;34224:1;34227:3;34202:5;:29::i;:::-;34179:52;;34306:1;34291:12;:16;34282:42;;;;-1:-1:-1;;;34282:42:0;;;;;;;:::i;:::-;34337:21;34361:4;:19;;34381:15;34361:36;;;;;;-1:-1:-1;;;34361:36:0;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;34361:36:0;;-1:-1:-1;34425:11:0;;;34437:17;:15;34453:1;34437:17;:::i;:::-;34425:30;;;;;;-1:-1:-1;;;34425:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;34425:30:0;-1:-1:-1;;;;;34408:47:0;;;34466:14;34483:4;:11;;34495:15;34511:1;34495:17;;;;:::i;:::-;:21;;34515:1;34495:21;:::i;:::-;34483:34;;;;;;-1:-1:-1;;;34483:34:0;;;;;;;;;;;;;;;;;;;;;;34615:15;;34483:34;;;;;;;;;;-1:-1:-1;;;;;34483:34:0;;-1:-1:-1;;;;;;34615:15:0;;;34598:32;;;;34594:301;;;34668:11;-1:-1:-1;;;;;34655:24:0;:9;:24;34647:53;;;;-1:-1:-1;;;34647:53:0;;;;;;;:::i;:::-;34594:301;;;34753:58;;-1:-1:-1;;;34753:58:0;;34733:17;;-1:-1:-1;;;;;34753:31:0;;;;;:58;;34785:10;;34805:4;;34753:58;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;34733:78;;34847:11;-1:-1:-1;;;;;34834:24:0;:9;:24;;34826:57;;;;-1:-1:-1;;;34826:57:0;;;;;;;:::i;:::-;34594:301;;34907:22;35049:55;35062:33;35075:11;-1:-1:-1;;;;;35062:33:0;35088:6;35062:12;:33::i;:::-;35097:6;35049:12;:55::i;:::-;35032:72;;35178:1;35161:14;:18;35153:65;;;;-1:-1:-1;;;35153:65:0;;;;;;;:::i;:::-;35231:13;35247:31;35253:6;:14;;;35269:3;35274;35247:5;:31::i;:::-;35231:47;;35310:5;35293:14;:22;35289:688;;;35421:5;35404:22;;35463:49;35476:27;35489:5;35496:6;35476:12;:27::i;35463:49::-;35441:72;;35289:688;;;35584:12;35567:14;:29;35563:414;;;35680:12;35663:29;;35729:56;35742:34;35755:12;35769:6;35742:12;:34::i;35729:56::-;35878:15;;35707:79;;-1:-1:-1;;;;;;35861:32:0;;;35878:15;;35861:32;35857:108;;;35920:10;35912:53;35941:23;-1:-1:-1;;;;;35941:23:0;;:9;:23;:::i;:::-;35912:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35857:108;36013:5;35995:14;:23;;35987:32;;;;;;36152:137;36165:4;:21;;36187:15;36165:38;;;;;;-1:-1:-1;;;36165:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;36165:38:0;-1:-1:-1;;;;;36152:137:0;36277:11;-1:-1:-1;;;;;36152:137:0;:12;:137::i;:::-;36103:4;:21;;36125:15;36103:38;;;;;;-1:-1:-1;;;36103:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;:187;;;;;-1:-1:-1;;;;;36103:187:0;;;;;-1:-1:-1;;;;;36103:187:0;;;;;;36427:4;:16;;:28;36444:10;-1:-1:-1;;;;;36427:28:0;-1:-1:-1;;;;;36427:28:0;;;;;;;;;;;;;36459:1;36427:33;36418:62;;;;-1:-1:-1;;;36418:62:0;;;;;;;:::i;:::-;36574:78;36585:6;:14;;;36601:1;36604:3;36609:42;36622:12;36636:14;36609:12;:42::i;:::-;36574:10;:78::i;:::-;36559:12;;;:93;36680:10;36663:28;;;;:16;;;:28;;;;;:45;;;36856:15;;-1:-1:-1;;;;;36839:32:0;;;36856:15;;36839:32;36835:143;;36888:78;-1:-1:-1;;;;;36888:38:0;;36927:10;36947:4;-1:-1:-1;;;;;36888:78:0;;:38;:78::i;:::-;37026:91;37038:2;37042:10;37054:13;37069:4;:18;;;;;;;;;;-1:-1:-1;;;;;37069:18:0;37089:11;37102:14;37026:91;;;;;;;;;;;:::i;:::-;;;;;;;;37306:16;;;;;;37302:232;;37359:18;;;;37344:77;;-1:-1:-1;;;;;37359:18:0;37387:4;37394:10;37406:14;37344;:77::i;:::-;37441:81;37454:2;37458:10;37470:15;37487:14;37503:4;:18;;;;;;;;;;-1:-1:-1;;;;;37503:18:0;37441:81;;;;;;;;;;:::i;:::-;;;;;;;;37302:232;-1:-1:-1;37565:14:0;32924:4663;-1:-1:-1;;;;;;;;;;;;32924:4663:0:o;40836:1743::-;40885:17;40905:14;;;:10;:14;;;;;;;;40952:12;;;;-1:-1:-1;;;40952:12:0;;-1:-1:-1;;;;;40952:12:0;40938:10;:26;40930:74;;;;-1:-1:-1;;;40930:74:0;;;;;;;:::i;:::-;41017:18;41069:9;;41044:12;;-1:-1:-1;;;41069:9:0;;;-1:-1:-1;;;;;41069:9:0;;41038:28;;41058:3;41063:2;41038:5;:28::i;:::-;:40;;;;:::i;:::-;41017:61;;41089:24;41116:27;41122:4;:12;;;41136:1;41139:3;41116:5;:27::i;:::-;41089:54;;41231:15;41217:10;:29;;:54;;;-1:-1:-1;41250:21:0;;41217:54;41209:82;;;;-1:-1:-1;;;41209:82:0;;;;;;;:::i;:::-;41344:21;;41340:133;;41397:18;;;;41382:79;;-1:-1:-1;;;;;41397:18:0;41425:4;41432:10;41444:16;41382:14;:79::i;:::-;41652:9;41647:460;41671:19;;;:26;41667:30;;41647:460;;;41750:1;41723:4;:21;;41745:1;41723:24;;;;;;-1:-1:-1;;;41723:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;41723:24:0;:28;41719:377;;;41828:15;;;41802:19;;;:22;;-1:-1:-1;;;;;41828:15:0;;;;41822:1;;41802:22;;;;-1:-1:-1;;;41802:22:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;41802:22:0;:41;41798:282;;41866:91;41881:4;:19;;41901:1;41881:22;;;;;;-1:-1:-1;;;41881:22:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;41881:22:0;41913:4;41920:10;41932:4;:21;;41954:1;41932:24;;;;;;-1:-1:-1;;;41932:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;41932:24:0;41866:14;:91::i;:::-;41798:282;;;42034:10;-1:-1:-1;;;;;42026:28:0;:54;42055:4;:21;;42077:1;42055:24;;;;;;-1:-1:-1;;;42055:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;42055:24:0;-1:-1:-1;;;;;42026:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41798:282;41699:3;;;;:::i;:::-;;;;41647:460;;;-1:-1:-1;42142:18:0;;;;42122:80;;;;;;42138:2;;-1:-1:-1;;;;;42142:18:0;;42162:16;;42180:21;;;;42122:80;:::i;:::-;;;;;;;;42253:1;42238:16;;;42265:12;;;:16;;;42307:15;;42292:12;;;:30;;-1:-1:-1;;;;;;42292:30:0;-1:-1:-1;;;;;42307:15:0;;;-1:-1:-1;;;42292:30:0;;;;;;;42333:239;42357:19;;;:26;42353:30;;42333:239;;;42430:15;;;42405:19;;;:22;;-1:-1:-1;;;;;42430:15:0;;;;42425:1;;42405:22;;;;-1:-1:-1;;;42405:22:0;;;;;;;;;;;;;;;;;:40;;;;;-1:-1:-1;;;;;42405:40:0;;;;;-1:-1:-1;;;;;42405:40:0;;;;;;42487:1;42460:4;:21;;42482:1;42460:24;;;;;;-1:-1:-1;;;42460:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;:28;;;;;-1:-1:-1;;;;;42460:28:0;;;;;-1:-1:-1;;;;;42460:28:0;;;;;;42522:1;42503:4;:11;;42515:1;42517;42515:3;;;;:::i;:::-;42503:16;;;;;;-1:-1:-1;;;42503:16:0;;;;;;;;;;;;;;;;;;;;;;;;;;;:20;;;;;-1:-1:-1;;;;;42503:20:0;;;;;-1:-1:-1;;;;;42503:20:0;;;;;;42559:1;42538:4;:11;;42550:1;42552;42550:3;;;;:::i;:::-;:5;;42554:1;42550:5;:::i;:::-;42538:18;;;;;;-1:-1:-1;;;42538:18:0;;;;;;;;;;;;;;;;;;;;;;;;;;;:22;;;;;-1:-1:-1;;;;;42538:22:0;;;;;-1:-1:-1;;;;;42538:22:0;;;;;;42385:3;;;;;:::i;:::-;;;;42333:239;;;;40836:1743;;;;:::o;39942:234::-;40017:17;40037:14;;;:10;:14;;;;;;;;40070:12;;;;-1:-1:-1;;;40070:12:0;;-1:-1:-1;;;;;40070:12:0;40086:10;40070:26;40062:56;;;;-1:-1:-1;;;40062:56:0;;;;;;;:::i;:::-;40129:16;;:39;;-1:-1:-1;;40129:39:0;;;;;;;;;;;;-1:-1:-1;39942:234:0:o;28873:3312::-;29208:5;:8;;;;;:5;:8;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;29244:4;29235:6;:13;29227:69;;;;-1:-1:-1;;;29227:69:0;;;;;;;:::i;:::-;29322:12;29315:4;:19;:40;;;-1:-1:-1;29338:17:0;;29315:40;29307:96;;;;-1:-1:-1;;;29307:96:0;;;;;;;:::i;:::-;29432:13;29422:6;:23;;29414:92;;;;-1:-1:-1;;;29414:92:0;;;;;;;:::i;:::-;-1:-1:-1;;;29525:13:0;:24;29517:90;;;;-1:-1:-1;;;29517:90:0;;;;;;;:::i;:::-;29626:56;;-1:-1:-1;;;29626:56:0;;29686:13;;-1:-1:-1;;;;;29626:29:0;;;;;:56;;29656:10;;29676:4;;29626:56;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:73;;29618:107;;;;-1:-1:-1;;;29618:107:0;;;;;;;:::i;:::-;29769:1;29744:15;:22;:26;29736:78;;;;-1:-1:-1;;;29736:78:0;;;;;;;:::i;:::-;29855:22;;29851:26;;:1;:26;:::i;:::-;29833:7;:14;:44;29825:100;;;;-1:-1:-1;;;29825:100:0;;;;;;;:::i;:::-;29938:11;30008:5;;30015:4;;29962:58;;;;29979:10;;29991:15;;30008:5;;;;;29962:58;;;:::i;:::-;;;;-1:-1:-1;;29962:58:0;;;;;;;;;29952:69;;29962:58;29952:69;;;;30032:17;30052:15;;;:10;:15;;;;;29952:69;;-1:-1:-1;30093:42:0;30099:14;30115:5;30122:6;30130:4;30093:5;:42::i;:::-;30078:57;;30200:28;30206:13;30221:6;30200:5;:28::i;:::-;30185:12;;;:43;30292:16;;;:39;;-1:-1:-1;;30292:39:0;;;;;-1:-1:-1;;;;;;30407:25:0;30422:10;-1:-1:-1;;;30407:25:0;;;;30509:37;;;;:19;;;;:37;;;;;:::i;:::-;-1:-1:-1;30611:18:0;;;:32;;-1:-1:-1;;;;;;30611:32:0;-1:-1:-1;;;;;30611:32:0;;;;;-1:-1:-1;30771:346:0;30795:15;:22;30791:1;:26;30771:346;;;30865:15;;30843:18;;-1:-1:-1;;;;;30865:15:0;;;;30843;;30859:1;;30843:18;;;;-1:-1:-1;;;30843:18:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;30843:37:0;;30839:222;;31022:1;30986:15;31002:1;30986:18;;;;;;-1:-1:-1;;;30986:18:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;30979:38:0;;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;30971:74;;;;-1:-1:-1;;;30971:74:0;;;;;;;:::i;:::-;31075:21;;;:29;;;;;;;;-1:-1:-1;31075:29:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;31075:29:0;;;;;;;30819:3;;;;:::i;:::-;;;;30771:346;;;;31199:9;31194:711;31218:7;:14;31214:1;:18;31194:711;;;31256:12;31271:38;31284:7;31292:1;31284:10;;;;;;-1:-1:-1;;;31284:10:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;31271:38:0;31296:7;31304:1;31306;31304:3;;;;:::i;:::-;31296:12;;;;;;-1:-1:-1;;;31296:12:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;31271:38:0;:12;:38::i;:::-;31256:53;-1:-1:-1;31366:12:0;31381:38;31394:7;31402:3;:1;31404;31402:3;:::i;:::-;31394:12;;;;;;-1:-1:-1;;;31394:12:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;31381:38:0;31408:7;31416:1;31408:10;;;;;;-1:-1:-1;;;31408:10:0;;;;;;;;31381:38;31366:53;;31494:7;31502:1;31494:10;;;;;;-1:-1:-1;;;31494:10:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;31494:15:0;31508:1;31494:15;31490:404;;;31546:7;31554:3;:1;31556;31554:3;:::i;:::-;31546:12;;;;;;-1:-1:-1;;;31546:12:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;31538:20:0;:4;:20;31530:29;;;;;;31490:404;;;31585:7;31593:3;:1;31595;31593:3;:::i;:::-;31585:12;;;;;;-1:-1:-1;;;31585:12:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;31585:17:0;31601:1;31585:17;31581:313;;;31639:7;31647:1;31639:10;;;;;;-1:-1:-1;;;31639:10:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;31631:18:0;:4;:18;31623:27;;;;;31581:313;31806:7;31814:1;31806:10;;;;;;-1:-1:-1;;;31806:10:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;31783:33:0;31790:7;31798:1;31800;31798:3;;;;:::i;:::-;31790:12;;;;;;-1:-1:-1;;;31790:12:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;31783:19:0;:4;:19;;;;:::i;:::-;:33;;31775:42;;;;;;31865:7;31873:3;:1;31875;31873:3;:::i;:::-;31865:12;;;;;;-1:-1:-1;;;31865:12:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;31844:33:0;31851:7;31859:1;31851:10;;;;;;-1:-1:-1;;;31851:10:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;31844:17:0;:4;:17;;;;:::i;:::-;:33;;31836:42;;;;;;-1:-1:-1;31234:5:0;;-1:-1:-1;31238:1:0;31234:5;;:::i;:::-;;;31194:711;;;-1:-1:-1;31915:21:0;;;;:11;;;;:21;;;;;:::i;:::-;-1:-1:-1;31999:78:0;-1:-1:-1;;;;;31999:36:0;;32036:10;32056:4;32063:13;31999:36;:78::i;:::-;32095:82;32107:13;32122:3;32127:10;32139:15;32156:11;32169:7;32095:82;;;;;;;;;;;:::i;:::-;;;;;;;;28873:3312;;;;;;;;;;;;;:::o;46521:336::-;46604:15;46640:21;46651:3;46656:4;46640:10;:21::i;:::-;46632:58;;;;-1:-1:-1;;;46632:58:0;;;;;;;:::i;:::-;-1:-1:-1;;;46813:1:0;46799:12;;;46795:20;46817:19;;;46791:46;;46710:140::o;48263:333::-;48436:47;;-1:-1:-1;;;48436:47:0;;48487:6;;-1:-1:-1;;;;;48436:31:0;;;;;:47;;48468:14;;48436:47;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:57;;48428:88;;;;-1:-1:-1;;;48428:88:0;;;;;;;:::i;:::-;48527:61;-1:-1:-1;;;;;48527:34:0;;48562:17;48581:6;48527:34;:61::i;:::-;48263:333;;;;:::o;18304:98::-;18362:7;18389:5;18393:1;18389;:5;:::i;:::-;18382:12;18304:98;-1:-1:-1;;;18304:98:0:o;18703:::-;18761:7;18788:5;18792:1;18788;:5;:::i;17566:98::-;17624:7;17651:5;17655:1;17651;:5;:::i;17947:98::-;18005:7;18032:5;18036:1;18032;:5;:::i;47558:395::-;47915:19;;47908:1;47894:12;;;-1:-1:-1;;47890:20:0;47876:35;;;47872:40;47862:51;;;;47858:77;;47721:225::o;11751:205::-;11852:96;11872:5;11902:27;;;11931:4;11937:2;11941:5;11879:68;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;11879:68:0;;;;;;;;;;;;;;-1:-1:-1;;;;;11879:68:0;-1:-1:-1;;;;;;11879:68:0;;;;;;;;;;11852:19;:96::i;44486:613::-;44616:15;;44687:46;44616:15;44694:3;-1:-1:-1;;;;;44700:32:0;;44687:3;:46::i;:::-;44675:58;44789:35;44793:3;44798:2;44820:3;44802:21;;;44789:3;:35::i;:::-;44777:47;44888:20;44892:3;44897:2;44901:6;44888:3;:20::i;:::-;44876:32;44986:18;44990:3;44995:2;44999:4;44986:3;:18::i;:::-;44974:30;;44486:613;-1:-1:-1;;;;;44486:613:0:o;45298:339::-;45376:15;;45447:26;45376:15;45454:3;45459:13;45447:3;:26::i;:::-;45435:38;45545:21;45549:3;;45559:6;45545:3;:21::i;:::-;45533:33;;45298:339;-1:-1:-1;;;45298:339:0:o;47023:234::-;47210:3;47201:13;;47229:1;47219:12;;;47216:22;47198:41;;47128:122::o;11566:177::-;11649:86;11669:5;11699:23;;;11724:2;11728:5;11676:58;;;;;;;;;:::i;14000:761::-;14424:23;14450:69;14478:4;14450:69;;;;;;;;;;;;;;;;;14458:5;-1:-1:-1;;;;;14450:27:0;;;:69;;;;;:::i;:::-;14534:17;;14424:95;;-1:-1:-1;14534:21:0;14530:224;;14676:10;14665:30;;;;;;;;;;;;:::i;:::-;14657:85;;;;-1:-1:-1;;;14657:85:0;;;;;;;:::i;45934:278::-;46015:13;46049:22;46060:4;46066;46049:10;:22::i;:::-;46041:57;;;;-1:-1:-1;;;46041:57:0;;;;;;;:::i;:::-;-1:-1:-1;46175:19:0;;;;46118:87;-1:-1:-1;46118:87:0:o;6592:195::-;6695:12;6727:52;6749:6;6757:4;6763:1;6766:12;6727:21;:52::i;:::-;6720:59;6592:195;-1:-1:-1;;;;6592:195:0:o;7644:530::-;7771:12;7829:5;7804:21;:30;;7796:81;;;;-1:-1:-1;;;7796:81:0;;;;;;;:::i;:::-;7896:18;7907:6;7896:10;:18::i;:::-;7888:60;;;;-1:-1:-1;;;7888:60:0;;;;;;;:::i;:::-;8022:12;8036:23;8063:6;-1:-1:-1;;;;;8063:11:0;8083:5;8091:4;8063:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8021:75;;;;8114:52;8132:7;8141:10;8153:12;8114:17;:52::i;:::-;8107:59;7644:530;-1:-1:-1;;;;;;;7644:530:0:o;3674:422::-;4041:20;;4080:8;;3674:422;;;;:::o;10184:742::-;10299:12;10328:7;10324:595;;;-1:-1:-1;10359:10:0;10352:17;;10324:595;10473:17;;:21;10469:439;;10736:10;10730:17;10797:15;10784:10;10780:2;10776:19;10769:44;10684:148;10879:12;10872:20;;-1:-1:-1;;;10872:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:175:1;84:20;;-1:-1:-1;;;;;133:31:1;;123:42;;113:2;;179:1;176;169:12;194:714;;307:3;300:4;292:6;288:17;284:27;274:2;;329:5;322;315:20;274:2;369:6;356:20;395:4;419:66;435:49;481:2;435:49;:::i;:::-;419:66;:::i;:::-;519:15;;;550:12;;;;582:15;;;628:11;;;616:24;;612:33;;609:42;-1:-1:-1;606:2:1;;;668:5;661;654:20;606:2;694:5;708:171;722:2;719:1;716:9;708:171;;;779:25;800:3;779:25;:::i;:::-;767:38;;825:12;;;;857;;;;740:1;733:9;708:171;;;-1:-1:-1;897:5:1;;264:644;-1:-1:-1;;;;;;;264:644:1:o;913:714::-;;1026:3;1019:4;1011:6;1007:17;1003:27;993:2;;1048:5;1041;1034:20;993:2;1088:6;1075:20;1114:4;1138:66;1154:49;1200:2;1154:49;:::i;1138:66::-;1238:15;;;1269:12;;;;1301:15;;;1347:11;;;1335:24;;1331:33;;1328:42;-1:-1:-1;1325:2:1;;;1387:5;1380;1373:20;1325:2;1413:5;1427:171;1441:2;1438:1;1435:9;1427:171;;;1498:25;1519:3;1498:25;:::i;:::-;1486:38;;1544:12;;;;1576;;;;1459:1;1452:9;1427:171;;1632:553;;1730:3;1723:4;1715:6;1711:17;1707:27;1697:2;;1752:5;1745;1738:20;1697:2;1792:6;1779:20;1818:18;1814:2;1811:26;1808:2;;;1840:18;;:::i;:::-;1884:55;1927:2;1908:13;;-1:-1:-1;;1904:27:1;1933:4;1900:38;1884:55;:::i;:::-;1964:2;1955:7;1948:19;2010:3;2003:4;1998:2;1990:6;1986:15;1982:26;1979:35;1976:2;;;2031:5;2024;2017:20;1976:2;2100;2093:4;2085:6;2081:17;2074:4;2065:7;2061:18;2048:55;2123:16;;;2141:4;2119:27;2112:42;;;;2127:7;1687:498;-1:-1:-1;;1687:498:1:o;2190:190::-;2260:20;;-1:-1:-1;;;;;2309:46:1;;2299:57;;2289:2;;2370:1;2367;2360:12;2385:954;;2500:2;2543;2531:9;2522:7;2518:23;2514:32;2511:2;;;2564:6;2556;2549:22;2511:2;2609:9;2596:23;2642:18;2634:6;2631:30;2628:2;;;2679:6;2671;2664:22;2628:2;2707:22;;2760:4;2752:13;;2748:27;-1:-1:-1;2738:2:1;;2794:6;2786;2779:22;2738:2;2835;2822:16;2858:66;2874:49;2920:2;2874:49;:::i;2858:66::-;2958:15;;;2989:12;;;;3021:11;;;3059;;;3051:20;;3047:29;;3044:42;-1:-1:-1;3041:2:1;;;3104:6;3096;3089:22;3041:2;3131:6;3122:15;;3146:163;3160:2;3157:1;3154:9;3146:163;;;3217:17;;3205:30;;3178:1;3171:9;;;;;3255:12;;;;3287;;3146:163;;;-1:-1:-1;3328:5:1;2480:859;-1:-1:-1;;;;;;;2480:859:1:o;3344:297::-;;3464:2;3452:9;3443:7;3439:23;3435:32;3432:2;;;3485:6;3477;3470:22;3432:2;3522:9;3516:16;3575:5;3568:13;3561:21;3554:5;3551:32;3541:2;;3602:6;3594;3587:22;3646:190;;3758:2;3746:9;3737:7;3733:23;3729:32;3726:2;;;3779:6;3771;3764:22;3726:2;-1:-1:-1;3807:23:1;;3716:120;-1:-1:-1;3716:120:1:o;3841:472::-;;;;;;4021:3;4009:9;4000:7;3996:23;3992:33;3989:2;;;4043:6;4035;4028:22;3989:2;4084:9;4071:23;4061:33;;4141:2;4130:9;4126:18;4113:32;4103:42;;4192:2;4181:9;4177:18;4164:32;4154:42;;4243:2;4232:9;4228:18;4215:32;4205:42;;4266:41;4302:3;4291:9;4287:19;4266:41;:::i;:::-;4256:51;;3979:334;;;;;;;;:::o;4318:258::-;;;4447:2;4435:9;4426:7;4422:23;4418:32;4415:2;;;4468:6;4460;4453:22;4415:2;-1:-1:-1;;4496:23:1;;;4566:2;4551:18;;;4538:32;;-1:-1:-1;4405:171:1:o;4581:1400::-;;;;;;;;;;;;4924:3;4912:9;4903:7;4899:23;4895:33;4892:2;;;4946:6;4938;4931:22;4892:2;4987:9;4974:23;4964:33;;5044:2;5033:9;5029:18;5016:32;5006:42;;5095:2;5084:9;5080:18;5067:32;5057:42;;5118:18;5185:2;5179;5168:9;5164:18;5151:32;5148:40;5145:2;;;5206:6;5198;5191:22;5145:2;5234:78;5304:7;5297:2;5286:9;5282:18;5269:32;5258:9;5254:48;5234:78;:::i;:::-;5224:88;;5362:2;5355:3;5344:9;5340:19;5327:33;5324:41;5321:2;;;5383:6;5375;5368:22;5321:2;5411:94;5497:7;5489:3;5478:9;5474:19;5461:33;5450:9;5446:49;5411:94;:::i;:::-;5401:104;;5555:2;5548:3;5537:9;5533:19;5520:33;5517:41;5514:2;;;5576:6;5568;5561:22;5514:2;;5604:94;5690:7;5682:3;5671:9;5667:19;5654:33;5643:9;5639:49;5604:94;:::i;:::-;5594:104;;5745:3;5734:9;5730:19;5717:33;5707:43;;5769:41;5805:3;5794:9;5790:19;5769:41;:::i;:::-;5759:51;;5857:3;5846:9;5842:19;5829:33;5819:43;;5909:3;5898:9;5894:19;5881:33;5871:43;;5934:41;5970:3;5959:9;5955:19;5934:41;:::i;:::-;5923:52;;4882:1099;;;;;;;;;;;;;;:::o;5986:194::-;;6109:2;6097:9;6088:7;6084:23;6080:32;6077:2;;;6130:6;6122;6115:22;6077:2;-1:-1:-1;6158:16:1;;6067:113;-1:-1:-1;6067:113:1:o;6185:484::-;;6282:5;6276:12;6309:6;6304:3;6297:19;6335:4;6364:2;6359:3;6355:12;6348:19;;6401:2;6394:5;6390:14;6422:3;6434:210;6448:6;6445:1;6442:13;6434:210;;;6513:13;;-1:-1:-1;;;;;6509:54:1;6497:67;;6584:12;;;;6619:15;;;;6470:1;6463:9;6434:210;;;-1:-1:-1;6660:3:1;;6252:417;-1:-1:-1;;;;;6252:417:1:o;6674:93::-;6746:13;6739:21;6727:34;;6717:50::o;6772:260::-;;6854:5;6848:12;6881:6;6876:3;6869:19;6897:63;6953:6;6946:4;6941:3;6937:14;6930:4;6923:5;6919:16;6897:63;:::i;:::-;7014:2;6993:15;-1:-1:-1;;6989:29:1;6980:39;;;;7021:4;6976:50;;6824:208;-1:-1:-1;;6824:208:1:o;7037:121::-;-1:-1:-1;;;;;7105:46:1;7093:59;;7083:75::o;7163:229::-;7312:2;7308:15;;;;-1:-1:-1;;;;;;7304:53:1;7292:66;;7383:2;7374:12;;7282:110::o;7397:459::-;7628:2;7624:15;;;;-1:-1:-1;;;;;;7620:53:1;7608:66;;7699:2;7690:12;;7683:28;;;;7767:3;7745:16;-1:-1:-1;;;;;;7741:43:1;7736:2;7727:12;;7720:65;7810:2;7801:12;;7794:28;7847:2;7838:12;;7598:258::o;7861:274::-;;8028:6;8022:13;8044:53;8090:6;8085:3;8078:4;8070:6;8066:17;8044:53;:::i;:::-;8113:16;;;;;7998:137;-1:-1:-1;;7998:137:1:o;8140:294::-;8297:19;;;8354:2;8350:15;-1:-1:-1;;;;;;8346:53:1;8341:2;8332:12;;8325:75;8425:2;8416:12;;8287:147::o;8439:203::-;-1:-1:-1;;;;;8603:32:1;;;;8585:51;;8573:2;8558:18;;8540:102::o;8647:304::-;-1:-1:-1;;;;;8877:15:1;;;8859:34;;8929:15;;8924:2;8909:18;;8902:43;8809:2;8794:18;;8776:175::o;8956:375::-;-1:-1:-1;;;;;9214:15:1;;;9196:34;;9266:15;;;;9261:2;9246:18;;9239:43;9313:2;9298:18;;9291:34;;;;9146:2;9131:18;;9113:218::o;9336:274::-;-1:-1:-1;;;;;9528:32:1;;;;9510:51;;9592:2;9577:18;;9570:34;9498:2;9483:18;;9465:145::o;9615:1309::-;10014:3;10067:21;;;10137:13;;10040:18;;;10159:22;;;9615:1309;;10212:3;10197:19;;;10235:4;;10262:15;;;9615:1309;10308:195;10322:6;10319:1;10316:13;10308:195;;;10387:13;;-1:-1:-1;;;;;10383:39:1;10371:52;;10443:12;;;;10478:15;;;;10419:1;10337:9;10308:195;;;-1:-1:-1;;;10519:18:1;;10512:34;;;10555:45;10596:2;10581:18;;10573:6;10555:45;:::i;:::-;10609;10650:2;10639:9;10635:18;10627:6;10609:45;:::i;:::-;10663:46;10704:3;10693:9;10689:19;10681:6;10663:46;:::i;:::-;10746:6;10740:3;10729:9;10725:19;10718:35;10790:6;10784:3;10773:9;10769:19;10762:35;10843:9;10838:3;10834:19;10828:3;10817:9;10813:19;10806:48;10871:47;10914:3;10906:6;10871:47;:::i;:::-;10863:55;9994:930;-1:-1:-1;;;;;;;;;;;9994:930:1:o;10929:641::-;11216:25;;;-1:-1:-1;;;;;11315:15:1;;;11310:2;11295:18;;11288:43;11367:15;;;11362:2;11347:18;;11340:43;11419:15;;11414:2;11399:18;;11392:43;-1:-1:-1;;;;;11472:47:1;;;11466:3;11451:19;;11444:76;11268:3;11536:19;;11529:35;11203:3;11188:19;;11170:400::o;11575:345::-;11777:25;;;-1:-1:-1;;;;;11838:32:1;;;;11833:2;11818:18;;11811:60;11902:2;11887:18;;11880:34;11765:2;11750:18;;11732:188::o;11925:1664::-;;12177:3;12218:2;12207:9;12203:18;12248:6;12237:9;12230:25;12274:2;12341:1;12337;12332:3;12328:11;12324:19;12316:6;12312:32;12307:2;12296:9;12292:18;12285:60;12364:2;12402:6;12397:2;12386:9;12382:18;12375:34;12445:2;12440;12429:9;12425:18;12418:30;12468:6;12503;12497:13;12526:68;12587:6;12579;12526:68;:::i;:::-;12519:75;;12617:54;12664:6;12617:54;:::i;:::-;12603:68;;12699:4;12712:452;12832:1;12881:6;12876:2;12863:11;12859:20;12856:32;12846:2;;12892:5;;;12846:2;12930:6;12924:13;12950:72;13018:3;-1:-1:-1;;;;;12975:4:1;12971:45;12950:72;:::i;:::-;13035:49;13080:2;13075:3;13071:12;13064:4;13060:2;13056:13;13035:49;:::i;:::-;-1:-1:-1;13139:15:1;;;;;13104:12;;;;12787:1;12770:19;12712:452;;;13187:13;;;13212:23;;;13209:2;;;13258:74;13328:3;-1:-1:-1;;;;;13283:6:1;13279:47;13258:74;:::i;:::-;13352:12;;;;13409:1;13392:19;13209:2;13449:6;13436:11;13433:23;13430:2;;;13479:42;13517:3;13508:6;13504:2;13500:15;13479:42;:::i;:::-;13541:12;;;;13430:2;-1:-1:-1;13580:3:1;;12157:1432;-1:-1:-1;;;;;;;;;;;12157:1432:1:o;13594:519::-;13853:25;;;-1:-1:-1;;;;;13952:15:1;;;13947:2;13932:18;;13925:43;13999:2;13984:18;;13977:34;;;;14042:2;14027:18;;14020:34;14091:15;14085:3;14070:19;;14063:44;13840:3;13825:19;;13807:306::o;14118:222::-;;14267:2;14256:9;14249:21;14287:47;14330:2;14319:9;14315:18;14307:6;14287:47;:::i;14345:348::-;14547:2;14529:21;;;14586:2;14566:18;;;14559:30;14625:26;14620:2;14605:18;;14598:54;14684:2;14669:18;;14519:174::o;14698:398::-;14900:2;14882:21;;;14939:2;14919:18;;;14912:30;14978:34;14973:2;14958:18;;14951:62;-1:-1:-1;;;15044:2:1;15029:18;;15022:32;15086:3;15071:19;;14872:224::o;15101:399::-;15303:2;15285:21;;;15342:2;15322:18;;;15315:30;15381:34;15376:2;15361:18;;15354:62;-1:-1:-1;;;15447:2:1;15432:18;;15425:33;15490:3;15475:19;;15275:225::o;15505:403::-;15707:2;15689:21;;;15746:2;15726:18;;;15719:30;15785:34;15780:2;15765:18;;15758:62;-1:-1:-1;;;15851:2:1;15836:18;;15829:37;15898:3;15883:19;;15679:229::o;15913:417::-;16115:2;16097:21;;;16154:2;16134:18;;;16127:30;16193:34;16188:2;16173:18;;16166:62;-1:-1:-1;;;16259:2:1;16244:18;;16237:51;16320:3;16305:19;;16087:243::o;16335:342::-;16537:2;16519:21;;;16576:2;16556:18;;;16549:30;-1:-1:-1;;;16610:2:1;16595:18;;16588:48;16668:2;16653:18;;16509:168::o;16682:339::-;16884:2;16866:21;;;16923:2;16903:18;;;16896:30;-1:-1:-1;;;16957:2:1;16942:18;;16935:45;17012:2;16997:18;;16856:165::o;17026:339::-;17228:2;17210:21;;;17267:2;17247:18;;;17240:30;-1:-1:-1;;;17301:2:1;17286:18;;17279:45;17356:2;17341:18;;17200:165::o;17370:407::-;17572:2;17554:21;;;17611:2;17591:18;;;17584:30;17650:34;17645:2;17630:18;;17623:62;-1:-1:-1;;;17716:2:1;17701:18;;17694:41;17767:3;17752:19;;17544:233::o;17782:347::-;17984:2;17966:21;;;18023:2;18003:18;;;17996:30;18062:25;18057:2;18042:18;;18035:53;18120:2;18105:18;;17956:173::o;18134:338::-;18336:2;18318:21;;;18375:2;18355:18;;;18348:30;-1:-1:-1;;;18409:2:1;18394:18;;18387:44;18463:2;18448:18;;18308:164::o;18477:402::-;18679:2;18661:21;;;18718:2;18698:18;;;18691:30;18757:34;18752:2;18737:18;;18730:62;-1:-1:-1;;;18823:2:1;18808:18;;18801:36;18869:3;18854:19;;18651:228::o;18884:336::-;19086:2;19068:21;;;19125:2;19105:18;;;19098:30;-1:-1:-1;;;19159:2:1;19144:18;;19137:42;19211:2;19196:18;;19058:162::o;19225:345::-;19427:2;19409:21;;;19466:2;19446:18;;;19439:30;-1:-1:-1;;;19500:2:1;19485:18;;19478:51;19561:2;19546:18;;19399:171::o;19575:344::-;19777:2;19759:21;;;19816:2;19796:18;;;19789:30;-1:-1:-1;;;19850:2:1;19835:18;;19828:50;19910:2;19895:18;;19749:170::o;19924:407::-;20126:2;20108:21;;;20165:2;20145:18;;;20138:30;20204:34;20199:2;20184:18;;20177:62;-1:-1:-1;;;20270:2:1;20255:18;;20248:41;20321:3;20306:19;;20098:233::o;20336:341::-;20538:2;20520:21;;;20577:2;20557:18;;;20550:30;-1:-1:-1;;;20611:2:1;20596:18;;20589:47;20668:2;20653:18;;20510:167::o;20682:341::-;20884:2;20866:21;;;20923:2;20903:18;;;20896:30;-1:-1:-1;;;20957:2:1;20942:18;;20935:47;21014:2;20999:18;;20856:167::o;21028:331::-;21230:2;21212:21;;;21269:1;21249:18;;;21242:29;-1:-1:-1;;;21302:2:1;21287:18;;21280:38;21350:2;21335:18;;21202:157::o;21364:346::-;21566:2;21548:21;;;21605:2;21585:18;;;21578:30;-1:-1:-1;;;21639:2:1;21624:18;;21617:52;21701:2;21686:18;;21538:172::o;21715:336::-;21917:2;21899:21;;;21956:2;21936:18;;;21929:30;-1:-1:-1;;;21990:2:1;21975:18;;21968:42;22042:2;22027:18;;21889:162::o;22056:353::-;22258:2;22240:21;;;22297:2;22277:18;;;22270:30;22336:31;22331:2;22316:18;;22309:59;22400:2;22385:18;;22230:179::o;22414:420::-;22616:2;22598:21;;;22655:2;22635:18;;;22628:30;22694:34;22689:2;22674:18;;22667:62;22765:26;22760:2;22745:18;;22738:54;22824:3;22809:19;;22588:246::o;22839:399::-;23041:2;23023:21;;;23080:2;23060:18;;;23053:30;23119:34;23114:2;23099:18;;23092:62;-1:-1:-1;;;23185:2:1;23170:18;;23163:33;23228:3;23213:19;;23013:225::o;23243:340::-;23445:2;23427:21;;;23484:2;23464:18;;;23457:30;-1:-1:-1;;;23518:2:1;23503:18;;23496:46;23574:2;23559:18;;23417:166::o;23588:337::-;23790:2;23772:21;;;23829:2;23809:18;;;23802:30;-1:-1:-1;;;23863:2:1;23848:18;;23841:43;23916:2;23901:18;;23762:163::o;23930:406::-;24132:2;24114:21;;;24171:2;24151:18;;;24144:30;24210:34;24205:2;24190:18;;24183:62;-1:-1:-1;;;24276:2:1;24261:18;;24254:40;24326:3;24311:19;;24104:232::o;24341:341::-;24543:2;24525:21;;;24582:2;24562:18;;;24555:30;-1:-1:-1;;;24616:2:1;24601:18;;24594:47;24673:2;24658:18;;24515:167::o;24687:407::-;24889:2;24871:21;;;24928:2;24908:18;;;24901:30;24967:34;24962:2;24947:18;;24940:62;-1:-1:-1;;;25033:2:1;25018:18;;25011:41;25084:3;25069:19;;24861:233::o;25099:177::-;25245:25;;;25233:2;25218:18;;25200:76::o;25281:637::-;25552:25;;;25608:2;25593:18;;25586:34;;;-1:-1:-1;;;;;25694:15:1;;;25689:2;25674:18;;25667:43;25741:2;25726:18;;25719:34;;;25790:15;;25784:3;25769:19;;25762:44;25843:3;25647;25822:19;;25815:32;;;25281:637;;25864:48;;25892:19;;25884:6;25864:48;:::i;:::-;25856:56;25542:376;-1:-1:-1;;;;;;;;25542:376:1:o;25923:275::-;25994:2;25988:9;26059:2;26040:13;;-1:-1:-1;;26036:27:1;26024:40;;26094:18;26079:34;;26115:22;;;26076:62;26073:2;;;26141:18;;:::i;:::-;26177:2;26170:22;25968:230;;-1:-1:-1;25968:230:1:o;26203:192::-;;26302:18;26294:6;26291:30;26288:2;;;26324:18;;:::i;:::-;-1:-1:-1;26384:4:1;26365:17;;;26361:28;;26278:117::o;26400:144::-;;26483:17;;;26533:4;26517:21;;;26473:71::o;26721:238::-;;-1:-1:-1;;;;;26828:10:1;;;26858;;;26888:12;;;26880:21;;26877:2;;;26904:18;;:::i;:::-;26940:13;;26769:190;-1:-1:-1;;;;26769:190:1:o;26964:128::-;;27035:1;27031:6;27028:1;27025:13;27022:2;;;27041:18;;:::i;:::-;-1:-1:-1;27077:9:1;;27012:80::o;27097:217::-;;27163:1;27153:2;;-1:-1:-1;;;27188:31:1;;27242:4;27239:1;27232:15;27270:4;27195:1;27260:15;27153:2;-1:-1:-1;27299:9:1;;27143:171::o;27319:168::-;;27425:1;27421;27417:6;27413:14;27410:1;27407:21;27402:1;27395:9;27388:17;27384:45;27381:2;;;27432:18;;:::i;:::-;-1:-1:-1;27472:9:1;;27371:116::o;27492:125::-;;27560:1;27557;27554:8;27551:2;;;27565:18;;:::i;:::-;-1:-1:-1;27602:9:1;;27541:76::o;27622:258::-;27694:1;27704:113;27718:6;27715:1;27712:13;27704:113;;;27794:11;;;27788:18;27775:11;;;27768:39;27740:2;27733:10;27704:113;;;27835:6;27832:1;27829:13;27826:2;;;-1:-1:-1;;27870:1:1;27852:16;;27845:27;27675:205::o;27885:135::-;;-1:-1:-1;;27945:17:1;;27942:2;;;27965:18;;:::i;:::-;-1:-1:-1;28012:1:1;28001:13;;27932:88::o;28025:201::-;;28091:10;28136:2;28129:5;28125:14;28163:2;28154:7;28151:15;28148:2;;;28169:18;;:::i;:::-;28218:1;28205:15;;28071:155;-1:-1:-1;;;28071:155:1:o;28231:127::-;28292:10;28287:3;28283:20;28280:1;28273:31;28323:4;28320:1;28313:15;28347:4;28344:1;28337:15;28363:127;28424:10;28419:3;28415:20;28412:1;28405:31;28455:4;28452:1;28445:15;28479:4;28476:1;28469:15
Swarm Source
ipfs://514567ac97ce2a52346891fb1fa79398719dfc3625c962f89ef81e693295dbc7
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.