Overview
BERA Balance
BERA Value
$0.00More Info
Private Name Tags
ContractCreator
Multichain Info
No addresses found
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
UniversalResolver
Compiler Version
v0.8.28+commit.7893614a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity >=0.8.17 <0.9.0; import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; import {BeraDefaultResolver} from "src/resolver/Resolver.sol"; import {LowLevelCallUtils} from "src/resolver/libraries/LowLevelCallUtils.sol"; import {IExtendedResolver} from "src/resolver/interfaces/IExtendedResolver.sol"; import {INameResolver} from "src/resolver/interfaces/INameResolver.sol"; import {IAddrResolver} from "src/resolver/interfaces/IAddrResolver.sol"; import {BNS} from "src/registry/interfaces/BNS.sol"; import {NameEncoder} from "src/resolver/libraries/NameEncoder.sol"; import {BytesUtils} from "src/resolver/libraries/BytesUtils.sol"; import {HexUtils} from "src/resolver/libraries/HexUtils.sol"; /// @notice Thrown when the offchain lookup fails. error OffchainLookup(address sender, string[] urls, bytes callData, bytes4 callbackFunction, bytes extraData); /// @notice Thrown when the resolver is not found. error ResolverNotFound(); /// @notice Thrown when the resolver wildcard is not supported. error ResolverWildcardNotSupported(); /// @notice Thrown when the registry is invalid. error InvalidRegistry(); /// @notice Thrown when the array lengths do not match. error ArrayLengthsMustMatch(); /// @notice Thrown when the encrypted label length is invalid. error InvalidEncryptedLabelLength(); struct MulticallData { bytes name; bytes[] data; string[] gateways; bytes4 callbackFunction; bool isWildcard; address resolver; bytes metaData; bool[] failures; } struct OffchainLookupCallData { address sender; string[] urls; bytes callData; } struct OffchainLookupExtraData { bytes4 callbackFunction; bytes data; } interface BatchGateway { function query(OffchainLookupCallData[] memory data) external returns (bool[] memory failures, bytes[] memory responses); } /** * The Universal Resolver is a contract that handles the work of resolving a name entirely onchain, * making it possible to make a single smart contract call to resolve an BNS name. */ contract UniversalResolver is ERC165, Ownable { using Address for address; using NameEncoder for string; using BytesUtils for bytes; using HexUtils for bytes; string[] public batchGatewayURLs; BNS public immutable registry; constructor(address _registry, string[] memory _urls) Ownable(msg.sender) { if (_registry == address(0)) revert InvalidRegistry(); registry = BNS(_registry); batchGatewayURLs = _urls; } function setGatewayURLs(string[] memory _urls) public onlyOwner { batchGatewayURLs = _urls; } /** * @dev Performs BNS name resolution for the supplied name and resolution data. * @param name The name to resolve, in normalised and DNS-encoded form. * @param data The resolution data, as specified in ENSIP-10. * @return The result of resolving the name. */ function resolve(bytes calldata name, bytes memory data) external view returns (bytes memory, address) { return _resolveSingle(name, data, batchGatewayURLs, this.resolveSingleCallback.selector, ""); } function resolve(bytes calldata name, bytes[] memory data) external view returns (bytes[] memory, address) { return resolve(name, data, batchGatewayURLs); } function resolve(bytes calldata name, bytes memory data, string[] memory gateways) external view returns (bytes memory, address) { return _resolveSingle(name, data, gateways, this.resolveSingleCallback.selector, ""); } function resolve(bytes calldata name, bytes[] memory data, string[] memory gateways) public view returns (bytes[] memory, address) { return _resolve(name, data, gateways, this.resolveCallback.selector, ""); } function _resolveSingle( bytes calldata name, bytes memory data, string[] memory gateways, bytes4 callbackFunction, bytes memory metaData ) public view returns (bytes memory, address) { bytes[] memory dataArr = new bytes[](1); dataArr[0] = data; (bytes[] memory results, address resolver) = _resolve(name, dataArr, gateways, callbackFunction, metaData); return (results[0], resolver); } function _resolve( bytes calldata name, bytes[] memory data, string[] memory gateways, bytes4 callbackFunction, bytes memory metaData ) internal view returns (bytes[] memory results, address resolverAddress) { (BeraDefaultResolver resolver,, uint256 finalOffset) = findResolver(name); resolverAddress = address(resolver); if (resolverAddress == address(0)) { revert ResolverNotFound(); } bool isWildcard = finalOffset != 0; results = _multicall( MulticallData( name, data, gateways, callbackFunction, isWildcard, resolverAddress, metaData, new bool[](data.length) ) ); } /** * @dev Performs BNS name reverse resolution for the supplied reverse name. Called by Viem when doing getEnsName() * @param reverseName The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse * @return The resolved name, the resolved address, the reverse resolver address, and the resolver address. */ function reverse(bytes calldata reverseName) external view returns (string memory, address, address, address) { return reverse(reverseName, batchGatewayURLs); } /** * @dev Performs BNS name reverse resolution for the supplied reverse name. * @param reverseName The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse * @return The resolved name, the resolved address, the reverse resolver address, and the resolver address. */ function reverse(bytes calldata reverseName, string[] memory gateways) public view returns (string memory, address, address, address) { bytes memory encodedCall = abi.encodeCall(INameResolver.name, reverseName.namehash(0)); (bytes memory resolvedReverseData, address reverseResolverAddress) = _resolveSingle(reverseName, encodedCall, gateways, this.reverseCallback.selector, ""); return getForwardDataFromReverse(resolvedReverseData, reverseResolverAddress, gateways); } function getForwardDataFromReverse( bytes memory resolvedReverseData, address reverseResolverAddress, string[] memory gateways ) internal view returns (string memory, address, address, address) { string memory resolvedName = abi.decode(resolvedReverseData, (string)); (bytes memory encodedName, bytes32 namehash) = resolvedName.dnsEncodeName(); bytes memory encodedCall = abi.encodeCall(IAddrResolver.addr, namehash); bytes memory metaData = abi.encode(resolvedName, reverseResolverAddress); (bytes memory resolvedData, address resolverAddress) = this._resolveSingle(encodedName, encodedCall, gateways, this.reverseCallback.selector, metaData); address resolvedAddress = abi.decode(resolvedData, (address)); return (resolvedName, resolvedAddress, reverseResolverAddress, resolverAddress); } function resolveSingleCallback(bytes calldata response, bytes calldata extraData) external view returns (bytes memory, address) { (bytes[] memory results, address resolver,,) = _resolveCallback(response, extraData, this.resolveSingleCallback.selector); return (results[0], resolver); } function resolveCallback(bytes calldata response, bytes calldata extraData) external view returns (bytes[] memory, address) { (bytes[] memory results, address resolver,,) = _resolveCallback(response, extraData, this.resolveCallback.selector); return (results, resolver); } function reverseCallback(bytes calldata response, bytes calldata extraData) external view returns (string memory, address, address, address) { (bytes[] memory resolvedData, address resolverAddress, string[] memory gateways, bytes memory metaData) = _resolveCallback(response, extraData, this.reverseCallback.selector); if (metaData.length > 0) { (string memory resolvedName, address reverseResolverAddress) = abi.decode(metaData, (string, address)); address resolvedAddress = abi.decode(resolvedData[0], (address)); return (resolvedName, resolvedAddress, reverseResolverAddress, resolverAddress); } return getForwardDataFromReverse(resolvedData[0], resolverAddress, gateways); } function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IExtendedResolver).interfaceId || super.supportsInterface(interfaceId); } function _resolveCallback(bytes calldata response, bytes calldata extraData, bytes4 callbackFunction) internal view returns (bytes[] memory, address, string[] memory, bytes memory) { MulticallData memory multicallData; multicallData.callbackFunction = callbackFunction; (bool[] memory failures, bytes[] memory responses) = abi.decode(response, (bool[], bytes[])); OffchainLookupExtraData[] memory extraDatas; (multicallData.isWildcard, multicallData.resolver, multicallData.gateways, multicallData.metaData, extraDatas) = abi.decode(extraData, (bool, address, string[], bytes, OffchainLookupExtraData[])); require(responses.length <= extraDatas.length); multicallData.data = new bytes[](extraDatas.length); multicallData.failures = new bool[](extraDatas.length); uint256 offchainCount = 0; for (uint256 i = 0; i < extraDatas.length; i++) { if (extraDatas[i].callbackFunction == bytes4(0)) { // This call did not require an offchain lookup; use the previous input data. multicallData.data[i] = extraDatas[i].data; } else { if (failures[offchainCount]) { multicallData.failures[i] = true; multicallData.data[i] = responses[offchainCount]; } else { multicallData.data[i] = abi.encodeWithSelector( extraDatas[i].callbackFunction, responses[offchainCount], extraDatas[i].data ); } offchainCount = offchainCount + 1; } } return (_multicall(multicallData), multicallData.resolver, multicallData.gateways, multicallData.metaData); } /** * @dev Makes a call to `target` with `data`. If the call reverts with an `OffchainLookup` error, wraps * the error with the data necessary to continue the request where it left off. * @param target The address to call. * @param data The data to call `target` with. * @return offchain Whether the call reverted with an `OffchainLookup` error. * @return returnData If `target` did not revert, contains the return data from the call to `target`. Otherwise, contains a `OffchainLookupCallData` struct. * @return extraData If `target` did not revert, is empty. Otherwise, contains a `OffchainLookupExtraData` struct. * @return result Whether the call succeeded. */ function callWithOffchainLookupPropagation(address target, bytes memory data) internal view returns (bool offchain, bytes memory returnData, OffchainLookupExtraData memory extraData, bool result) { result = LowLevelCallUtils.functionStaticCall(address(target), data); uint256 size = LowLevelCallUtils.returnDataSize(); if (result) { return (false, LowLevelCallUtils.readReturnData(0, size), extraData, true); } // Failure if (size >= 4) { bytes memory errorId = LowLevelCallUtils.readReturnData(0, 4); // Offchain lookup. Decode the revert message and create our own that nests it. bytes memory revertData = LowLevelCallUtils.readReturnData(4, size - 4); if (bytes4(errorId) == OffchainLookup.selector) { ( address wrappedSender, string[] memory wrappedUrls, bytes memory wrappedCallData, bytes4 wrappedCallbackFunction, bytes memory wrappedExtraData ) = abi.decode(revertData, (address, string[], bytes, bytes4, bytes)); if (wrappedSender == target) { returnData = abi.encode(OffchainLookupCallData(wrappedSender, wrappedUrls, wrappedCallData)); extraData = OffchainLookupExtraData(wrappedCallbackFunction, wrappedExtraData); return (true, returnData, extraData, false); } } else { returnData = bytes.concat(errorId, revertData); return (false, returnData, extraData, false); } } } /** * @dev Finds a resolver by recursively querying the registry, starting at the longest name and progressively * removing labels until it finds a result. * @param name The name to resolve, in DNS-encoded and normalised form. * @return resolver The Resolver responsible for this name. * @return namehash The namehash of the full name. * @return finalOffset The offset of the first label with a resolver. */ function findResolver(bytes calldata name) public view returns (BeraDefaultResolver, bytes32, uint256) { (address resolver, bytes32 namehash, uint256 finalOffset) = findResolver(name, 0); return (BeraDefaultResolver(resolver), namehash, finalOffset); } function findResolver(bytes calldata name, uint256 offset) internal view returns (address, bytes32, uint256) { // Add bounds checking for offset if (offset >= name.length) { return (address(0), bytes32(0), offset); } uint256 labelLength = uint256(uint8(name[offset])); if (labelLength == 0) { return (address(0), bytes32(0), offset); } // Add bounds checking for the full label range if (offset + labelLength + 1 > name.length) { return (address(0), bytes32(0), offset); } uint256 nextLabel = offset + labelLength + 1; bytes32 labelHash; if ( // 0x5b == '[' // 0x5d == ']' labelLength == 66 && name[offset + 1] == 0x5b && name[nextLabel - 1] == 0x5d ) { // Validate the hex string is exactly 64 characters bytes memory hexString = bytes(name[offset + 2:nextLabel - 1]); if (hexString.length != 64) revert InvalidEncryptedLabelLength(); // Validate all characters are valid hex for (uint256 i = 0; i < 64; i++) { bytes1 char = hexString[i]; if ( !(char >= 0x30 && char <= 0x39) // 0-9 && !(char >= 0x41 && char <= 0x46) // A-F && !(char >= 0x61 && char <= 0x66) // a-f ) { revert("Invalid hex character in encrypted label"); } } // Convert validated hex string to bytes32 (labelHash,) = hexString.hexStringToBytes32(0, 64); } else { labelHash = keccak256(name[offset + 1:nextLabel]); } (address parentresolver, bytes32 parentnode, uint256 parentoffset) = findResolver(name, nextLabel); bytes32 node = keccak256(abi.encodePacked(parentnode, labelHash)); address resolver = registry.resolver(node); if (resolver != address(0)) { return (resolver, node, offset); } return (parentresolver, node, parentoffset); } function _hasExtendedResolver(address resolver) internal view returns (bool) { try BeraDefaultResolver(resolver).supportsInterface{gas: 50_000}(type(IExtendedResolver).interfaceId) returns ( bool supported ) { return supported; } catch { return false; } } function _multicall(MulticallData memory multicallData) internal view returns (bytes[] memory results) { uint256 length = multicallData.data.length; if (length != multicallData.failures.length) revert ArrayLengthsMustMatch(); uint256 offchainCount = 0; OffchainLookupCallData[] memory callDatas = new OffchainLookupCallData[](length); OffchainLookupExtraData[] memory extraDatas = new OffchainLookupExtraData[](length); results = new bytes[](length); bool isCallback = multicallData.name.length == 0; bool hasExtendedResolver = _hasExtendedResolver(multicallData.resolver); if (multicallData.isWildcard && !hasExtendedResolver) { revert ResolverWildcardNotSupported(); } for (uint256 i = 0; i < length; i++) { bytes memory item = multicallData.data[i]; bool failure = multicallData.failures[i]; if (failure) { results[i] = item; continue; } if (!isCallback && hasExtendedResolver) { item = abi.encodeCall(IExtendedResolver.resolve, (multicallData.name, item)); } (bool offchain, bytes memory returnData, OffchainLookupExtraData memory extraData, bool success) = callWithOffchainLookupPropagation(multicallData.resolver, item); if (offchain) { callDatas[offchainCount] = abi.decode(returnData, (OffchainLookupCallData)); extraDatas[i] = extraData; offchainCount += 1; continue; } if (success && hasExtendedResolver) { // if this is a successful resolve() call, unwrap the result returnData = abi.decode(returnData, (bytes)); } results[i] = returnData; extraDatas[i].data = multicallData.data[i]; } if (offchainCount == 0) { return results; } // Trim callDatas if offchain data exists assembly { mstore(callDatas, offchainCount) } revert OffchainLookup( address(this), multicallData.gateways, abi.encodeWithSelector(BatchGateway.query.selector, callDatas), multicallData.callbackFunction, abi.encode( multicallData.isWildcard, multicallData.resolver, multicallData.gateways, multicallData.metaData, extraDatas ) ); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @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://consensys.net/diligence/blog/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.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @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 or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * 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. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @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`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) private pure { // 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.23; // Admin Controller import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; // Bera Name Service import {BNS} from "src/registry/interfaces/BNS.sol"; // Interfaces import {IExtendedResolver} from "src/resolver/interfaces/IExtendedResolver.sol"; import {IReverseRegistrar} from "src/registrar/interfaces/IReverseRegistrar.sol"; // Resolver Profiles import {ABIResolver} from "src/resolver/profiles/ABIResolver.sol"; import {AddrResolver} from "src/resolver/profiles/AddrResolver.sol"; import {ContentHashResolver} from "src/resolver/profiles/ContentHashResolver.sol"; // import {DNSResolver} from "src/resolver/profiles/DNSResolver.sol"; import {ExtendedResolver} from "src/resolver/profiles/ExtendedResolver.sol"; import {InterfaceResolver} from "src/resolver/profiles/InterfaceResolver.sol"; import {Multicallable} from "src/resolver/types/Multicallable.sol"; import {NameResolver} from "src/resolver/profiles/NameResolver.sol"; import {PubkeyResolver} from "src/resolver/profiles/PubkeyResolver.sol"; import {TextResolver} from "src/resolver/profiles/TextResolver.sol"; /// @title BeraResolver contract BeraDefaultResolver is // Accessability Controller Multicallable, // Resolvers ABIResolver, AddrResolver, ContentHashResolver, // DNSResolver, InterfaceResolver, NameResolver, PubkeyResolver, TextResolver, ExtendedResolver, // Admin Controller Ownable { /// Errors ----------------------------------------------------------- /// @notice Thown when msg.sender tries to set itself as an operator/delegate. error CantSetSelf(); /// @notice Thown when the registrar controller is not set. error InvalidRegistrarController(); /// @notice Thown when the reverse registrar is not set. error InvalidReverseRegistrar(); /// @notice Thown when the caller is not the owner of the node. error NotOwner(); /// Storage ---------------------------------------------------------- /// @notice The BNS registry. BNS public immutable bns; /// @notice The trusted registrar controller contract. address public registrarController; /// @notice The reverse registrar contract. address public reverseRegistrar; /// @notice A mapping of account operators: can control owner's nodes. mapping(address owner => mapping(address operator => bool isApproved)) private _operatorApprovals; /// @notice A mapping node operators: can control a specific node. mapping(address owner => mapping(bytes32 node => mapping(address delegate => bool isApproved))) private _tokenApprovals; /// Events ----------------------------------------------------------- /// @notice Emitted when an operator is added or removed. /// /// @param owner The address of the owner of names. /// @param operator The address of the approved operator for the `owner`. /// @param approved Whether the `operator` is approved or not. event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /// @notice Emitted when a delegate is approved or an approval is revoked. /// /// @param owner The address of the owner of the name. /// @param node The namehash of the name. /// @param delegate The address of the operator for the specified `node`. /// @param approved Whether the `delegate` is approved for the specified `node`. event Approved(address owner, bytes32 indexed node, address indexed delegate, bool indexed approved); /// @notice Emitted when the owner of this contract updates the Registrar Controller addrress. /// /// @param newRegistrarController The address of the new RegistrarController contract. event RegistrarControllerUpdated(address indexed newRegistrarController); /// @notice Emitted when the owner of this contract updates the Reverse Registrar address. /// /// @param newReverseRegistrar The address of the new ReverseRegistrar contract. event ReverseRegistrarUpdated(address indexed newReverseRegistrar); /// Constructor ------------------------------------------------------ /// @notice L2 Resolver constructor used to establish the necessary contract configuration. /// /// @param bns_ The Registry contract. /// @param registrarController_ The address of the RegistrarController contract. /// @param reverseRegistrar_ The address of the ReverseRegistrar contract. /// @param owner_ The permissioned address initialized as the `owner` in the `Ownable` context. constructor(BNS bns_, address registrarController_, address reverseRegistrar_, address owner_) Ownable(owner_) { // Set state bns = bns_; if (registrarController_ == address(0)) revert InvalidRegistrarController(); if (reverseRegistrar_ == address(0)) revert InvalidReverseRegistrar(); registrarController = registrarController_; reverseRegistrar = reverseRegistrar_; // Initialize reverse registrar IReverseRegistrar(reverseRegistrar_).claim(owner_); } /// Authorisation Functions ----------------------------------------- /// @dev See {IERC1155-setApprovalForAll}. function setApprovalForAll(address operator, bool approved) external { if (msg.sender == operator) revert CantSetSelf(); _operatorApprovals[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } /// @dev See {IERC1155-isApprovedForAll}. function isApprovedForAll(address account, address operator) public view returns (bool) { return _operatorApprovals[account][operator]; } /// @notice Modify the permissions for a specified `delegate` for the specified `node`. /// /// @dev This method only sets the approval status for msg.sender's nodes. /// /// @param node The namehash `node` whose permissions are being updated. /// @param delegate The address of the `delegate` /// @param approved Whether the `delegate` has approval to modify records for `msg.sender`'s `node`. function approve(bytes32 node, address delegate, bool approved) external { if (msg.sender == delegate) revert CantSetSelf(); if (msg.sender != bns.owner(node)) revert NotOwner(); _tokenApprovals[msg.sender][node][delegate] = approved; emit Approved(msg.sender, node, delegate, approved); } /// @notice Check to see if the `delegate` has been approved by the `owner` for the `node`. /// /// @param owner The address of the name owner. /// @param node The namehash `node` whose permissions are being checked. /// @param delegate The address of the `delegate` whose permissions are being checked. /// /// @return `true` if `delegate` is approved to modify `msg.sender`'s `node`, else `false`. function isApprovedFor(address owner, bytes32 node, address delegate) public view returns (bool) { return _tokenApprovals[owner][node][delegate]; } /// @notice Check to see whether `msg.sender` is authorized to modify records for the specified `node`. /// /// @dev Override for `ResolverBase:isAuthorised()`. Used in the context of each inherited resolver "profile". /// Validates that `msg.sender` is one of: /// 1. The stored registrarController (for setting records upon registration) /// 2 The stored reverseRegistrar (for setting reverse records) /// 3. The owner of the node in the Registry /// 4. An approved operator for owner /// 5. An approved delegate for owner of the specified `node` /// /// @param node The namehashed `node` being authorized. /// /// @return `true` if `msg.sender` is authorized to modify records for the specified `node`, else `false`. function isAuthorised(bytes32 node) internal view override returns (bool) { if (msg.sender == registrarController || msg.sender == reverseRegistrar) { return true; } address owner = bns.owner(node); return owner == msg.sender || isApprovedForAll(owner, msg.sender) || isApprovedFor(owner, node, msg.sender); } /// ERC165 Interface Support ----------------------------------------- /// @notice ERC165 compliant signal for interface support. /// @param interfaceID the ERC165 iface id being checked for compliance /// @return bool Whether this contract supports the provided interfaceID function supportsInterface(bytes4 interfaceID) public view override( Multicallable, ABIResolver, AddrResolver, ContentHashResolver, // DNSResolver, InterfaceResolver, NameResolver, PubkeyResolver, TextResolver ) returns (bool) { return (interfaceID == type(IExtendedResolver).interfaceId || super.supportsInterface(interfaceID)); } /// Admin Functions -------------------------------------------------- /// @notice Allows the `owner` to set the registrar controller contract address. /// /// @dev Emits `RegistrarControllerUpdated` after setting the `registrarController` address. /// /// @param registrarController_ The address of the new RegistrarController contract. function setRegistrarController(address registrarController_) external onlyOwner { if (registrarController_ == address(0)) revert InvalidRegistrarController(); registrarController = registrarController_; emit RegistrarControllerUpdated(registrarController_); } /// @notice Allows the `owner` to set the reverse registrar contract address. /// /// @dev Emits `ReverseRegistrarUpdated` after setting the `reverseRegistrar` address. /// /// @param reverseRegistrar_ The address of the new ReverseRegistrar contract. function setReverseRegistrar(address reverseRegistrar_) external onlyOwner { if (reverseRegistrar_ == address(0)) revert InvalidReverseRegistrar(); reverseRegistrar = reverseRegistrar_; emit ReverseRegistrarUpdated(reverseRegistrar_); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; library LowLevelCallUtils { using Address for address; /** * @dev Makes a static call to the specified `target` with `data`. Return data can be fetched with * `returnDataSize` and `readReturnData`. * @param target The address to staticcall. * @param data The data to pass to the call. * @return success True if the call succeeded, or false if it reverts. */ function functionStaticCall(address target, bytes memory data) internal view returns (bool success) { assembly { // Check if the target address has code if iszero(extcodesize(target)) { revert(0, 0) } // Perform the static call success := staticcall(gas(), target, add(data, 32), mload(data), 0, 0) } } /** * @dev Returns the size of the return data of the most recent external call. */ function returnDataSize() internal pure returns (uint256 len) { assembly { len := returndatasize() } } /** * @dev Reads return data from the most recent external call. * @param offset Offset into the return data. * @param length Number of bytes to return. * @return data The copied return data * @dev Reverts if offset + length exceeds returndatasize */ function readReturnData(uint256 offset, uint256 length) internal pure returns (bytes memory data) { data = new bytes(length); assembly { // Validate that offset + length <= returndatasize() if gt(add(offset, length), returndatasize()) { revert(0, 0) } returndatacopy(add(data, 32), offset, length) } } /** * @dev Reverts with the return data from the most recent external call. */ function propagateRevert() internal pure { assembly { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; interface IExtendedResolver { function resolve(bytes memory name, bytes memory data) external view returns (bytes memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface INameResolver { event NameChanged(bytes32 indexed node, string name); /** * Returns the name associated with an BNS node, for reverse records. * Defined in EIP181. * @param node The BNS node to query. * @return The associated name. */ function name(bytes32 node) external view returns (string memory); } abstract contract AbstractNameResolver { function setName(bytes32 node, string memory name) public virtual; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; /** * Interface for the legacy (ETH-only) addr function. */ interface IAddrResolver { event AddrChanged(bytes32 indexed node, address a); /** * Returns the address associated with an BNS node. * @param node The BNS node to query. * @return The associated address. */ function addr(bytes32 node) external view returns (address payable); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface BNS { // Logged when the owner of a node assigns a new owner to a subnode. event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner); // Logged when the owner of a node transfers ownership to a new account. event Transfer(bytes32 indexed node, address owner); // Logged when the resolver for a node changes. event NewResolver(bytes32 indexed node, address resolver); // Logged when the TTL of a node changes event NewTTL(bytes32 indexed node, uint64 ttl); // Logged when an operator is added or removed. event ApprovalForAll(address indexed owner, address indexed operator, bool approved); function setRecord(bytes32 node, address owner, address resolver, uint64 ttl) external; function setSubnodeRecord(bytes32 node, bytes32 label, address owner, address resolver, uint64 ttl) external; function setSubnodeOwner(bytes32 node, bytes32 label, address owner) external returns (bytes32); function setResolver(bytes32 node, address resolver) external; function setOwner(bytes32 node, address owner) external; function setTTL(bytes32 node, uint64 ttl) external; function setApprovalForAll(address operator, bool approved) external; function owner(bytes32 node) external view returns (address); function resolver(bytes32 node) external view returns (address); function ttl(bytes32 node) external view returns (uint64); function recordExists(bytes32 node) external view returns (bool); function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {BytesUtils} from "src/resolver/libraries/BytesUtils.sol"; library NameEncoder { using BytesUtils for bytes; function dnsEncodeName(string memory name) internal pure returns (bytes memory dnsName, bytes32 node) { uint8 labelLength = 0; bytes memory bytesName = bytes(name); uint256 length = bytesName.length; dnsName = new bytes(length + 2); node = 0; if (length == 0) { dnsName[0] = 0; return (dnsName, node); } // use unchecked to save gas since we check for an underflow // and we check for the length before the loop unchecked { for (uint256 i = length - 1; i >= 0; i--) { if (bytesName[i] == ".") { dnsName[i + 1] = bytes1(labelLength); node = keccak256(abi.encodePacked(node, bytesName.keccak(i + 1, labelLength))); labelLength = 0; } else { labelLength += 1; dnsName[i + 1] = bytesName[i]; } if (i == 0) { break; } } } node = keccak256(abi.encodePacked(node, bytesName.keccak(0, labelLength))); dnsName[0] = bytes1(labelLength); return (dnsName, node); } }
//SPDX-License-Identifier: MIT pragma solidity ~0.8.17; library BytesUtils { /* * @dev Returns the keccak-256 hash of a byte range. * @param self The byte string to hash. * @param offset The position to start hashing at. * @param len The number of bytes to hash. * @return The hash of the byte range. */ function keccak(bytes memory self, uint256 offset, uint256 len) internal pure returns (bytes32 ret) { require(offset + len <= self.length); assembly { ret := keccak256(add(add(self, 32), offset), len) } } /** * @dev Returns the ENS namehash of a DNS-encoded name. * @param self The DNS-encoded name to hash. * @param offset The offset at which to start hashing. * @return The namehash of the name. */ function namehash(bytes memory self, uint256 offset) internal pure returns (bytes32) { // First count the number of labels uint256 labelCount = 0; uint256 countOffset = offset; while (countOffset < self.length) { bytes32 labelhash; uint256 newOffset; (labelhash, newOffset) = readLabel(self, countOffset); if (labelhash == bytes32(0)) { break; } labelCount++; countOffset = newOffset; } // Then find all label hashes bytes32[] memory labels = new bytes32[](labelCount); uint256 currentOffset = offset; uint256 index = 0; while (currentOffset < self.length) { bytes32 labelhash; uint256 newOffset; (labelhash, newOffset) = readLabel(self, currentOffset); if (labelhash == bytes32(0)) { require(currentOffset == self.length - 1, "namehash: Junk at end of name"); break; } labels[index] = labelhash; index++; currentOffset = newOffset; } // Finally compute namehash from right to left bytes32 node = bytes32(0); while (labelCount > 0) { labelCount--; node = keccak256(abi.encodePacked(node, labels[labelCount])); } return node; } /** * @dev Returns the keccak-256 hash of a DNS-encoded label, and the offset to the start of the next label. * @param self The byte string to read a label from. * @param idx The index to read a label at. * @return labelhash The hash of the label at the specified index, or 0 if it is the last label. * @return newIdx The index of the start of the next label. */ function readLabel(bytes memory self, uint256 idx) internal pure returns (bytes32 labelhash, uint256 newIdx) { require(idx < self.length, "readLabel: Index out of bounds"); uint256 len = uint256(uint8(self[idx])); if (len > 0) { labelhash = keccak(self, idx + 1, len); } else { labelhash = bytes32(0); } newIdx = idx + len + 1; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; library HexUtils { /** * @dev Attempts to parse bytes32 from a hex string * @param str The string to parse * @param idx The offset to start parsing at * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string. */ function hexStringToBytes32(bytes memory str, uint256 idx, uint256 lastIdx) internal pure returns (bytes32 r, bool valid) { if ((lastIdx - idx) % 2 != 0) return (r, false); if (idx >= lastIdx || lastIdx > str.length) return (bytes32(0), false); valid = true; assembly { // check that the index to read to is not past the end of the string if gt(lastIdx, mload(str)) { revert(0, 0) } function getHex(c) -> ascii { // chars 48-57: 0-9 if and(gt(c, 47), lt(c, 58)) { ascii := sub(c, 48) leave } // chars 65-70: A-F if and(gt(c, 64), lt(c, 71)) { ascii := add(sub(c, 65), 10) leave } // chars 97-102: a-f if and(gt(c, 96), lt(c, 103)) { ascii := add(sub(c, 97), 10) leave } // invalid char ascii := 0xff } let ptr := add(str, 32) for { let i := idx } lt(i, lastIdx) { i := add(i, 2) } { let byte1 := getHex(byte(0, mload(add(ptr, i)))) let byte2 := getHex(byte(0, mload(add(ptr, add(i, 1))))) // if either byte is invalid, set invalid and break loop if or(eq(byte1, 0xff), eq(byte2, 0xff)) { valid := false break } let combined := or(shl(4, byte1), byte2) r := or(shl(8, r), combined) } } } /** * @dev Attempts to parse an address from a hex string * @param str The string to parse * @param idx The offset to start parsing at * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string. */ function hexToAddress(bytes memory str, uint256 idx, uint256 lastIdx) internal pure returns (address, bool) { if (lastIdx - idx != 40) return (address(0x0), false); (bytes32 r, bool valid) = hexStringToBytes32(str, idx, lastIdx); return (address(uint160(uint256(r))), valid); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.23; interface IReverseRegistrar { /// @notice Thrown when the registry is invalid. error InvalidRegistry(); function claim(address claimant) external returns (bytes32); function setNameForAddr(address addr, address owner, address resolver, string memory name) external returns (bytes32); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import {ResolverBase} from "src/resolver/types/ResolverBase.sol"; import {IABIResolver} from "src/resolver/interfaces/IABIResolver.sol"; abstract contract ABIResolver is IABIResolver, ResolverBase { mapping(uint64 => mapping(bytes32 => mapping(uint256 => bytes))) versionable_abis; /** * Sets the ABI associated with an BNS node. * Nodes may have one ABI of each content type. To remove an ABI, set it to * the empty string. * @param node The node to update. * @param contentType The content type of the ABI * @param data The ABI data. */ function setABI(bytes32 node, uint256 contentType, bytes calldata data) external virtual authorised(node) { // Content types must be powers of 2 require(((contentType - 1) & contentType) == 0); versionable_abis[recordVersions[node]][node][contentType] = data; emit ABIChanged(node, contentType); } /** * Returns the ABI associated with an BNS node. * Defined in EIP205. * @param node The BNS node to query * @param contentTypes A bitwise OR of the ABI formats accepted by the caller. * @return contentType The content type of the return value * @return data The ABI data */ function ABI(bytes32 node, uint256 contentTypes) external view virtual override returns (uint256, bytes memory) { mapping(uint256 => bytes) storage abiset = versionable_abis[recordVersions[node]][node]; for (uint256 contentType = 1; contentType <= contentTypes; contentType <<= 1) { if ((contentType & contentTypes) != 0 && abiset[contentType].length > 0) { return (contentType, abiset[contentType]); } } return (0, bytes("")); } function supportsInterface(bytes4 interfaceID) public view virtual override returns (bool) { return interfaceID == type(IABIResolver).interfaceId || super.supportsInterface(interfaceID); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import {ResolverBase} from "src/resolver/types/ResolverBase.sol"; import "src/resolver/interfaces/IAddrResolver.sol"; import "src/resolver/interfaces/IAddressResolver.sol"; abstract contract AddrResolver is IAddrResolver, IAddressResolver, ResolverBase { uint256 private constant COIN_TYPE_ETH = 60; mapping(uint64 => mapping(bytes32 => mapping(uint256 => bytes))) versionable_addresses; /** * Sets the address associated with an BNS node. * May only be called by the owner of that node in the BNS registry. * @param node The node to update. * @param a The address to set. */ function setAddr(bytes32 node, address a) external virtual authorised(node) { setAddr(node, COIN_TYPE_ETH, addressToBytes(a)); } /** * Returns the address associated with an BNS node. * @param node The BNS node to query. * @return The associated address. */ function addr(bytes32 node) public view virtual override returns (address payable) { bytes memory a = addr(node, COIN_TYPE_ETH); if (a.length == 0) { return payable(0); } return bytesToAddress(a); } function setAddr(bytes32 node, uint256 coinType, bytes memory a) public virtual authorised(node) { emit AddressChanged(node, coinType, a); if (coinType == COIN_TYPE_ETH) { emit AddrChanged(node, bytesToAddress(a)); } versionable_addresses[recordVersions[node]][node][coinType] = a; } function addr(bytes32 node, uint256 coinType) public view virtual override returns (bytes memory) { return versionable_addresses[recordVersions[node]][node][coinType]; } function supportsInterface(bytes4 interfaceID) public view virtual override returns (bool) { return interfaceID == type(IAddrResolver).interfaceId || interfaceID == type(IAddressResolver).interfaceId || super.supportsInterface(interfaceID); } function bytesToAddress(bytes memory b) internal pure returns (address payable a) { require(b.length == 20); assembly { a := div(mload(add(b, 32)), exp(256, 12)) } } function addressToBytes(address a) internal pure returns (bytes memory b) { b = new bytes(20); assembly { mstore(add(b, 32), mul(a, exp(256, 12))) } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import {ResolverBase} from "src/resolver/types/ResolverBase.sol"; import "src/resolver/interfaces/IContentHashResolver.sol"; abstract contract ContentHashResolver is IContentHashResolver, ResolverBase { mapping(uint64 => mapping(bytes32 => bytes)) versionable_hashes; /** * Sets the contenthash associated with an BNS node. * May only be called by the owner of that node in the BNS registry. * @param node The node to update. * @param hash The contenthash to set */ function setContenthash(bytes32 node, bytes calldata hash) external virtual authorised(node) { versionable_hashes[recordVersions[node]][node] = hash; emit ContenthashChanged(node, hash); } /** * Returns the contenthash associated with an BNS node. * @param node The BNS node to query. * @return The associated contenthash. */ function contenthash(bytes32 node) external view virtual override returns (bytes memory) { return versionable_hashes[recordVersions[node]][node]; } function supportsInterface(bytes4 interfaceID) public view virtual override returns (bool) { return interfaceID == type(IContentHashResolver).interfaceId || super.supportsInterface(interfaceID); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; contract ExtendedResolver { function resolve(bytes memory, /* name */ bytes memory data) external view returns (bytes memory) { (bool success, bytes memory result) = address(this).staticcall(data); if (success) { return result; } else { // Revert with the reason provided by the call assembly { revert(add(result, 0x20), mload(result)) } } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import {ResolverBase} from "src/resolver/types/ResolverBase.sol"; import {AddrResolver} from "src/resolver/profiles/AddrResolver.sol"; import {IInterfaceResolver} from "src/resolver/interfaces/IInterfaceResolver.sol"; abstract contract InterfaceResolver is IInterfaceResolver, AddrResolver { mapping(uint64 => mapping(bytes32 => mapping(bytes4 => address))) versionable_interfaces; /** * Sets an interface associated with a name. * Setting the address to 0 restores the default behaviour of querying the contract at `addr()` for interface support. * @param node The node to update. * @param interfaceID The EIP 165 interface ID. * @param implementer The address of a contract that implements this interface for this node. */ function setInterface(bytes32 node, bytes4 interfaceID, address implementer) external virtual authorised(node) { versionable_interfaces[recordVersions[node]][node][interfaceID] = implementer; emit InterfaceChanged(node, interfaceID, implementer); } /** * Returns the address of a contract that implements the specified interface for this name. * If an implementer has not been set for this interfaceID and name, the resolver will query * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that * contract implements EIP165 and returns `true` for the specified interfaceID, its address * will be returned. * @param node The BNS node to query. * @param interfaceID The EIP 165 interface ID to check for. * @return The address that implements this interface, or 0 if the interface is unsupported. */ function interfaceImplementer(bytes32 node, bytes4 interfaceID) external view virtual override returns (address) { address implementer = versionable_interfaces[recordVersions[node]][node][interfaceID]; if (implementer != address(0)) { return implementer; } address a = addr(node); if (a == address(0)) { return address(0); } (bool success, bytes memory returnData) = a.staticcall(abi.encodeWithSignature("supportsInterface(bytes4)", type(IERC165).interfaceId)); if (!success || returnData.length < 32 || returnData[31] == 0) { // EIP 165 not supported by target return address(0); } (success, returnData) = a.staticcall(abi.encodeWithSignature("supportsInterface(bytes4)", interfaceID)); if (!success || returnData.length < 32 || returnData[31] == 0) { // Specified interface not supported by target return address(0); } return a; } function supportsInterface(bytes4 interfaceID) public view virtual override returns (bool) { return interfaceID == type(IInterfaceResolver).interfaceId || super.supportsInterface(interfaceID); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; // Internal imports import "src/resolver/interfaces/IMulticallable.sol"; abstract contract Multicallable is IMulticallable, ERC165 { function _multicall(bytes32 nodehash, bytes[] calldata data) internal returns (bytes[] memory results) { results = new bytes[](data.length); for (uint256 i = 0; i < data.length; i++) { if (nodehash != bytes32(0)) { bytes32 txNamehash = bytes32(data[i][4:36]); require(txNamehash == nodehash, "multicall: All records must have a matching namehash"); } (bool success, bytes memory result) = address(this).delegatecall(data[i]); if (!success) { if (result.length > 0) { assembly { let revertDataSize := mload(result) revert(add(result, 32), revertDataSize) } } else { revert("Multicall delegatecall failed without a reason"); } } results[i] = result; } return results; } // This function provides an extra security check when called // from priviledged contracts (such as EthRegistrarController) // that can set records on behalf of the node owners function multicallWithNodeCheck(bytes32 nodehash, bytes[] calldata data) external returns (bytes[] memory results) { return _multicall(nodehash, data); } function multicall(bytes[] calldata data) public override returns (bytes[] memory results) { return _multicall(bytes32(0), data); } function supportsInterface(bytes4 interfaceID) public view virtual override returns (bool) { return interfaceID == type(IMulticallable).interfaceId || super.supportsInterface(interfaceID); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import {ResolverBase} from "src/resolver/types/ResolverBase.sol"; import "src/resolver/interfaces/INameResolver.sol"; abstract contract NameResolver is INameResolver, ResolverBase { mapping(uint64 => mapping(bytes32 => string)) versionable_names; /** * Sets the name associated with an BNS node, for reverse records. * May only be called by the owner of that node in the BNS registry. * @param node The node to update. */ function setName(bytes32 node, string calldata newName) external virtual authorised(node) { versionable_names[recordVersions[node]][node] = newName; emit NameChanged(node, newName); } /** * Returns the name associated with an BNS node, for reverse records. * Defined in EIP181. * @param node The BNS node to query. * @return The associated name. */ function name(bytes32 node) external view virtual override returns (string memory) { return versionable_names[recordVersions[node]][node]; } function supportsInterface(bytes4 interfaceID) public view virtual override returns (bool) { return interfaceID == type(INameResolver).interfaceId || super.supportsInterface(interfaceID); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import {ResolverBase} from "src/resolver/types/ResolverBase.sol"; import "src/resolver/interfaces/IPubkeyResolver.sol"; abstract contract PubkeyResolver is IPubkeyResolver, ResolverBase { struct PublicKey { bytes32 x; bytes32 y; } mapping(uint64 => mapping(bytes32 => PublicKey)) versionable_pubkeys; /** * Sets the SECP256k1 public key associated with an BNS node. * @param node The BNS node to query * @param x the X coordinate of the curve point for the public key. * @param y the Y coordinate of the curve point for the public key. */ function setPubkey(bytes32 node, bytes32 x, bytes32 y) external virtual authorised(node) { versionable_pubkeys[recordVersions[node]][node] = PublicKey(x, y); emit PubkeyChanged(node, x, y); } /** * Returns the SECP256k1 public key associated with an BNS node. * Defined in EIP 619. * @param node The BNS node to query * @return x The X coordinate of the curve point for the public key. * @return y The Y coordinate of the curve point for the public key. */ function pubkey(bytes32 node) external view virtual override returns (bytes32 x, bytes32 y) { uint64 currentRecordVersion = recordVersions[node]; return (versionable_pubkeys[currentRecordVersion][node].x, versionable_pubkeys[currentRecordVersion][node].y); } function supportsInterface(bytes4 interfaceID) public view virtual override returns (bool) { return interfaceID == type(IPubkeyResolver).interfaceId || super.supportsInterface(interfaceID); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import {ResolverBase} from "src/resolver/types/ResolverBase.sol"; import "src/resolver/interfaces/ITextResolver.sol"; abstract contract TextResolver is ITextResolver, ResolverBase { mapping(uint64 => mapping(bytes32 => mapping(string => string))) versionable_texts; /** * Sets the text data associated with an BNS node and key. * May only be called by the owner of that node in the BNS registry. * @param node The node to update. * @param key The key to set. * @param value The text data value to set. */ function setText(bytes32 node, string calldata key, string calldata value) external virtual authorised(node) { versionable_texts[recordVersions[node]][node][key] = value; emit TextChanged(node, key, key, value); } /** * Returns the text data associated with an BNS node and key. * @param node The BNS node to query. * @param key The text data key to query. * @return The associated text data. */ function text(bytes32 node, string calldata key) external view virtual override returns (string memory) { return versionable_texts[recordVersions[node]][node][key]; } function supportsInterface(bytes4 interfaceID) public view virtual override returns (bool) { return interfaceID == type(ITextResolver).interfaceId || super.supportsInterface(interfaceID); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import {IVersionableResolver} from "src/resolver/interfaces/IVersionableResolver.sol"; abstract contract ResolverBase is ERC165, IVersionableResolver { mapping(bytes32 => uint64) public recordVersions; function isAuthorised(bytes32 node) internal view virtual returns (bool); modifier authorised(bytes32 node) { require(isAuthorised(node), "Unauthorized"); _; } /** * Increments the record version associated with an BNS node. * May only be called by the owner of that node in the BNS registry. * @param node The node to update. */ function clearRecords(bytes32 node) public virtual authorised(node) { recordVersions[node]++; emit VersionChanged(node, recordVersions[node]); } function supportsInterface(bytes4 interfaceID) public view virtual override returns (bool) { return interfaceID == type(IVersionableResolver).interfaceId || super.supportsInterface(interfaceID); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface IABIResolver { event ABIChanged(bytes32 indexed node, uint256 indexed contentType); /** * Returns the ABI associated with an ENS node. * Defined in EIP205. * @param node The ENS node to query * @param contentTypes A bitwise OR of the ABI formats accepted by the caller. * @return contentType The content type of the return value * @return data The ABI data */ function ABI(bytes32 node, uint256 contentTypes) external view returns (uint256, bytes memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; /** * Interface for the new (multicoin) addr function. */ interface IAddressResolver { event AddressChanged(bytes32 indexed node, uint256 coinType, bytes newAddress); function addr(bytes32 node, uint256 coinType) external view returns (bytes memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface IContentHashResolver { event ContenthashChanged(bytes32 indexed node, bytes hash); /** * Returns the contenthash associated with an BNS node. * @param node The BNS node to query. * @return The associated contenthash. */ function contenthash(bytes32 node) external view returns (bytes memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface IInterfaceResolver { event InterfaceChanged(bytes32 indexed node, bytes4 indexed interfaceID, address implementer); /** * Returns the address of a contract that implements the specified interface for this name. * If an implementer has not been set for this interfaceID and name, the resolver will query * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that * contract implements EIP165 and returns `true` for the specified interfaceID, its address * will be returned. * @param node The BNS node to query. * @param interfaceID The EIP 165 interface ID to check for. * @return The address that implements this interface, or 0 if the interface is unsupported. */ function interfaceImplementer(bytes32 node, bytes4 interfaceID) external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; interface IMulticallable { function multicall(bytes[] calldata data) external returns (bytes[] memory results); function multicallWithNodeCheck(bytes32, bytes[] calldata data) external returns (bytes[] memory results); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface IPubkeyResolver { event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y); /** * Returns the SECP256k1 public key associated with an ENS node. * Defined in EIP 619. * @param node The ENS node to query * @return x The X coordinate of the curve point for the public key. * @return y The Y coordinate of the curve point for the public key. */ function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface ITextResolver { event TextChanged(bytes32 indexed node, string indexed indexedKey, string key, string value); /** * Returns the text data associated with an BNS node and key. * @param node The BNS node to query. * @param key The text data key to query. * @return The associated text data. */ function text(bytes32 node, string calldata key) external view returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface IVersionableResolver { event VersionChanged(bytes32 indexed node, uint64 newVersion); function recordVersions(bytes32 node) external view returns (uint64); }
{ "remappings": [ "@pythnetwork/pyth-sdk-solidity/=node_modules/@pythnetwork/pyth-sdk-solidity/", "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "forge-std/=lib/forge-std/src/", "ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "openzeppelin-contracts/=lib/openzeppelin-contracts/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "evmVersion": "cancun", "viaIR": false, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_registry","type":"address"},{"internalType":"string[]","name":"_urls","type":"string[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ArrayLengthsMustMatch","type":"error"},{"inputs":[],"name":"InvalidEncryptedLabelLength","type":"error"},{"inputs":[],"name":"InvalidRegistry","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string[]","name":"urls","type":"string[]"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"bytes4","name":"callbackFunction","type":"bytes4"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"OffchainLookup","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ResolverNotFound","type":"error"},{"inputs":[],"name":"ResolverWildcardNotSupported","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"string[]","name":"gateways","type":"string[]"},{"internalType":"bytes4","name":"callbackFunction","type":"bytes4"},{"internalType":"bytes","name":"metaData","type":"bytes"}],"name":"_resolveSingle","outputs":[{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"batchGatewayURLs","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"}],"name":"findResolver","outputs":[{"internalType":"contract BeraDefaultResolver","name":"","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"registry","outputs":[{"internalType":"contract BNS","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"string[]","name":"gateways","type":"string[]"}],"name":"resolve","outputs":[{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"},{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"resolve","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"},{"internalType":"bytes[]","name":"data","type":"bytes[]"},{"internalType":"string[]","name":"gateways","type":"string[]"}],"name":"resolve","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"resolve","outputs":[{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"response","type":"bytes"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"resolveCallback","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"response","type":"bytes"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"resolveSingleCallback","outputs":[{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"reverseName","type":"bytes"},{"internalType":"string[]","name":"gateways","type":"string[]"}],"name":"reverse","outputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"reverseName","type":"bytes"}],"name":"reverse","outputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"response","type":"bytes"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"reverseCallback","outputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string[]","name":"_urls","type":"string[]"}],"name":"setGatewayURLs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a060405234801561000f575f5ffd5b5060405161385f38038061385f83398101604081905261002e916101fd565b338061005357604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b61005c816100ac565b506001600160a01b038216610084576040516311a1e69760e01b815260040160405180910390fd5b6001600160a01b03821660805280516100a49060019060208401906100fb565b505050610480565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b828054828255905f5260205f2090810192821561013f579160200282015b8281111561013f578251829061012f90826103c6565b5091602001919060010190610119565b5061014b92915061014f565b5090565b8082111561014b575f610162828261016b565b5060010161014f565b50805461017790610342565b5f825580601f10610186575050565b601f0160209004905f5260205f20908101906101a291906101a5565b50565b5b8082111561014b575f81556001016101a6565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b03811182821017156101f5576101f56101b9565b604052919050565b5f5f6040838503121561020e575f5ffd5b82516001600160a01b0381168114610224575f5ffd5b60208401519092506001600160401b0381111561023f575f5ffd5b8301601f8101851361024f575f5ffd5b80516001600160401b03811115610268576102686101b9565b8060051b610278602082016101cd565b91825260208184018101929081019088841115610293575f5ffd5b6020850192505b838310156103335782516001600160401b038111156102b7575f5ffd5b8501603f81018a136102c7575f5ffd5b60208101516001600160401b038111156102e3576102e36101b9565b6102f6601f8201601f19166020016101cd565b8181526040838301018c101561030a575f5ffd5b8160408401602083015e5f6020838301015280855250505060208201915060208301925061029a565b80955050505050509250929050565b600181811c9082168061035657607f821691505b60208210810361037457634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156103c157805f5260205f20601f840160051c8101602085101561039f5750805b601f840160051c820191505b818110156103be575f81556001016103ab565b50505b505050565b81516001600160401b038111156103df576103df6101b9565b6103f3816103ed8454610342565b8461037a565b6020601f821160018114610425575f831561040e5750848201515b5f19600385901b1c1916600184901b1784556103be565b5f84815260208120601f198516915b828110156104545787850151825560209485019460019092019101610434565b508482101561047157868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b6080516133c061049f5f395f81816101c401526113e601526133c05ff3fe608060405234801561000f575f5ffd5b5060043610610111575f3560e01c80638e5ea8df1161009e578063b241d0d31161006e578063b241d0d31461029f578063b4a85801146102b2578063e0a85412146102c5578063ec11c823146102d8578063f2fde38b146102eb575f5ffd5b80638e5ea8df146102215780639061b92314610234578063a1cbcbaf14610247578063a6b164191461027f575f5ffd5b8063715018a6116100e4578063715018a6146101a257806376286c00146101ac5780637b103999146101bf5780638da5cb5b146101fe5780638e25a0f31461020e575f5ffd5b806301ffc9a7146101155780630667cfea1461013d578063206c74c91461015e5780636dc4fb731461017f575b5f5ffd5b61012861012336600461219b565b6102fe565b60405190151581526020015b60405180910390f35b61015061014b3660046123cb565b610334565b60405161013492919061248a565b61017161016c366004612531565b610367565b604051610134929190612598565b61019261018d36600461260f565b61044f565b6040516101349493929190612679565b6101aa610516565b005b6101716101ba3660046126b4565b610529565b6101e67f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610134565b5f546001600160a01b03166101e6565b61015061021c366004612712565b61054f565b6101aa61022f3660046127dd565b6105e0565b610150610242366004612816565b6105ff565b61025a610255366004612873565b6106f1565b604080516001600160a01b039094168452602084019290925290820152606001610134565b61029261028d3660046128b1565b610713565b60405161013491906128c8565b6101926102ad3660046128da565b6107b9565b6101716102c036600461260f565b61088c565b6101506102d336600461260f565b6108b6565b6101926102e6366004612873565b6108ff565b6101aa6102f936600461294b565b6109ed565b5f6001600160e01b03198216639061b92360e01b148061032e57506301ffc9a760e01b6001600160e01b03198316145b92915050565b60605f61035a8686868663e0a8541260e01b60405180602001604052805f81525061054f565b9150915094509492505050565b60605f6104428585856001805480602002602001604051908101604052809291908181526020015f905b82821015610439578382905f5260205f200180546103ae90612966565b80601f01602080910402602001604051908101604052809291908181526020018280546103da90612966565b80156104255780601f106103fc57610100808354040283529160200191610425565b820191905f5260205f20905b81548152906001019060200180831161040857829003601f168201915b505050505081526020019060010190610391565b50505050610529565b915091505b935093915050565b60605f80808080808061046c8c8c8c8c636dc4fb7360e01b610a2f565b93509350935093505f815111156104da575f5f8280602001905181019061049391906129ed565b915091505f865f815181106104aa576104aa612a3b565b60200260200101518060200190518101906104c59190612a4f565b929a50919850965092945061050b9350505050565b6104fe845f815181106104ef576104ef612a3b565b60200260200101518484610d9f565b9750975097509750505050505b945094509450949050565b61051e610edc565b6105275f610f08565b565b60605f61035a8686868663b4a8580160e01b60405180602001604052805f815250610f57565b6040805160018082528183019092526060915f918291816020015b606081526020019060019003908161056a57905050905086815f8151811061059457610594612a3b565b60200260200101819052505f5f6105af8b8b858b8b8b610f57565b91509150815f815181106105c5576105c5612a3b565b60200260200101518194509450505050965096945050505050565b6105e8610edc565b80516105fb9060019060208401906120d0565b5050565b60605f6104428585856001805480602002602001604051908101604052809291908181526020015f905b828210156106d1578382905f5260205f2001805461064690612966565b80601f016020809104026020016040519081016040528092919081815260200182805461067290612966565b80156106bd5780601f10610694576101008083540402835291602001916106bd565b820191905f5260205f20905b8154815290600101906020018083116106a057829003601f168201915b505050505081526020019060010190610629565b5050505063e0a8541260e01b60405180602001604052805f81525061054f565b5f5f5f5f5f5f61070288885f61107a565b919750955093505050509250925092565b60018181548110610722575f80fd5b905f5260205f20015f91509050805461073a90612966565b80601f016020809104026020016040519081016040528092919081815260200182805461076690612966565b80156107b15780601f10610788576101008083540402835291602001916107b1565b820191905f5260205f20905b81548152906001019060200180831161079457829003601f168201915b505050505081565b60605f5f5f5f6108015f89898080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250929392505061148b9050565b60405160240161081391815260200190565b60408051601f19818403018152918152602080830180516001600160e01b031663691f343160e01b17905281519081019091525f8082529192508190610869908b908b9086908c90636dc4fb7360e01b9061054f565b9150915061087882828a610d9f565b965096509650965050505093509350935093565b60605f80806108a58888888863b4a8580160e01b610a2f565b50919a909950975050505050505050565b60605f80806108cf888888886370542a0960e11b610a2f565b505091509150815f815181106108e7576108e7612a3b565b60200260200101518193509350505094509492505050565b60605f5f5f6109db86866001805480602002602001604051908101604052809291908181526020015f905b828210156109d2578382905f5260205f2001805461094790612966565b80601f016020809104026020016040519081016040528092919081815260200182805461097390612966565b80156109be5780601f10610995576101008083540402835291602001916109be565b820191905f5260205f20905b8154815290600101906020018083116109a157829003601f168201915b50505050508152602001906001019061092a565b505050506107b9565b93509350935093505b92959194509250565b6109f5610edc565b6001600160a01b038116610a2357604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b610a2c81610f08565b50565b60605f606080610a8f6040518061010001604052806060815260200160608152602001606081526020015f6001600160e01b03191681526020015f151581526020015f6001600160a01b0316815260200160608152602001606081525090565b6001600160e01b0319861660608201525f80610aad8b8d018d612a77565b90925090506060610ac08a8c018c612b30565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610af9575f5ffd5b80516001600160401b03811115610b1257610b12612201565b604051908082528060200260200182016040528015610b4557816020015b6060815260200190600190039081610b305790505b50602085015280516001600160401b03811115610b6457610b64612201565b604051908082528060200260200182016040528015610b8d578160200160208202803683370190505b5060e08501525f805b8251811015610d6d5782515f90849083908110610bb557610bb5612a3b565b60200260200101515f01516001600160e01b03191603610c1357828181518110610be157610be1612a3b565b60200260200101516020015186602001518281518110610c0357610c03612a3b565b6020026020010181905250610d65565b848281518110610c2557610c25612a3b565b602002602001015115610c9c5760018660e001518281518110610c4a57610c4a612a3b565b602002602001019015159081151581525050838281518110610c6e57610c6e612a3b565b602002602001015186602001518281518110610c8c57610c8c612a3b565b6020026020010181905250610d57565b828181518110610cae57610cae612a3b565b60200260200101515f0151848381518110610ccb57610ccb612a3b565b6020026020010151848381518110610ce557610ce5612a3b565b602002602001015160200151604051602401610d02929190612caa565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610d4b57610d4b612a3b565b60200260200101819052505b610d62826001612ceb565b91505b600101610b96565b50610d778561163e565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b60605f5f5f5f87806020019051810190610db99190612cfe565b90505f5f610dc683611a7d565b915091505f81604051602401610dde91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b0316631d9dabef60e11b17905290519192505f91610e1e9187918e910161248a565b60405160208183030381529060405290505f5f306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b8152600401610e6c959493929190612d89565b5f60405180830381865afa158015610e86573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610ead91908101906129ed565b915091505f82806020019051810190610ec69190612a4f565b979f979e50909b50959950505050505050505050565b5f546001600160a01b031633146105275760405163118cdaa760e01b8152336004820152602401610a1a565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60605f5f5f610f668a8a6106f1565b919450849350909150506001600160a01b038216610f9757604051637199966d60e01b815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b81528315159261106a929182918f908f90819085018382808284375f92019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e0909101906001600160401b0381111561103957611039612201565b604051908082528060200260200182016040528015611062578160200160208202803683370190505b50905261163e565b9450505050965096945050505050565b5f808084841061109157505f915081905082611482565b5f8686868181106110a4576110a4612a3b565b919091013560f81c9150505f8190036110c657505f9250829150839050611482565b856110d18287612ceb565b6110dc906001612ceb565b11156110f157505f9250829150839050611482565b5f6110fc8287612ceb565b611107906001612ceb565b90505f82604214801561114c57508888611122896001612ceb565b81811061113157611131612a3b565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b801561118a57508888611160600185612de5565b81811061116f5761116f612a3b565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b1561134b575f898961119d8a6002612ceb565b906111a9600187612de5565b926111b693929190612df8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250508251929350506040909114905061121157604051639bf46a6360e01b815260040160405180910390fd5b5f5b6040811015611334575f82828151811061122f5761122f612a3b565b01602001516001600160f81b0319169050600360fc1b81108015906112625750603960f81b6001600160f81b0319821611155b1580156112985750604160f81b6001600160f81b03198216108015906112965750602360f91b6001600160f81b0319821611155b155b80156112cd5750606160f81b6001600160f81b03198216108015906112cb5750603360f91b6001600160f81b0319821611155b155b1561132b5760405162461bcd60e51b815260206004820152602860248201527f496e76616c6964206865782063686172616374657220696e20656e63727970746044820152671959081b1858995b60c21b6064820152608401610a1a565b50600101611213565b50611341815f6040611c65565b50915061137d9050565b8888611358896001612ceb565b61136492859290612df8565b604051611372929190612e1f565b604051809103902090505b5f5f5f61138b8c8c8761107a565b9250925092505f82856040516020016113ae929190918252602082015260400190565b60408051601f19818403018152908290528051602090910120630178b8bf60e01b82526004820181905291505f906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa15801561142b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061144f9190612a4f565b90506001600160a01b03811615611473579950975089965061148295505050505050565b50929850919650909450505050505b93509350939050565b5f80825b84518110156114cc575f5f6114a48784611d71565b9092509050816114b55750506114cc565b836114bf81612e2e565b945050809250505061148f565b5f826001600160401b038111156114e5576114e5612201565b60405190808252806020026020018201604052801561150e578160200160208202803683370190505b509050845f5b87518210156115cb575f5f6115298a85611d71565b9092509050816115965760018a516115419190612de5565b841461158f5760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d650000006044820152606401610a1a565b50506115cb565b818584815181106115a9576115a9612a3b565b6020908102919091010152826115be81612e2e565b9350508093505050611514565b5f5b851561163257856115dd81612e46565b965050808487815181106115f3576115f3612a3b565b6020026020010151604051602001611615929190918252602082015260400190565b6040516020818303038152906040528051906020012090506115cd565b98975050505050505050565b60208101515160e08201515160609190811461166d5760405163587543d160e01b815260040160405180910390fd5b5f80826001600160401b0381111561168757611687612201565b6040519080825280602002602001820160405280156116e457816020015b6116d160405180606001604052805f6001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116a55790505b5090505f836001600160401b0381111561170057611700612201565b60405190808252806020026020018201604052801561174557816020015b604080518082019091525f81526060602082015281526020019060019003908161171e5790505b509050836001600160401b0381111561176057611760612201565b60405190808252806020026020018201604052801561179357816020015b606081526020019060019003908161177e5790505b5086515160a088015191965015905f906117ac90611e25565b9050876080015180156117bd575080155b156117db5760405163105858e560e31b815260040160405180910390fd5b5f5b868110156119bc575f896020015182815181106117fc576117fc612a3b565b602002602001015190505f8a60e00151838151811061181d5761181d612a3b565b60200260200101519050801561185257818a848151811061184057611840612a3b565b602002602001018190525050506119b4565b8415801561185d5750835b156118a3578a5160405161187691908490602401612caa565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b17905291505b5f5f5f5f6118b58f60a0015187611e9e565b9350935093509350831561192a57828060200190518101906118d79190612ed9565b8b8d815181106118e9576118e9612a3b565b6020026020010181905250818a888151811061190757611907612a3b565b602090810291909101015261191d60018d612ceb565b9b505050505050506119b4565b8080156119345750875b15611950578280602001905181019061194d9190612cfe565b92505b828e888151811061196357611963612a3b565b60200260200101819052508e60200151878151811061198457611984612a3b565b60200260200101518a888151811061199e5761199e612a3b565b6020026020010151602001819052505050505050505b6001016117dd565b50845f036119cf57505050505050919050565b84845230886040015163a780bab660e01b866040516024016119f19190612fbf565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b0383818316178352505050508a606001518b608001518c60a001518d604001518e60c001518a604051602001611a52959493929190613022565b60408051601f1981840301815290829052630556f18360e41b8252610a1a95949392916004016130e8565b80516060905f9081908490611a93816002612ceb565b6001600160401b03811115611aaa57611aaa612201565b6040519080825280601f01601f191660200182016040528015611ad4576020820181803683370190505b5094505f9350808403611b15575f60f81b855f81518110611af757611af7612a3b565b60200101906001600160f81b03191690815f1a905350505050915091565b5f1981015b828181518110611b2c57611b2c612a3b565b01602001516001600160f81b031916601760f91b03611bb8578360f81b868260010181518110611b5e57611b5e612a3b565b60200101906001600160f81b03191690815f1a90535084611b86846001840160ff881661202f565b6040805160208101939093528201526060016040516020818303038152906040528051906020012094505f9350611c07565b600184019350828181518110611bd057611bd0612a3b565b602001015160f81c60f81b868260010181518110611bf057611bf0612a3b565b60200101906001600160f81b03191690815f1a9053505b8015611c15575f1901611b1a565b5083611c25835f60ff871661202f565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b855f81518110611af757611af7612a3b565b5f806002611c738585612de5565b611c7d919061311d565b15611c8957505f610447565b8284101580611c985750845183115b15611ca757505f905080610447565b600190508451831115611cb8575f5ffd5b611d08565b5f603a8210602f83111615611cd45750602f190190565b60478210604083111615611cea57506036190190565b60678210606083111615611d0057506056190190565b5060ff919050565b60208501845b84811015611d6757611d24818301515f1a611cbd565b611d35600183018401515f1a611cbd565b60ff811460ff83141715611d4d575f94505050611d67565b60049190911b1760089490941b9390931792600201611d0e565b5050935093915050565b5f5f83518310611dc35760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e647300006044820152606401610a1a565b5f848481518110611dd657611dd6612a3b565b016020015160f81c90508015611e0257611dfb85611df5866001612ceb565b8361202f565b9250611e06565b5f92505b611e108185612ceb565b611e1b906001612ceb565b9150509250929050565b6040516301ffc9a760e01b8152639061b92360e01b60048201525f906001600160a01b038316906301ffc9a79061c350906024016020604051808303818786fa93505050508015611e93575060408051601f3d908101601f19168201909252611e909181019061313c565b60015b61032e57505f919050565b604080518082019091525f80825260606020830181905290915f611ec28686612051565b90503d8115611ee6575f611ed65f8361206e565b9095509350600191506109e49050565b60048110612025575f611efa5f600461206e565b90505f611f116004611f0c8186612de5565b61206e565b9050630556f18360e41b611f2483613157565b6001600160e01b03191603611fee575f5f5f5f5f85806020019051810190611f4c9190613195565b945094509450945094508d6001600160a01b0316856001600160a01b031603611fe4576040518060600160405280866001600160a01b0316815260200185815260200184815250604051602001611fa39190613247565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b5090995097505f96506109e495505050505050565b5050505050612022565b8181604051602001612001929190613270565b60408051601f198184030181529190525f975095508693506109e492505050565b50505b5092959194509250565b82515f9061203d8385612ceb565b1115612047575f5ffd5b5091016020012090565b5f823b61205c575f5ffd5b5f5f835160208501865afa9392505050565b6060816001600160401b0381111561208857612088612201565b6040519080825280601f01601f1916602001820160405280156120b2576020820181803683370190505b5090503d82840111156120c3575f5ffd5b8183602083013e92915050565b828054828255905f5260205f20908101928215612114579160200282015b82811115612114578251829061210490826132d0565b50916020019190600101906120ee565b50612120929150612124565b5090565b80821115612120575f6121378282612140565b50600101612124565b50805461214c90612966565b5f825580601f1061215b575050565b601f0160209004905f5260205f2090810190610a2c91905b80821115612120575f8155600101612173565b6001600160e01b031981168114610a2c575f5ffd5b5f602082840312156121ab575f5ffd5b81356121b681612186565b9392505050565b5f5f83601f8401126121cd575f5ffd5b5081356001600160401b038111156121e3575f5ffd5b6020830191508360208285010111156121fa575f5ffd5b9250929050565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b038111828210171561223757612237612201565b60405290565b604051606081016001600160401b038111828210171561223757612237612201565b604051601f8201601f191681016001600160401b038111828210171561228757612287612201565b604052919050565b5f6001600160401b038211156122a7576122a7612201565b50601f01601f191660200190565b5f6122c76122c28461228f565b61225f565b90508281528383830111156122da575f5ffd5b828260208301375f602084830101529392505050565b5f82601f8301126122ff575f5ffd5b6121b6838335602085016122b5565b5f6001600160401b0382111561232657612326612201565b5060051b60200190565b5f82601f83011261233f575f5ffd5b813561234d6122c28261230e565b8082825260208201915060208360051b86010192508583111561236e575f5ffd5b602085015b838110156123c15780356001600160401b03811115612390575f5ffd5b8601603f810188136123a0575f5ffd5b6123b2886020830135604084016122b5565b84525060209283019201612373565b5095945050505050565b5f5f5f5f606085870312156123de575f5ffd5b84356001600160401b038111156123f3575f5ffd5b6123ff878288016121bd565b90955093505060208501356001600160401b0381111561241d575f5ffd5b612429878288016122f0565b92505060408501356001600160401b03811115612444575f5ffd5b61245087828801612330565b91505092959194509250565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b604081525f61249c604083018561245c565b905060018060a01b03831660208301529392505050565b5f82601f8301126124c2575f5ffd5b81356124d06122c28261230e565b8082825260208201915060208360051b8601019250858311156124f1575f5ffd5b602085015b838110156123c15780356001600160401b03811115612513575f5ffd5b612522886020838a01016122f0565b845250602092830192016124f6565b5f5f5f60408486031215612543575f5ffd5b83356001600160401b03811115612558575f5ffd5b612564868287016121bd565b90945092505060208401356001600160401b03811115612582575f5ffd5b61258e868287016124b3565b9150509250925092565b5f604082016040835280855180835260608501915060608160051b8601019250602087015f5b828110156125ef57605f198786030184526125da85835161245c565b945060209384019391909101906001016125be565b505050506001600160a01b03939093166020929092019190915250919050565b5f5f5f5f60408587031215612622575f5ffd5b84356001600160401b03811115612637575f5ffd5b612643878288016121bd565b90955093505060208501356001600160401b03811115612661575f5ffd5b61266d878288016121bd565b95989497509550505050565b608081525f61268b608083018761245c565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b5f5f5f5f606085870312156126c7575f5ffd5b84356001600160401b038111156126dc575f5ffd5b6126e8878288016121bd565b90955093505060208501356001600160401b03811115612706575f5ffd5b612429878288016124b3565b5f5f5f5f5f5f60a08789031215612727575f5ffd5b86356001600160401b0381111561273c575f5ffd5b61274889828a016121bd565b90975095505060208701356001600160401b03811115612766575f5ffd5b61277289828a016122f0565b94505060408701356001600160401b0381111561278d575f5ffd5b61279989828a01612330565b93505060608701356127aa81612186565b915060808701356001600160401b038111156127c4575f5ffd5b6127d089828a016122f0565b9150509295509295509295565b5f602082840312156127ed575f5ffd5b81356001600160401b03811115612802575f5ffd5b61280e84828501612330565b949350505050565b5f5f5f60408486031215612828575f5ffd5b83356001600160401b0381111561283d575f5ffd5b612849868287016121bd565b90945092505060208401356001600160401b03811115612867575f5ffd5b61258e868287016122f0565b5f5f60208385031215612884575f5ffd5b82356001600160401b03811115612899575f5ffd5b6128a5858286016121bd565b90969095509350505050565b5f602082840312156128c1575f5ffd5b5035919050565b602081525f6121b6602083018461245c565b5f5f5f604084860312156128ec575f5ffd5b83356001600160401b03811115612901575f5ffd5b61290d868287016121bd565b90945092505060208401356001600160401b0381111561292b575f5ffd5b61258e86828701612330565b6001600160a01b0381168114610a2c575f5ffd5b5f6020828403121561295b575f5ffd5b81356121b681612937565b600181811c9082168061297a57607f821691505b60208210810361299857634e487b7160e01b5f52602260045260245ffd5b50919050565b5f82601f8301126129ad575f5ffd5b8151602083015f6129c06122c28461228f565b90508281528583830111156129d3575f5ffd5b8282602083015e5f92810160200192909252509392505050565b5f5f604083850312156129fe575f5ffd5b82516001600160401b03811115612a13575f5ffd5b612a1f8582860161299e565b9250506020830151612a3081612937565b809150509250929050565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215612a5f575f5ffd5b81516121b681612937565b8015158114610a2c575f5ffd5b5f5f60408385031215612a88575f5ffd5b82356001600160401b03811115612a9d575f5ffd5b8301601f81018513612aad575f5ffd5b8035612abb6122c28261230e565b8082825260208201915060208360051b850101925087831115612adc575f5ffd5b6020840193505b82841015612b07578335612af681612a6a565b825260209384019390910190612ae3565b945050505060208301356001600160401b03811115612b24575f5ffd5b611e1b858286016124b3565b5f5f5f5f5f60a08688031215612b44575f5ffd5b8535612b4f81612a6a565b94506020860135612b5f81612937565b935060408601356001600160401b03811115612b79575f5ffd5b612b8588828901612330565b93505060608601356001600160401b03811115612ba0575f5ffd5b612bac888289016122f0565b92505060808601356001600160401b03811115612bc7575f5ffd5b8601601f81018813612bd7575f5ffd5b8035612be56122c28261230e565b8082825260208201915060208360051b85010192508a831115612c06575f5ffd5b602084015b83811015612c985780356001600160401b03811115612c28575f5ffd5b85016040818e03601f19011215612c3d575f5ffd5b612c45612215565b6020820135612c5381612186565b815260408201356001600160401b03811115612c6d575f5ffd5b612c7c8f6020838601016122f0565b6020830152508085525050602083019250602081019050612c0b565b50809450505050509295509295909350565b604081525f612cbc604083018561245c565b8281036020840152612cce818561245c565b95945050505050565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561032e5761032e612cd7565b5f60208284031215612d0e575f5ffd5b81516001600160401b03811115612d23575f5ffd5b61280e8482850161299e565b5f82825180855260208501945060208160051b830101602085015f5b83811015612d7d57601f19858403018852612d6783835161245c565b6020988901989093509190910190600101612d4b565b50909695505050505050565b60a081525f612d9b60a083018861245c565b8281036020840152612dad818861245c565b90508281036040840152612dc18187612d2f565b6001600160e01b03198616606085015283810360808501529050611632818561245c565b8181038181111561032e5761032e612cd7565b5f5f85851115612e06575f5ffd5b83861115612e12575f5ffd5b5050820193919092039150565b818382375f9101908152919050565b5f60018201612e3f57612e3f612cd7565b5060010190565b5f81612e5457612e54612cd7565b505f190190565b5f82601f830112612e6a575f5ffd5b8151612e786122c28261230e565b8082825260208201915060208360051b860101925085831115612e99575f5ffd5b602085015b838110156123c15780516001600160401b03811115612ebb575f5ffd5b612eca886020838a010161299e565b84525060209283019201612e9e565b5f60208284031215612ee9575f5ffd5b81516001600160401b03811115612efe575f5ffd5b820160608185031215612f0f575f5ffd5b612f1761223d565b8151612f2281612937565b815260208201516001600160401b03811115612f3c575f5ffd5b612f4886828501612e5b565b60208301525060408201516001600160401b03811115612f66575f5ffd5b612f728682850161299e565b604083015250949350505050565b60018060a01b0381511682525f602082015160606020850152612fa66060850182612d2f565b905060408301518482036040860152612cce828261245c565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561301657603f19878603018452613001858351612f80565b94506020938401939190910190600101612fe5565b50929695505050505050565b85151581526001600160a01b038516602082015260a0604082018190525f9061304d90830186612d2f565b828103606084015261305f818661245c565b9050828103608084015280845180835260208301915060208160051b840101602087015f5b838110156130d757858303601f19018552815180516001600160e01b03191684526020908101516040918501829052906130c09085018261245c565b602096870196909450929092019150600101613084565b50909b9a5050505050505050505050565b6001600160a01b038616815260a0602082018190525f9061310b90830187612d2f565b8281036040840152612dc1818761245c565b5f8261313757634e487b7160e01b5f52601260045260245ffd5b500690565b5f6020828403121561314c575f5ffd5b81516121b681612a6a565b805160208201516001600160e01b031981169190600482101561318e576001600160e01b0319600483900360031b81901b82161692505b5050919050565b5f5f5f5f5f60a086880312156131a9575f5ffd5b85516131b481612937565b60208701519095506001600160401b038111156131cf575f5ffd5b6131db88828901612e5b565b94505060408601516001600160401b038111156131f6575f5ffd5b6132028882890161299e565b935050606086015161321381612186565b60808701519092506001600160401b0381111561322e575f5ffd5b61323a8882890161299e565b9150509295509295909350565b602081525f6121b66020830184612f80565b5f81518060208401855e5f93019283525090919050565b5f61280e61327e8386613259565b84613259565b601f8211156132cb57805f5260205f20601f840160051c810160208510156132a95750805b601f840160051c820191505b818110156132c8575f81556001016132b5565b50505b505050565b81516001600160401b038111156132e9576132e9612201565b6132fd816132f78454612966565b84613284565b6020601f82116001811461332f575f83156133185750848201515b5f19600385901b1c1916600184901b1784556132c8565b5f84815260208120601f198516915b8281101561335e578785015182556020948501946001909201910161333e565b508482101561337b57868401515f19600387901b60f8161c191681555b50505050600190811b0190555056fea2646970667358221220c137a2f87a7ea65f6ad0abfc8b464684e8e7a772ce64993bdb3adc0e46ca695864736f6c634300081c00330000000000000000000000005b22280886a2f5e09a49bea7e320eab0e5320e2800000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561000f575f5ffd5b5060043610610111575f3560e01c80638e5ea8df1161009e578063b241d0d31161006e578063b241d0d31461029f578063b4a85801146102b2578063e0a85412146102c5578063ec11c823146102d8578063f2fde38b146102eb575f5ffd5b80638e5ea8df146102215780639061b92314610234578063a1cbcbaf14610247578063a6b164191461027f575f5ffd5b8063715018a6116100e4578063715018a6146101a257806376286c00146101ac5780637b103999146101bf5780638da5cb5b146101fe5780638e25a0f31461020e575f5ffd5b806301ffc9a7146101155780630667cfea1461013d578063206c74c91461015e5780636dc4fb731461017f575b5f5ffd5b61012861012336600461219b565b6102fe565b60405190151581526020015b60405180910390f35b61015061014b3660046123cb565b610334565b60405161013492919061248a565b61017161016c366004612531565b610367565b604051610134929190612598565b61019261018d36600461260f565b61044f565b6040516101349493929190612679565b6101aa610516565b005b6101716101ba3660046126b4565b610529565b6101e67f0000000000000000000000005b22280886a2f5e09a49bea7e320eab0e5320e2881565b6040516001600160a01b039091168152602001610134565b5f546001600160a01b03166101e6565b61015061021c366004612712565b61054f565b6101aa61022f3660046127dd565b6105e0565b610150610242366004612816565b6105ff565b61025a610255366004612873565b6106f1565b604080516001600160a01b039094168452602084019290925290820152606001610134565b61029261028d3660046128b1565b610713565b60405161013491906128c8565b6101926102ad3660046128da565b6107b9565b6101716102c036600461260f565b61088c565b6101506102d336600461260f565b6108b6565b6101926102e6366004612873565b6108ff565b6101aa6102f936600461294b565b6109ed565b5f6001600160e01b03198216639061b92360e01b148061032e57506301ffc9a760e01b6001600160e01b03198316145b92915050565b60605f61035a8686868663e0a8541260e01b60405180602001604052805f81525061054f565b9150915094509492505050565b60605f6104428585856001805480602002602001604051908101604052809291908181526020015f905b82821015610439578382905f5260205f200180546103ae90612966565b80601f01602080910402602001604051908101604052809291908181526020018280546103da90612966565b80156104255780601f106103fc57610100808354040283529160200191610425565b820191905f5260205f20905b81548152906001019060200180831161040857829003601f168201915b505050505081526020019060010190610391565b50505050610529565b915091505b935093915050565b60605f80808080808061046c8c8c8c8c636dc4fb7360e01b610a2f565b93509350935093505f815111156104da575f5f8280602001905181019061049391906129ed565b915091505f865f815181106104aa576104aa612a3b565b60200260200101518060200190518101906104c59190612a4f565b929a50919850965092945061050b9350505050565b6104fe845f815181106104ef576104ef612a3b565b60200260200101518484610d9f565b9750975097509750505050505b945094509450949050565b61051e610edc565b6105275f610f08565b565b60605f61035a8686868663b4a8580160e01b60405180602001604052805f815250610f57565b6040805160018082528183019092526060915f918291816020015b606081526020019060019003908161056a57905050905086815f8151811061059457610594612a3b565b60200260200101819052505f5f6105af8b8b858b8b8b610f57565b91509150815f815181106105c5576105c5612a3b565b60200260200101518194509450505050965096945050505050565b6105e8610edc565b80516105fb9060019060208401906120d0565b5050565b60605f6104428585856001805480602002602001604051908101604052809291908181526020015f905b828210156106d1578382905f5260205f2001805461064690612966565b80601f016020809104026020016040519081016040528092919081815260200182805461067290612966565b80156106bd5780601f10610694576101008083540402835291602001916106bd565b820191905f5260205f20905b8154815290600101906020018083116106a057829003601f168201915b505050505081526020019060010190610629565b5050505063e0a8541260e01b60405180602001604052805f81525061054f565b5f5f5f5f5f5f61070288885f61107a565b919750955093505050509250925092565b60018181548110610722575f80fd5b905f5260205f20015f91509050805461073a90612966565b80601f016020809104026020016040519081016040528092919081815260200182805461076690612966565b80156107b15780601f10610788576101008083540402835291602001916107b1565b820191905f5260205f20905b81548152906001019060200180831161079457829003601f168201915b505050505081565b60605f5f5f5f6108015f89898080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250929392505061148b9050565b60405160240161081391815260200190565b60408051601f19818403018152918152602080830180516001600160e01b031663691f343160e01b17905281519081019091525f8082529192508190610869908b908b9086908c90636dc4fb7360e01b9061054f565b9150915061087882828a610d9f565b965096509650965050505093509350935093565b60605f80806108a58888888863b4a8580160e01b610a2f565b50919a909950975050505050505050565b60605f80806108cf888888886370542a0960e11b610a2f565b505091509150815f815181106108e7576108e7612a3b565b60200260200101518193509350505094509492505050565b60605f5f5f6109db86866001805480602002602001604051908101604052809291908181526020015f905b828210156109d2578382905f5260205f2001805461094790612966565b80601f016020809104026020016040519081016040528092919081815260200182805461097390612966565b80156109be5780601f10610995576101008083540402835291602001916109be565b820191905f5260205f20905b8154815290600101906020018083116109a157829003601f168201915b50505050508152602001906001019061092a565b505050506107b9565b93509350935093505b92959194509250565b6109f5610edc565b6001600160a01b038116610a2357604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b610a2c81610f08565b50565b60605f606080610a8f6040518061010001604052806060815260200160608152602001606081526020015f6001600160e01b03191681526020015f151581526020015f6001600160a01b0316815260200160608152602001606081525090565b6001600160e01b0319861660608201525f80610aad8b8d018d612a77565b90925090506060610ac08a8c018c612b30565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610af9575f5ffd5b80516001600160401b03811115610b1257610b12612201565b604051908082528060200260200182016040528015610b4557816020015b6060815260200190600190039081610b305790505b50602085015280516001600160401b03811115610b6457610b64612201565b604051908082528060200260200182016040528015610b8d578160200160208202803683370190505b5060e08501525f805b8251811015610d6d5782515f90849083908110610bb557610bb5612a3b565b60200260200101515f01516001600160e01b03191603610c1357828181518110610be157610be1612a3b565b60200260200101516020015186602001518281518110610c0357610c03612a3b565b6020026020010181905250610d65565b848281518110610c2557610c25612a3b565b602002602001015115610c9c5760018660e001518281518110610c4a57610c4a612a3b565b602002602001019015159081151581525050838281518110610c6e57610c6e612a3b565b602002602001015186602001518281518110610c8c57610c8c612a3b565b6020026020010181905250610d57565b828181518110610cae57610cae612a3b565b60200260200101515f0151848381518110610ccb57610ccb612a3b565b6020026020010151848381518110610ce557610ce5612a3b565b602002602001015160200151604051602401610d02929190612caa565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610d4b57610d4b612a3b565b60200260200101819052505b610d62826001612ceb565b91505b600101610b96565b50610d778561163e565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b60605f5f5f5f87806020019051810190610db99190612cfe565b90505f5f610dc683611a7d565b915091505f81604051602401610dde91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b0316631d9dabef60e11b17905290519192505f91610e1e9187918e910161248a565b60405160208183030381529060405290505f5f306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b8152600401610e6c959493929190612d89565b5f60405180830381865afa158015610e86573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610ead91908101906129ed565b915091505f82806020019051810190610ec69190612a4f565b979f979e50909b50959950505050505050505050565b5f546001600160a01b031633146105275760405163118cdaa760e01b8152336004820152602401610a1a565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60605f5f5f610f668a8a6106f1565b919450849350909150506001600160a01b038216610f9757604051637199966d60e01b815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b81528315159261106a929182918f908f90819085018382808284375f92019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e0909101906001600160401b0381111561103957611039612201565b604051908082528060200260200182016040528015611062578160200160208202803683370190505b50905261163e565b9450505050965096945050505050565b5f808084841061109157505f915081905082611482565b5f8686868181106110a4576110a4612a3b565b919091013560f81c9150505f8190036110c657505f9250829150839050611482565b856110d18287612ceb565b6110dc906001612ceb565b11156110f157505f9250829150839050611482565b5f6110fc8287612ceb565b611107906001612ceb565b90505f82604214801561114c57508888611122896001612ceb565b81811061113157611131612a3b565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b801561118a57508888611160600185612de5565b81811061116f5761116f612a3b565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b1561134b575f898961119d8a6002612ceb565b906111a9600187612de5565b926111b693929190612df8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250508251929350506040909114905061121157604051639bf46a6360e01b815260040160405180910390fd5b5f5b6040811015611334575f82828151811061122f5761122f612a3b565b01602001516001600160f81b0319169050600360fc1b81108015906112625750603960f81b6001600160f81b0319821611155b1580156112985750604160f81b6001600160f81b03198216108015906112965750602360f91b6001600160f81b0319821611155b155b80156112cd5750606160f81b6001600160f81b03198216108015906112cb5750603360f91b6001600160f81b0319821611155b155b1561132b5760405162461bcd60e51b815260206004820152602860248201527f496e76616c6964206865782063686172616374657220696e20656e63727970746044820152671959081b1858995b60c21b6064820152608401610a1a565b50600101611213565b50611341815f6040611c65565b50915061137d9050565b8888611358896001612ceb565b61136492859290612df8565b604051611372929190612e1f565b604051809103902090505b5f5f5f61138b8c8c8761107a565b9250925092505f82856040516020016113ae929190918252602082015260400190565b60408051601f19818403018152908290528051602090910120630178b8bf60e01b82526004820181905291505f906001600160a01b037f0000000000000000000000005b22280886a2f5e09a49bea7e320eab0e5320e281690630178b8bf90602401602060405180830381865afa15801561142b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061144f9190612a4f565b90506001600160a01b03811615611473579950975089965061148295505050505050565b50929850919650909450505050505b93509350939050565b5f80825b84518110156114cc575f5f6114a48784611d71565b9092509050816114b55750506114cc565b836114bf81612e2e565b945050809250505061148f565b5f826001600160401b038111156114e5576114e5612201565b60405190808252806020026020018201604052801561150e578160200160208202803683370190505b509050845f5b87518210156115cb575f5f6115298a85611d71565b9092509050816115965760018a516115419190612de5565b841461158f5760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d650000006044820152606401610a1a565b50506115cb565b818584815181106115a9576115a9612a3b565b6020908102919091010152826115be81612e2e565b9350508093505050611514565b5f5b851561163257856115dd81612e46565b965050808487815181106115f3576115f3612a3b565b6020026020010151604051602001611615929190918252602082015260400190565b6040516020818303038152906040528051906020012090506115cd565b98975050505050505050565b60208101515160e08201515160609190811461166d5760405163587543d160e01b815260040160405180910390fd5b5f80826001600160401b0381111561168757611687612201565b6040519080825280602002602001820160405280156116e457816020015b6116d160405180606001604052805f6001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116a55790505b5090505f836001600160401b0381111561170057611700612201565b60405190808252806020026020018201604052801561174557816020015b604080518082019091525f81526060602082015281526020019060019003908161171e5790505b509050836001600160401b0381111561176057611760612201565b60405190808252806020026020018201604052801561179357816020015b606081526020019060019003908161177e5790505b5086515160a088015191965015905f906117ac90611e25565b9050876080015180156117bd575080155b156117db5760405163105858e560e31b815260040160405180910390fd5b5f5b868110156119bc575f896020015182815181106117fc576117fc612a3b565b602002602001015190505f8a60e00151838151811061181d5761181d612a3b565b60200260200101519050801561185257818a848151811061184057611840612a3b565b602002602001018190525050506119b4565b8415801561185d5750835b156118a3578a5160405161187691908490602401612caa565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b17905291505b5f5f5f5f6118b58f60a0015187611e9e565b9350935093509350831561192a57828060200190518101906118d79190612ed9565b8b8d815181106118e9576118e9612a3b565b6020026020010181905250818a888151811061190757611907612a3b565b602090810291909101015261191d60018d612ceb565b9b505050505050506119b4565b8080156119345750875b15611950578280602001905181019061194d9190612cfe565b92505b828e888151811061196357611963612a3b565b60200260200101819052508e60200151878151811061198457611984612a3b565b60200260200101518a888151811061199e5761199e612a3b565b6020026020010151602001819052505050505050505b6001016117dd565b50845f036119cf57505050505050919050565b84845230886040015163a780bab660e01b866040516024016119f19190612fbf565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b0383818316178352505050508a606001518b608001518c60a001518d604001518e60c001518a604051602001611a52959493929190613022565b60408051601f1981840301815290829052630556f18360e41b8252610a1a95949392916004016130e8565b80516060905f9081908490611a93816002612ceb565b6001600160401b03811115611aaa57611aaa612201565b6040519080825280601f01601f191660200182016040528015611ad4576020820181803683370190505b5094505f9350808403611b15575f60f81b855f81518110611af757611af7612a3b565b60200101906001600160f81b03191690815f1a905350505050915091565b5f1981015b828181518110611b2c57611b2c612a3b565b01602001516001600160f81b031916601760f91b03611bb8578360f81b868260010181518110611b5e57611b5e612a3b565b60200101906001600160f81b03191690815f1a90535084611b86846001840160ff881661202f565b6040805160208101939093528201526060016040516020818303038152906040528051906020012094505f9350611c07565b600184019350828181518110611bd057611bd0612a3b565b602001015160f81c60f81b868260010181518110611bf057611bf0612a3b565b60200101906001600160f81b03191690815f1a9053505b8015611c15575f1901611b1a565b5083611c25835f60ff871661202f565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b855f81518110611af757611af7612a3b565b5f806002611c738585612de5565b611c7d919061311d565b15611c8957505f610447565b8284101580611c985750845183115b15611ca757505f905080610447565b600190508451831115611cb8575f5ffd5b611d08565b5f603a8210602f83111615611cd45750602f190190565b60478210604083111615611cea57506036190190565b60678210606083111615611d0057506056190190565b5060ff919050565b60208501845b84811015611d6757611d24818301515f1a611cbd565b611d35600183018401515f1a611cbd565b60ff811460ff83141715611d4d575f94505050611d67565b60049190911b1760089490941b9390931792600201611d0e565b5050935093915050565b5f5f83518310611dc35760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e647300006044820152606401610a1a565b5f848481518110611dd657611dd6612a3b565b016020015160f81c90508015611e0257611dfb85611df5866001612ceb565b8361202f565b9250611e06565b5f92505b611e108185612ceb565b611e1b906001612ceb565b9150509250929050565b6040516301ffc9a760e01b8152639061b92360e01b60048201525f906001600160a01b038316906301ffc9a79061c350906024016020604051808303818786fa93505050508015611e93575060408051601f3d908101601f19168201909252611e909181019061313c565b60015b61032e57505f919050565b604080518082019091525f80825260606020830181905290915f611ec28686612051565b90503d8115611ee6575f611ed65f8361206e565b9095509350600191506109e49050565b60048110612025575f611efa5f600461206e565b90505f611f116004611f0c8186612de5565b61206e565b9050630556f18360e41b611f2483613157565b6001600160e01b03191603611fee575f5f5f5f5f85806020019051810190611f4c9190613195565b945094509450945094508d6001600160a01b0316856001600160a01b031603611fe4576040518060600160405280866001600160a01b0316815260200185815260200184815250604051602001611fa39190613247565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b5090995097505f96506109e495505050505050565b5050505050612022565b8181604051602001612001929190613270565b60408051601f198184030181529190525f975095508693506109e492505050565b50505b5092959194509250565b82515f9061203d8385612ceb565b1115612047575f5ffd5b5091016020012090565b5f823b61205c575f5ffd5b5f5f835160208501865afa9392505050565b6060816001600160401b0381111561208857612088612201565b6040519080825280601f01601f1916602001820160405280156120b2576020820181803683370190505b5090503d82840111156120c3575f5ffd5b8183602083013e92915050565b828054828255905f5260205f20908101928215612114579160200282015b82811115612114578251829061210490826132d0565b50916020019190600101906120ee565b50612120929150612124565b5090565b80821115612120575f6121378282612140565b50600101612124565b50805461214c90612966565b5f825580601f1061215b575050565b601f0160209004905f5260205f2090810190610a2c91905b80821115612120575f8155600101612173565b6001600160e01b031981168114610a2c575f5ffd5b5f602082840312156121ab575f5ffd5b81356121b681612186565b9392505050565b5f5f83601f8401126121cd575f5ffd5b5081356001600160401b038111156121e3575f5ffd5b6020830191508360208285010111156121fa575f5ffd5b9250929050565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b038111828210171561223757612237612201565b60405290565b604051606081016001600160401b038111828210171561223757612237612201565b604051601f8201601f191681016001600160401b038111828210171561228757612287612201565b604052919050565b5f6001600160401b038211156122a7576122a7612201565b50601f01601f191660200190565b5f6122c76122c28461228f565b61225f565b90508281528383830111156122da575f5ffd5b828260208301375f602084830101529392505050565b5f82601f8301126122ff575f5ffd5b6121b6838335602085016122b5565b5f6001600160401b0382111561232657612326612201565b5060051b60200190565b5f82601f83011261233f575f5ffd5b813561234d6122c28261230e565b8082825260208201915060208360051b86010192508583111561236e575f5ffd5b602085015b838110156123c15780356001600160401b03811115612390575f5ffd5b8601603f810188136123a0575f5ffd5b6123b2886020830135604084016122b5565b84525060209283019201612373565b5095945050505050565b5f5f5f5f606085870312156123de575f5ffd5b84356001600160401b038111156123f3575f5ffd5b6123ff878288016121bd565b90955093505060208501356001600160401b0381111561241d575f5ffd5b612429878288016122f0565b92505060408501356001600160401b03811115612444575f5ffd5b61245087828801612330565b91505092959194509250565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b604081525f61249c604083018561245c565b905060018060a01b03831660208301529392505050565b5f82601f8301126124c2575f5ffd5b81356124d06122c28261230e565b8082825260208201915060208360051b8601019250858311156124f1575f5ffd5b602085015b838110156123c15780356001600160401b03811115612513575f5ffd5b612522886020838a01016122f0565b845250602092830192016124f6565b5f5f5f60408486031215612543575f5ffd5b83356001600160401b03811115612558575f5ffd5b612564868287016121bd565b90945092505060208401356001600160401b03811115612582575f5ffd5b61258e868287016124b3565b9150509250925092565b5f604082016040835280855180835260608501915060608160051b8601019250602087015f5b828110156125ef57605f198786030184526125da85835161245c565b945060209384019391909101906001016125be565b505050506001600160a01b03939093166020929092019190915250919050565b5f5f5f5f60408587031215612622575f5ffd5b84356001600160401b03811115612637575f5ffd5b612643878288016121bd565b90955093505060208501356001600160401b03811115612661575f5ffd5b61266d878288016121bd565b95989497509550505050565b608081525f61268b608083018761245c565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b5f5f5f5f606085870312156126c7575f5ffd5b84356001600160401b038111156126dc575f5ffd5b6126e8878288016121bd565b90955093505060208501356001600160401b03811115612706575f5ffd5b612429878288016124b3565b5f5f5f5f5f5f60a08789031215612727575f5ffd5b86356001600160401b0381111561273c575f5ffd5b61274889828a016121bd565b90975095505060208701356001600160401b03811115612766575f5ffd5b61277289828a016122f0565b94505060408701356001600160401b0381111561278d575f5ffd5b61279989828a01612330565b93505060608701356127aa81612186565b915060808701356001600160401b038111156127c4575f5ffd5b6127d089828a016122f0565b9150509295509295509295565b5f602082840312156127ed575f5ffd5b81356001600160401b03811115612802575f5ffd5b61280e84828501612330565b949350505050565b5f5f5f60408486031215612828575f5ffd5b83356001600160401b0381111561283d575f5ffd5b612849868287016121bd565b90945092505060208401356001600160401b03811115612867575f5ffd5b61258e868287016122f0565b5f5f60208385031215612884575f5ffd5b82356001600160401b03811115612899575f5ffd5b6128a5858286016121bd565b90969095509350505050565b5f602082840312156128c1575f5ffd5b5035919050565b602081525f6121b6602083018461245c565b5f5f5f604084860312156128ec575f5ffd5b83356001600160401b03811115612901575f5ffd5b61290d868287016121bd565b90945092505060208401356001600160401b0381111561292b575f5ffd5b61258e86828701612330565b6001600160a01b0381168114610a2c575f5ffd5b5f6020828403121561295b575f5ffd5b81356121b681612937565b600181811c9082168061297a57607f821691505b60208210810361299857634e487b7160e01b5f52602260045260245ffd5b50919050565b5f82601f8301126129ad575f5ffd5b8151602083015f6129c06122c28461228f565b90508281528583830111156129d3575f5ffd5b8282602083015e5f92810160200192909252509392505050565b5f5f604083850312156129fe575f5ffd5b82516001600160401b03811115612a13575f5ffd5b612a1f8582860161299e565b9250506020830151612a3081612937565b809150509250929050565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215612a5f575f5ffd5b81516121b681612937565b8015158114610a2c575f5ffd5b5f5f60408385031215612a88575f5ffd5b82356001600160401b03811115612a9d575f5ffd5b8301601f81018513612aad575f5ffd5b8035612abb6122c28261230e565b8082825260208201915060208360051b850101925087831115612adc575f5ffd5b6020840193505b82841015612b07578335612af681612a6a565b825260209384019390910190612ae3565b945050505060208301356001600160401b03811115612b24575f5ffd5b611e1b858286016124b3565b5f5f5f5f5f60a08688031215612b44575f5ffd5b8535612b4f81612a6a565b94506020860135612b5f81612937565b935060408601356001600160401b03811115612b79575f5ffd5b612b8588828901612330565b93505060608601356001600160401b03811115612ba0575f5ffd5b612bac888289016122f0565b92505060808601356001600160401b03811115612bc7575f5ffd5b8601601f81018813612bd7575f5ffd5b8035612be56122c28261230e565b8082825260208201915060208360051b85010192508a831115612c06575f5ffd5b602084015b83811015612c985780356001600160401b03811115612c28575f5ffd5b85016040818e03601f19011215612c3d575f5ffd5b612c45612215565b6020820135612c5381612186565b815260408201356001600160401b03811115612c6d575f5ffd5b612c7c8f6020838601016122f0565b6020830152508085525050602083019250602081019050612c0b565b50809450505050509295509295909350565b604081525f612cbc604083018561245c565b8281036020840152612cce818561245c565b95945050505050565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561032e5761032e612cd7565b5f60208284031215612d0e575f5ffd5b81516001600160401b03811115612d23575f5ffd5b61280e8482850161299e565b5f82825180855260208501945060208160051b830101602085015f5b83811015612d7d57601f19858403018852612d6783835161245c565b6020988901989093509190910190600101612d4b565b50909695505050505050565b60a081525f612d9b60a083018861245c565b8281036020840152612dad818861245c565b90508281036040840152612dc18187612d2f565b6001600160e01b03198616606085015283810360808501529050611632818561245c565b8181038181111561032e5761032e612cd7565b5f5f85851115612e06575f5ffd5b83861115612e12575f5ffd5b5050820193919092039150565b818382375f9101908152919050565b5f60018201612e3f57612e3f612cd7565b5060010190565b5f81612e5457612e54612cd7565b505f190190565b5f82601f830112612e6a575f5ffd5b8151612e786122c28261230e565b8082825260208201915060208360051b860101925085831115612e99575f5ffd5b602085015b838110156123c15780516001600160401b03811115612ebb575f5ffd5b612eca886020838a010161299e565b84525060209283019201612e9e565b5f60208284031215612ee9575f5ffd5b81516001600160401b03811115612efe575f5ffd5b820160608185031215612f0f575f5ffd5b612f1761223d565b8151612f2281612937565b815260208201516001600160401b03811115612f3c575f5ffd5b612f4886828501612e5b565b60208301525060408201516001600160401b03811115612f66575f5ffd5b612f728682850161299e565b604083015250949350505050565b60018060a01b0381511682525f602082015160606020850152612fa66060850182612d2f565b905060408301518482036040860152612cce828261245c565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561301657603f19878603018452613001858351612f80565b94506020938401939190910190600101612fe5565b50929695505050505050565b85151581526001600160a01b038516602082015260a0604082018190525f9061304d90830186612d2f565b828103606084015261305f818661245c565b9050828103608084015280845180835260208301915060208160051b840101602087015f5b838110156130d757858303601f19018552815180516001600160e01b03191684526020908101516040918501829052906130c09085018261245c565b602096870196909450929092019150600101613084565b50909b9a5050505050505050505050565b6001600160a01b038616815260a0602082018190525f9061310b90830187612d2f565b8281036040840152612dc1818761245c565b5f8261313757634e487b7160e01b5f52601260045260245ffd5b500690565b5f6020828403121561314c575f5ffd5b81516121b681612a6a565b805160208201516001600160e01b031981169190600482101561318e576001600160e01b0319600483900360031b81901b82161692505b5050919050565b5f5f5f5f5f60a086880312156131a9575f5ffd5b85516131b481612937565b60208701519095506001600160401b038111156131cf575f5ffd5b6131db88828901612e5b565b94505060408601516001600160401b038111156131f6575f5ffd5b6132028882890161299e565b935050606086015161321381612186565b60808701519092506001600160401b0381111561322e575f5ffd5b61323a8882890161299e565b9150509295509295909350565b602081525f6121b66020830184612f80565b5f81518060208401855e5f93019283525090919050565b5f61280e61327e8386613259565b84613259565b601f8211156132cb57805f5260205f20601f840160051c810160208510156132a95750805b601f840160051c820191505b818110156132c8575f81556001016132b5565b50505b505050565b81516001600160401b038111156132e9576132e9612201565b6132fd816132f78454612966565b84613284565b6020601f82116001811461332f575f83156133185750848201515b5f19600385901b1c1916600184901b1784556132c8565b5f84815260208120601f198516915b8281101561335e578785015182556020948501946001909201910161333e565b508482101561337b57868401515f19600387901b60f8161c191681555b50505050600190811b0190555056fea2646970667358221220c137a2f87a7ea65f6ad0abfc8b464684e8e7a772ce64993bdb3adc0e46ca695864736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005b22280886a2f5e09a49bea7e320eab0e5320e2800000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _registry (address): 0x5B22280886a2F5e09A49bEa7E320eAB0e5320e28
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000005b22280886a2f5e09a49bea7e320eab0e5320e28
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
2242:17092:8:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9099:205;;;;;;:::i;:::-;;:::i;:::-;;;565:14:34;;558:22;540:41;;528:2;513:18;9099:205:8;;;;;;;;3510:258;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;3336:168::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;8301:792::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;2293:101:0:-;;;:::i;:::-;;3774:248:8;;;;;;:::i;:::-;;:::i;2460:29::-;;;;;;;;-1:-1:-1;;;;;10014:32:34;;;9996:51;;9984:2;9969:18;2460:29:8;9839:214:34;1638:85:0;1684:7;1710:6;-1:-1:-1;;;;;1710:6:0;1638:85;;4028:466:8;;;;;;:::i;:::-;;:::i;2716:105::-;;;;;;:::i;:::-;;:::i;3118:212::-;;;;;;:::i;:::-;;:::i;14005:272::-;;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;13146:32:34;;;13128:51;;13210:2;13195:18;;13188:34;;;;13238:18;;;13231:34;13116:2;13101:18;14005:272:8;12898:373:34;2422:32:8;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;6167:539::-;;;;;;:::i;:::-;;:::i;7963:332::-;;;;;;:::i;:::-;;:::i;7612:345::-;;;;;;:::i;:::-;;:::i;5631:172::-;;;;;;:::i;:::-;;:::i;2543:215:0:-;;;;;;:::i;:::-;;:::i;9099:205:8:-;9184:4;-1:-1:-1;;;;;;9207:50:8;;-1:-1:-1;;;9207:50:8;;:90;;-1:-1:-1;;;;;;;;;;861:40:3;;;9261:36:8;9200:97;9099:205;-1:-1:-1;;9099:205:8:o;3510:258::-;3640:12;3654:7;3684:77;3699:4;;3705;3711:8;3721:35;;;3684:77;;;;;;;;;;;;:14;:77::i;:::-;3677:84;;;;3510:258;;;;;;;:::o;3336:168::-;3418:14;3434:7;3460:37;3468:4;;3474;3480:16;3460:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:7;:37::i;:::-;3453:44;;;;3336:168;;;;;;;:::o;8301:792::-;8424:13;8439:7;;;;;;;8598:68;8615:8;;8625:9;;-1:-1:-1;;;8598:16:8;:68::i;:::-;8480:186;;;;;;;;8699:1;8681:8;:15;:19;8677:323;;;8717:26;8745:30;8790:8;8779:39;;;;;;;;;;;;:::i;:::-;8716:102;;;;8832:23;8869:12;8882:1;8869:15;;;;;;;;:::i;:::-;;;;;;;8858:38;;;;;;;;;;;;:::i;:::-;8918:12;;-1:-1:-1;8832:64:8;;-1:-1:-1;8949:22:8;-1:-1:-1;8973:15:8;;-1:-1:-1;8910:79:8;;-1:-1:-1;;;;8910:79:8;8677:323;9017:69;9043:12;9056:1;9043:15;;;;;;;;:::i;:::-;;;;;;;9060;9077:8;9017:25;:69::i;:::-;9010:76;;;;;;;;;;;;8301:792;;;;;;;;;;:::o;2293:101:0:-;1531:13;:11;:13::i;:::-;2357:30:::1;2384:1;2357:18;:30::i;:::-;2293:101::o:0;3774:248:8:-;3904:14;3920:7;3950:65;3959:4;;3965;3971:8;3981:29;;;3950:65;;;;;;;;;;;;:8;:65::i;4028:466::-;4291:14;;;4303:1;4291:14;;;;;;;;;4233:12;;4247:7;;;;4291:14;;;;;;;;;;;;;;;;;;;;4266:39;;4328:4;4315:7;4323:1;4315:10;;;;;;;;:::i;:::-;;;;;;:17;;;;4343:22;4367:16;4387:61;4396:4;;4402:7;4411:8;4421:16;4439:8;4387;:61::i;:::-;4342:106;;;;4466:7;4474:1;4466:10;;;;;;;;:::i;:::-;;;;;;;4478:8;4458:29;;;;;;;4028:466;;;;;;;;;:::o;2716:105::-;1531:13:0;:11;:13::i;:::-;2790:24:8;;::::1;::::0;:16:::1;::::0;:24:::1;::::0;::::1;::::0;::::1;:::i;:::-;;2716:105:::0;:::o;3118:212::-;3198:12;3212:7;3238:85;3253:4;;3259;3265:16;3238:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3283:35;;;3238:85;;;;;;;;;;;;:14;:85::i;14005:272::-;14069:19;14090:7;14099;14119:16;14137;14155:19;14178:21;14191:4;;14197:1;14178:12;:21::i;:::-;14118:81;;-1:-1:-1;14118:81:8;-1:-1:-1;14118:81:8;-1:-1:-1;;;;14005:272:8;;;;;:::o;2422:32::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;6167:539::-;6283:13;6298:7;6307;6316;6339:24;6401:23;6422:1;6401:11;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6401:20:8;;:23;-1:-1:-1;;6401:20:8;:23;-1:-1:-1;6401:23:8:i;:::-;6366:59;;;;;;16673:25:34;;16661:2;16646:18;;16527:177;6366:59:8;;;;-1:-1:-1;;6366:59:8;;;;;;;;;;;;;;;-1:-1:-1;;;;;6366:59:8;-1:-1:-1;;;6366:59:8;;;6516:85;;;;;;;;-1:-1:-1;6516:85:8;;;6366:59;;-1:-1:-1;;;6516:85:8;;6531:11;;;;6366:59;;6557:8;;-1:-1:-1;;;6567:29:8;6516:14;:85::i;:::-;6435:166;;;;6619:80;6645:19;6666:22;6690:8;6619:25;:80::i;:::-;6612:87;;;;;;;;;;;6167:539;;;;;;;:::o;7963:332::-;8086:14;8102:7;;;8184:68;8201:8;;8211:9;;-1:-1:-1;;;8184:16:8;:68::i;:::-;-1:-1:-1;8125:127:8;;;;-1:-1:-1;7963:332:8;-1:-1:-1;;;;;;;;7963:332:8:o;7612:345::-;7741:12;7755:7;;;7837:74;7854:8;;7864:9;;-1:-1:-1;;;7837:16:8;:74::i;:::-;7778:133;;;;;;7929:7;7937:1;7929:10;;;;;;;;:::i;:::-;;;;;;;7941:8;7921:29;;;;;;7612:345;;;;;;;:::o;5631:172::-;5699:13;5714:7;5723;5732;5758:38;5766:11;;5779:16;5758:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:7;:38::i;:::-;5751:45;;;;;;;;5631:172;;;;;;;;:::o;2543:215:0:-;1531:13;:11;:13::i;:::-;-1:-1:-1;;;;;2627:22:0;::::1;2623:91;;2672:31;::::0;-1:-1:-1;;;2672:31:0;;2700:1:::1;2672:31;::::0;::::1;9996:51:34::0;9969:18;;2672:31:0::1;;;;;;;;2623:91;2723:28;2742:8;2723:18;:28::i;:::-;2543:215:::0;:::o;9310:1801:8:-;9459:14;9475:7;9484:15;9501:12;9529:34;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9529:34:8;-1:-1:-1;;;;;;9573:49:8;;:30;;;:49;9633:22;;9685:39;;;;9696:8;9685:39;:::i;:::-;9632:92;;-1:-1:-1;9632:92:8;-1:-1:-1;9734:43:8;9912:82;;;;9923:9;9912:82;:::i;:::-;9862:22;;;9787:207;;;;9838:22;;;9787:207;;;;-1:-1:-1;;;;;9787:207:8;;;9814:22;;;9787:207;;;;9788:24;;;9787:207;10032:17;;10012:16;;9787:207;;-1:-1:-1;;10012:37:8;10004:46;;;;;;10093:10;:17;-1:-1:-1;;;;;10081:30:8;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10060:18:8;;;:51;10157:17;;-1:-1:-1;;;;;10146:29:8;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10146:29:8;-1:-1:-1;10121:22:8;;;:54;10185:21;;10220:768;10244:10;:17;10240:1;:21;10220:768;;;10286:13;;10327:1;;10286:10;;10297:1;;10286:13;;;;;;:::i;:::-;;;;;;;:30;;;-1:-1:-1;;;;;10286:43:8;;;10282:696;;10467:10;10478:1;10467:13;;;;;;;;:::i;:::-;;;;;;;:18;;;10443:13;:18;;;10462:1;10443:21;;;;;;;;:::i;:::-;;;;;;:42;;;;10282:696;;;10528:8;10537:13;10528:23;;;;;;;;:::i;:::-;;;;;;;10524:389;;;10603:4;10575:13;:22;;;10598:1;10575:25;;;;;;;;:::i;:::-;;;;;;:32;;;;;;;;;;;10653:9;10663:13;10653:24;;;;;;;;:::i;:::-;;;;;;;10629:13;:18;;;10648:1;10629:21;;;;;;;;:::i;:::-;;;;;;:48;;;;10524:389;;;10796:10;10807:1;10796:13;;;;;;;;:::i;:::-;;;;;;;:30;;;10828:9;10838:13;10828:24;;;;;;;;:::i;:::-;;;;;;;10854:10;10865:1;10854:13;;;;;;;;:::i;:::-;;;;;;;:18;;;10748:146;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;10748:146:8;;;;;;;-1:-1:-1;;;;;10748:146:8;;;;;;;;;;;10724:13;:18;;;10743:1;10724:21;;;;;;;;:::i;:::-;;;;;;:170;;;;10524:389;10946:17;:13;10962:1;10946:17;:::i;:::-;10930:33;;10282:696;10263:3;;10220:768;;;;11006:25;11017:13;11006:10;:25::i;:::-;11033:13;:22;;;11057:13;:22;;;11081:13;:22;;;10998:106;;;;;;;;;;;;;9310:1801;;;;;;;;;;:::o;6712:894::-;6892:13;6907:7;6916;6925;6944:26;6984:19;6973:41;;;;;;;;;;;;:::i;:::-;6944:70;;7026:24;7052:16;7072:28;:12;:26;:28::i;:::-;7025:75;;;;7111:24;7173:8;7138:44;;;;;;16673:25:34;;16661:2;16646:18;;16527:177;7138:44:8;;;;-1:-1:-1;;7138:44:8;;;;;;;;;;;;;;;-1:-1:-1;;;;;7138:44:8;-1:-1:-1;;;7138:44:8;;;7216:48;;7138:44;;-1:-1:-1;;;7216:48:8;;7227:12;;7241:22;;7216:48;;:::i;:::-;;;;;;;;;;;;;7192:72;;7275:25;7302:23;7341:4;-1:-1:-1;;;;;7341:19:8;;7361:11;7374;7387:8;7397:29;;;7428:8;7341:96;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;7341:96:8;;;;;;;;;;;;:::i;:::-;7274:163;;;;7448:23;7485:12;7474:35;;;;;;;;;;;;:::i;:::-;7528:12;;;;-1:-1:-1;7583:15:8;;-1:-1:-1;6712:894:8;;-1:-1:-1;;;;;;;;;;6712:894:8:o;1796:162:0:-;1684:7;1710:6;-1:-1:-1;;;;;1710:6:0;735:10:2;1855:23:0;1851:101;;1901:40;;-1:-1:-1;;;1901:40:0;;735:10:2;1901:40:0;;;9996:51:34;9969:18;;1901:40:0;9839:214:34;2912:187:0;2985:16;3004:6;;-1:-1:-1;;;;;3020:17:0;;;-1:-1:-1;;;;;;3020:17:0;;;;;;3052:40;;3004:6;;;;;;;3052:40;;2985:16;3052:40;2975:124;2912:187;:::o;4500:728:8:-;4703:22;4727:23;4763:28;4794:19;4817:18;4830:4;;4817:12;:18::i;:::-;4762:73;;-1:-1:-1;4762:73:8;;-1:-1:-1;4762:73:8;;-1:-1:-1;;;;;;;4894:29:8;;4890:85;;4946:18;;-1:-1:-1;;;4946:18:8;;;;;;;;;;;4890:85;5064:147;;;;;;;;;;;;;;;;;;;;;;;;;5003:16;;;;5040:181;;5064:147;;;5095:4;;;;;;5064:147;;5095:4;;;;5064:147;;;;;;;;;-1:-1:-1;;;5064:147:8;;;-1:-1:-1;5064:147:8;;;;;;;;;;;;-1:-1:-1;;;;;;5064:147:8;;;;;;;;;;;;;-1:-1:-1;;;;;5064:147:8;;;;;;;;;;;;5185:11;;5064:147;;;;;-1:-1:-1;;;;;5174:23:8;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5174:23:8;-1:-1:-1;5064:147:8;;5040:10;:181::i;:::-;5030:191;;4752:476;;;4500:728;;;;;;;;;:::o;14283:2128::-;14365:7;;;14448:21;;;14444:91;;-1:-1:-1;14501:1:8;;-1:-1:-1;14501:1:8;;-1:-1:-1;14517:6:8;14485:39;;14444:91;14545:19;14581:4;;14586:6;14581:12;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;14624:1:8;14609:16;;;14605:86;;-1:-1:-1;14657:1:8;;-1:-1:-1;14657:1:8;;-1:-1:-1;14673:6:8;;-1:-1:-1;14641:39:8;;14605:86;14788:4;14761:20;14770:11;14761:6;:20;:::i;:::-;:24;;14784:1;14761:24;:::i;:::-;:38;14757:108;;;-1:-1:-1;14831:1:8;;-1:-1:-1;14831:1:8;;-1:-1:-1;14847:6:8;;-1:-1:-1;14815:39:8;;14757:108;14875:17;14895:20;14904:11;14895:6;:20;:::i;:::-;:24;;14918:1;14895:24;:::i;:::-;14875:44;;14929:17;15027:11;15042:2;15027:17;:45;;;;-1:-1:-1;15048:4:8;;15053:10;:6;15062:1;15053:10;:::i;:::-;15048:16;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;15048:24:8;;15068:4;15048:24;;;15027:45;:76;;;;-1:-1:-1;15076:4:8;;15081:13;15093:1;15081:9;:13;:::i;:::-;15076:19;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;15076:27:8;;15099:4;15076:27;;;15027:76;14956:1068;;;15192:22;15223:4;;15228:10;:6;15237:1;15228:10;:::i;:::-;15223:30;15239:13;15251:1;15239:9;:13;:::i;:::-;15223:30;;;;;;;:::i;:::-;15192:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;15272:16:8;;15192:62;;-1:-1:-1;;15292:2:8;15272:22;;;;-1:-1:-1;15268:64:8;;15303:29;;-1:-1:-1;;;15303:29:8;;;;;;;;;;;15268:64;15405:9;15400:414;15424:2;15420:1;:6;15400:414;;;15451:11;15465:9;15475:1;15465:12;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;15465:12:8;;-1:-1:-1;;;;15522:12:8;;;;;:28;;-1:-1:-1;;;;;;;;;;15538:12:8;;;;15522:28;15520:31;:97;;;;-1:-1:-1;;;;;;;;;;15588:12:8;;;;;;:28;;-1:-1:-1;;;;;;;;;;15604:12:8;;;;15588:28;15586:31;15520:97;:163;;;;-1:-1:-1;;;;;;;;;;15654:12:8;;;;;;:28;;-1:-1:-1;;;;;;;;;;15670:12:8;;;;15654:28;15652:31;15520:163;15495:305;;;15731:50;;-1:-1:-1;;;15731:50:8;;24317:2:34;15731:50:8;;;24299:21:34;24356:2;24336:18;;;24329:30;24395:34;24375:18;;;24368:62;-1:-1:-1;;;24446:18:34;;;24439:38;24494:19;;15731:50:8;24115:404:34;15495:305:8;-1:-1:-1;15428:3:8;;15400:414;;;-1:-1:-1;15898:35:8;:9;15927:1;15930:2;15898:28;:35::i;:::-;-1:-1:-1;15883:50:8;-1:-1:-1;14956:1068:8;;-1:-1:-1;14956:1068:8;;15986:4;;15991:10;:6;16000:1;15991:10;:::i;:::-;15986:26;;16002:9;;15986:26;;:::i;:::-;15976:37;;;;;;;:::i;:::-;;;;;;;;15964:49;;14956:1068;16034:22;16058:18;16078:20;16102:29;16115:4;;16121:9;16102:12;:29::i;:::-;16033:98;;;;;;16141:12;16183:10;16195:9;16166:39;;;;;;;;24963:19:34;;;25007:2;24998:12;;24991:28;25044:2;25035:12;;24806:247;16166:39:8;;;;-1:-1:-1;;16166:39:8;;;;;;;;;;16156:50;;16166:39;16156:50;;;;-1:-1:-1;;;16235:23:8;;;;;16673:25:34;;;16156:50:8;-1:-1:-1;16216:16:8;;-1:-1:-1;;;;;16235:8:8;:17;;;;16646:18:34;;16235:23:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16216:42;-1:-1:-1;;;;;;16272:22:8;;;16268:84;;16318:8;-1:-1:-1;16328:4:8;-1:-1:-1;16334:6:8;;-1:-1:-1;16310:31:8;;-1:-1:-1;;;;;;16310:31:8;16268:84;-1:-1:-1;16369:14:8;;-1:-1:-1;16385:4:8;;-1:-1:-1;16391:12:8;;-1:-1:-1;;;;;14283:2128:8;;;;;;;;:::o;818:1419:20:-;894:7;;1011:6;1028:319;1049:4;:11;1035;:25;1028:319;;;1076:17;1107;1163:28;1173:4;1179:11;1163:9;:28::i;:::-;1138:53;;-1:-1:-1;1138:53:20;-1:-1:-1;1138:53:20;1206:67;;1253:5;;;;1206:67;1287:12;;;;:::i;:::-;;;;1327:9;1313:23;;1062:285;;1028:319;;;1395:23;1435:10;-1:-1:-1;;;;;1421:25:20;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1421:25:20;-1:-1:-1;1395:51:20;-1:-1:-1;1480:6:20;1456:21;1524:451;1547:4;:11;1531:13;:27;1524:451;;;1574:17;1605;1661:30;1671:4;1677:13;1661:9;:30::i;:::-;1636:55;;-1:-1:-1;1636:55:20;-1:-1:-1;1636:55:20;1706:159;;1792:1;1778:4;:11;:15;;;;:::i;:::-;1761:13;:32;1753:74;;;;-1:-1:-1;;;1753:74:20;;25656:2:34;1753:74:20;;;25638:21:34;25695:2;25675:18;;;25668:30;25734:31;25714:18;;;25707:59;25783:18;;1753:74:20;25454:353:34;1753:74:20;1845:5;;;;1706:159;1895:9;1879:6;1886:5;1879:13;;;;;;;;:::i;:::-;;;;;;;;;;:25;1918:7;;;;:::i;:::-;;;;1955:9;1939:25;;1560:415;;1524:451;;;2040:12;2075:134;2082:14;;2075:134;;2112:12;;;;:::i;:::-;;;;2172:4;2178:6;2185:10;2178:18;;;;;;;;:::i;:::-;;;;;;;2155:42;;;;;;;;24963:19:34;;;25007:2;24998:12;;24991:28;25044:2;25035:12;;24806:247;2155:42:20;;;;;;;;;;;;;2145:53;;;;;;2138:60;;2075:134;;;2226:4;818:1419;-1:-1:-1;;;;;;;;818:1419:20:o;16750:2582:8:-;16880:18;;;;:25;16929:22;;;;:29;16829:22;;16880:25;16919:39;;16915:75;;16967:23;;-1:-1:-1;;;16967:23:8;;;;;;;;;;;16915:75;17001:21;;17109:6;-1:-1:-1;;;;;17080:36:8;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17080:36:8;;;;;;;;;;;;;;;;;17036:80;;17126:43;17202:6;-1:-1:-1;;;;;17172:37:8;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;17172:37:8;;;;;;;;;;;;;;;;17126:83;;17241:6;-1:-1:-1;;;;;17229:19:8;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;17276:18:8;;:25;17364:22;;;;17219:29;;-1:-1:-1;17276:30:8;;17258:15;;17343:44;;:20;:44::i;:::-;17316:71;;17402:13;:24;;;:48;;;;;17431:19;17430:20;17402:48;17398:116;;;17473:30;;-1:-1:-1;;;17473:30:8;;;;;;;;;;;17398:116;17529:9;17524:1151;17548:6;17544:1;:10;17524:1151;;;17575:17;17595:13;:18;;;17614:1;17595:21;;;;;;;;:::i;:::-;;;;;;;17575:41;;17630:12;17645:13;:22;;;17668:1;17645:25;;;;;;;;:::i;:::-;;;;;;;17630:40;;17688:7;17684:89;;;17728:4;17715:7;17723:1;17715:10;;;;;;;;:::i;:::-;;;;;;:17;;;;17750:8;;;;17684:89;17791:10;17790:11;:34;;;;;17805:19;17790:34;17786:149;;;17894:18;;17851:69;;;;17894:18;17914:4;;17851:69;;;:::i;:::-;;;;-1:-1:-1;;17851:69:8;;;;;;;;;;;;;;-1:-1:-1;;;;;17851:69:8;-1:-1:-1;;;17851:69:8;;;;-1:-1:-1;17786:149:8;17949:13;17964:23;17989:40;18031:12;18063:63;18097:13;:22;;;18121:4;18063:33;:63::i;:::-;17948:178;;;;;;;;18145:8;18141:227;;;18211:10;18200:48;;;;;;;;;;;;:::i;:::-;18173:9;18183:13;18173:24;;;;;;;;:::i;:::-;;;;;;:75;;;;18282:9;18266:10;18277:1;18266:13;;;;;;;;:::i;:::-;;;;;;;;;;:25;18309:18;18326:1;18309:18;;:::i;:::-;;;18345:8;;;;;;;;18141:227;18386:7;:30;;;;;18397:19;18386:30;18382:190;;;18537:10;18526:31;;;;;;;;;;;;:::i;:::-;18513:44;;18382:190;18598:10;18585:7;18593:1;18585:10;;;;;;;;:::i;:::-;;;;;;:23;;;;18643:13;:18;;;18662:1;18643:21;;;;;;;;:::i;:::-;;;;;;;18622:10;18633:1;18622:13;;;;;;;;:::i;:::-;;;;;;;:18;;:42;;;;17561:1114;;;;;;17524:1151;17556:3;;17524:1151;;;;18689:13;18706:1;18689:18;18685:63;;18723:14;;;;;;16750:2582;;;:::o;18685:63::-;18849:13;18838:9;18831:32;18926:4;18945:13;:22;;;19004:27;;;19033:9;18981:62;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;18981:62:8;;;;;;;-1:-1:-1;;;;;18981:62:8;;;;;;;;;;;19057:13;:30;;;19129:13;:24;;;19171:13;:22;;;19211:13;:22;;;19251:13;:22;;;19291:10;19101:214;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;19101:214:8;;;;;;;;;;-1:-1:-1;;;18890:435:8;;;;;;;;;;;:::i;184:1219:23:-;390:16;;250:20;;272:12;;;;358:4;;436:10;390:16;445:1;436:10;:::i;:::-;-1:-1:-1;;;;;426:21:23;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;426:21:23;-1:-1:-1;416:31:23;-1:-1:-1;464:1:23;;-1:-1:-1;479:11:23;;;475:92;;519:1;506:14;;:7;514:1;506:10;;;;;;;;:::i;:::-;;;;:14;-1:-1:-1;;;;;506:14:23;;;;;;;;;534:22;;;184:1219;;;:::o;475:92::-;-1:-1:-1;;742:10:23;;725:502;789:9;799:1;789:12;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;789:12:23;-1:-1:-1;;;789:19:23;785:353;;856:11;849:19;;832:7;840:1;844;840:5;832:14;;;;;;;;:::i;:::-;;;;:36;-1:-1:-1;;;;;832:36:23;;;;;;;;-1:-1:-1;924:4:23;930:36;:9;951:1;947:5;;930:36;;;:16;:36::i;:::-;907:60;;;;;;24963:19:34;;;;24998:12;;24991:28;25035:12;;907:60:23;;;;;;;;;;;;897:71;;;;;;890:78;;1004:1;990:15;;785:353;;;1067:1;1052:16;;;;1107:9;1117:1;1107:12;;;;;;;;:::i;:::-;;;;;;;;;1090:7;1098:1;1102;1098:5;1090:14;;;;;;;;:::i;:::-;;;;:29;-1:-1:-1;;;;;1090:29:23;;;;;;;;;785:353;1155:58;;1189:5;1155:58;-1:-1:-1;;762:3:23;725:502;;;-1:-1:-1;1281:4:23;1287:32;:9;1304:1;1287:32;;;:16;:32::i;:::-;1264:56;;;;;;24963:19:34;;;;24998:12;;24991:28;25035:12;;1264:56:23;;;;;;;;;;;;1254:67;;;;;;1247:74;;1352:11;1345:19;;1332:7;1340:1;1332:10;;;;;;;;:::i;353:1693:21:-;476:9;;535:1;518:13;528:3;518:7;:13;:::i;:::-;517:19;;;;:::i;:::-;:24;513:47;;-1:-1:-1;554:5:21;543:17;;513:47;581:7;574:3;:14;;:38;;;;602:3;:10;592:7;:20;574:38;570:70;;;-1:-1:-1;630:1:21;;-1:-1:-1;630:1:21;614:26;;570:70;659:4;651:12;;798:3;792:10;783:7;780:23;777:43;;;816:1;813;806:12;777:43;834:626;;;856:5;940:2;937:1;934:9;929:2;926:1;923:9;919:25;916:114;;;-1:-1:-1;;;976:10:21;;834:626::o;916:114::-;1107:2;1104:1;1101:9;1096:2;1093:1;1090:9;1086:25;1083:123;;;-1:-1:-1;;;1143:19:21;;834:626::o;1083:123::-;1284:3;1281:1;1278:10;1273:2;1270:1;1267:9;1263:26;1260:124;;;-1:-1:-1;;;1321:19:21;;834:626::o;1260:124::-;-1:-1:-1;1442:4:21;;834:626;-1:-1:-1;834:626:21:o;:::-;1494:2;1489:3;1485:12;1525:3;1510:520;1537:7;1534:1;1531:14;1510:520;;;1596:35;1626:1;1621:3;1617:11;1611:18;1608:1;1603:27;1596:35;:::i;:::-;1661:43;1698:1;1695;1691:9;1686:3;1682:19;1676:26;1673:1;1668:35;1661:43;:::i;:::-;1827:4;1820:5;1817:15;1810:4;1803:5;1800:15;1797:36;1794:120;;;1865:5;1856:14;;1891:5;;;;1794:120;1954:1;1950:13;;;;1947:24;2000:1;1996:9;;;;1993:23;;;;;1560:1;1553:9;1510:520;;;1514:16;;353:1693;;;;;;:::o;2640:405:20:-;2714:17;2733:14;2773:4;:11;2767:3;:17;2759:60;;;;-1:-1:-1;;;2759:60:20;;32275:2:34;2759:60:20;;;32257:21:34;32314:2;32294:18;;;32287:30;32353:32;32333:18;;;32326:60;32403:18;;2759:60:20;32073:354:34;2759:60:20;2829:11;2857:4;2862:3;2857:9;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;2882:7:20;;2878:129;;2917:26;2924:4;2930:7;:3;2936:1;2930:7;:::i;:::-;2939:3;2917:6;:26::i;:::-;2905:38;;2878:129;;;2994:1;;-1:-1:-1;2878:129:20;3025:9;3031:3;3025;:9;:::i;:::-;:13;;3037:1;3025:13;:::i;:::-;3016:22;;2749:296;2640:405;;;;;:::o;16417:327:8:-;16508:97;;-1:-1:-1;;;16508:97:8;;-1:-1:-1;;;16508:97:8;;;32576:52:34;16488:4:8;;-1:-1:-1;;;;;16508:47:8;;;;;16561:6;;32549:18:34;;16508:97:8;;;;;;;;;;;;;;;;;;;-1:-1:-1;16508:97:8;;;;;;;;-1:-1:-1;;16508:97:8;;;;;;;;;;;;:::i;:::-;;;16504:234;;-1:-1:-1;16722:5:8;;16417:327;-1:-1:-1;16417:327:8:o;11835:1712::-;-1:-1:-1;;;;;;;;;11960:13:8;-1:-1:-1;;;11975:23:8;-1:-1:-1;;;;;;11960:13:8;;12042:11;12078:59;12123:6;12132:4;12078:36;:59::i;:::-;12069:68;-1:-1:-1;1109:16:22;12207:111:8;;;;12241:5;12248:41;12281:1;12284:4;12248:32;:41::i;:::-;12233:74;;-1:-1:-1;12233:74:8;-1:-1:-1;12302:4:8;;-1:-1:-1;12233:74:8;;-1:-1:-1;12233:74:8;12207:111;12359:1;12351:4;:9;12347:1194;;12376:20;12399:38;12432:1;12435;12399:32;:38::i;:::-;12376:61;-1:-1:-1;12543:23:8;12569:45;12602:1;12605:8;12602:1;12605:4;:8;:::i;:::-;12569:32;:45::i;:::-;12543:71;-1:-1:-1;;;;12632:15:8;12639:7;12632:15;:::i;:::-;-1:-1:-1;;;;;;12632:42:8;;12628:903;;12716:21;12759:27;12808:28;12858:30;12910:29;12971:10;12960:65;;;;;;;;;;;;:::i;:::-;12694:331;;;;;;;;;;13064:6;-1:-1:-1;;;;;13047:23:8;:13;-1:-1:-1;;;;;13047:23:8;;13043:327;;13118:67;;;;;;;;13141:13;-1:-1:-1;;;;;13118:67:8;;;;;13156:11;13118:67;;;;13169:15;13118:67;;;13107:79;;;;;;;;:::i;:::-;;;;-1:-1:-1;;13107:79:8;;;;;;13220:66;;;;;;-1:-1:-1;;;;;;13220:66:8;;;;;13107:79;13220:66;;;;;;13316:4;;-1:-1:-1;13107:79:8;;-1:-1:-1;13107:79:8;-1:-1:-1;;;;13308:43:8;;-1:-1:-1;;;;;;13308:43:8;13043:327;12676:708;;;;;12628:903;;;13434:7;13443:10;13421:33;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;13421:33:8;;;;;;;;;13480:5;;-1:-1:-1;13421:33:8;-1:-1:-1;13480:5:8;;-1:-1:-1;13472:44:8;;-1:-1:-1;;;13472:44:8;12628:903;12362:1179;;12347:1194;12059:1488;11835:1712;;;;;;;:::o;343:244:20:-;477:11;;430;;461:12;470:3;461:6;:12;:::i;:::-;:27;;453:36;;;;;;-1:-1:-1;539:26:20;;553:2;539:26;529:42;;343:244::o;533:370:22:-;619:12;740:6;728:19;718:47;;761:1;758;751:12;718:47;885:1;882;875:4;869:11;864:2;858:4;854:13;846:6;839:5;828:59;817:70;533:370;-1:-1:-1;;;533:370:22:o;1432:365::-;1511:17;1557:6;-1:-1:-1;;;;;1547:17:22;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1547:17:22;;1540:24;;1689:16;1680:6;1672;1668:19;1665:41;1662:61;;;1719:1;1716;1709:12;1662:61;1774:6;1766;1761:2;1755:4;1751:13;1736:45;1432:365;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:131:34;-1:-1:-1;;;;;;88:32:34;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;:::-;384:5;150:245;-1:-1:-1;;;150:245:34:o;592:347::-;643:8;653:6;707:3;700:4;692:6;688:17;684:27;674:55;;725:1;722;715:12;674:55;-1:-1:-1;748:20:34;;-1:-1:-1;;;;;780:30:34;;777:50;;;823:1;820;813:12;777:50;860:4;852:6;848:17;836:29;;912:3;905:4;896:6;888;884:19;880:30;877:39;874:59;;;929:1;926;919:12;874:59;592:347;;;;;:::o;944:127::-;1005:10;1000:3;996:20;993:1;986:31;1036:4;1033:1;1026:15;1060:4;1057:1;1050:15;1076:251;1148:2;1142:9;;;1178:15;;-1:-1:-1;;;;;1208:34:34;;1244:22;;;1205:62;1202:88;;;1270:18;;:::i;:::-;1306:2;1299:22;1076:251;:::o;1332:253::-;1404:2;1398:9;1446:4;1434:17;;-1:-1:-1;;;;;1466:34:34;;1502:22;;;1463:62;1460:88;;;1528:18;;:::i;1590:275::-;1661:2;1655:9;1726:2;1707:13;;-1:-1:-1;;1703:27:34;1691:40;;-1:-1:-1;;;;;1746:34:34;;1782:22;;;1743:62;1740:88;;;1808:18;;:::i;:::-;1844:2;1837:22;1590:275;;-1:-1:-1;1590:275:34:o;1870:186::-;1918:4;-1:-1:-1;;;;;1943:6:34;1940:30;1937:56;;;1973:18;;:::i;:::-;-1:-1:-1;2039:2:34;2018:15;-1:-1:-1;;2014:29:34;2045:4;2010:40;;1870:186::o;2061:336::-;2125:5;2154:52;2170:35;2198:6;2170:35;:::i;:::-;2154:52;:::i;:::-;2145:61;;2229:6;2222:5;2215:21;2269:3;2260:6;2255:3;2251:16;2248:25;2245:45;;;2286:1;2283;2276:12;2245:45;2335:6;2330:3;2323:4;2316:5;2312:16;2299:43;2389:1;2382:4;2373:6;2366:5;2362:18;2358:29;2351:40;2061:336;;;;;:::o;2402:220::-;2444:5;2497:3;2490:4;2482:6;2478:17;2474:27;2464:55;;2515:1;2512;2505:12;2464:55;2537:79;2612:3;2603:6;2590:20;2583:4;2575:6;2571:17;2537:79;:::i;2627:182::-;2686:4;-1:-1:-1;;;;;2711:6:34;2708:30;2705:56;;;2741:18;;:::i;:::-;-1:-1:-1;2786:1:34;2782:14;2798:4;2778:25;;2627:182::o;2814:956::-;2867:5;2920:3;2913:4;2905:6;2901:17;2897:27;2887:55;;2938:1;2935;2928:12;2887:55;2978:6;2965:20;3005:63;3021:46;3060:6;3021:46;:::i;3005:63::-;3092:3;3116:6;3111:3;3104:19;3148:4;3143:3;3139:14;3132:21;;3209:4;3199:6;3196:1;3192:14;3184:6;3180:27;3176:38;3162:52;;3237:3;3229:6;3226:15;3223:35;;;3254:1;3251;3244:12;3223:35;3290:4;3282:6;3278:17;3304:435;3320:6;3315:3;3312:15;3304:435;;;3408:3;3395:17;-1:-1:-1;;;;;3431:11:34;3428:35;3425:55;;;3476:1;3473;3466:12;3425:55;3503:24;;3562:2;3554:11;;3550:21;-1:-1:-1;3540:49:34;;3585:1;3582;3575:12;3540:49;3614:80;3690:3;3682:4;3678:2;3674:13;3661:27;3656:2;3652;3648:11;3614:80;:::i;:::-;3602:93;;-1:-1:-1;3724:4:34;3715:14;;;;3337;3304:435;;;-1:-1:-1;3757:7:34;2814:956;-1:-1:-1;;;;;2814:956:34:o;3775:874::-;3907:6;3915;3923;3931;3984:2;3972:9;3963:7;3959:23;3955:32;3952:52;;;4000:1;3997;3990:12;3952:52;4040:9;4027:23;-1:-1:-1;;;;;4065:6:34;4062:30;4059:50;;;4105:1;4102;4095:12;4059:50;4144:58;4194:7;4185:6;4174:9;4170:22;4144:58;:::i;:::-;4221:8;;-1:-1:-1;4118:84:34;-1:-1:-1;;4309:2:34;4294:18;;4281:32;-1:-1:-1;;;;;4325:32:34;;4322:52;;;4370:1;4367;4360:12;4322:52;4393:51;4436:7;4425:8;4414:9;4410:24;4393:51;:::i;:::-;4383:61;;;4497:2;4486:9;4482:18;4469:32;-1:-1:-1;;;;;4516:8:34;4513:32;4510:52;;;4558:1;4555;4548:12;4510:52;4581:62;4635:7;4624:8;4613:9;4609:24;4581:62;:::i;:::-;4571:72;;;3775:874;;;;;;;:::o;4654:299::-;4706:3;4744:5;4738:12;4771:6;4766:3;4759:19;4827:6;4820:4;4813:5;4809:16;4802:4;4797:3;4793:14;4787:47;4879:1;4872:4;4863:6;4858:3;4854:16;4850:27;4843:38;4942:4;4935:2;4931:7;4926:2;4918:6;4914:15;4910:29;4905:3;4901:39;4897:50;4890:57;;;4654:299;;;;:::o;4958:325::-;5133:2;5122:9;5115:21;5096:4;5153:55;5204:2;5193:9;5189:18;5181:6;5153:55;:::i;:::-;5145:63;;5273:1;5269;5264:3;5260:11;5256:19;5248:6;5244:32;5239:2;5228:9;5224:18;5217:60;4958:325;;;;;:::o;5288:824::-;5340:5;5393:3;5386:4;5378:6;5374:17;5370:27;5360:55;;5411:1;5408;5401:12;5360:55;5451:6;5438:20;5478:63;5494:46;5533:6;5494:46;:::i;5478:63::-;5565:3;5589:6;5584:3;5577:19;5621:4;5616:3;5612:14;5605:21;;5682:4;5672:6;5669:1;5665:14;5657:6;5653:27;5649:38;5635:52;;5710:3;5702:6;5699:15;5696:35;;;5727:1;5724;5717:12;5696:35;5763:4;5755:6;5751:17;5777:304;5793:6;5788:3;5785:15;5777:304;;;5881:3;5868:17;-1:-1:-1;;;;;5904:11:34;5901:35;5898:55;;;5949:1;5946;5939:12;5898:55;5978:58;6032:3;6025:4;6011:11;6003:6;5999:24;5995:35;5978:58;:::i;:::-;5966:71;;-1:-1:-1;6066:4:34;6057:14;;;;5810;5777:304;;6117:658;6230:6;6238;6246;6299:2;6287:9;6278:7;6274:23;6270:32;6267:52;;;6315:1;6312;6305:12;6267:52;6355:9;6342:23;-1:-1:-1;;;;;6380:6:34;6377:30;6374:50;;;6420:1;6417;6410:12;6374:50;6459:58;6509:7;6500:6;6489:9;6485:22;6459:58;:::i;:::-;6536:8;;-1:-1:-1;6433:84:34;-1:-1:-1;;6624:2:34;6609:18;;6596:32;-1:-1:-1;;;;;6640:32:34;;6637:52;;;6685:1;6682;6675:12;6637:52;6708:61;6761:7;6750:8;6739:9;6735:24;6708:61;:::i;:::-;6698:71;;;6117:658;;;;;:::o;6780:895::-;6968:4;7016:2;7005:9;7001:18;7046:2;7035:9;7028:21;7069:6;7104;7098:13;7135:6;7127;7120:22;7173:2;7162:9;7158:18;7151:25;;7235:2;7225:6;7222:1;7218:14;7207:9;7203:30;7199:39;7185:53;;7273:4;7265:6;7261:17;7296:1;7306:269;7320:6;7317:1;7314:13;7306:269;;;7413:2;7409:7;7397:9;7389:6;7385:22;7381:36;7376:3;7369:49;7441:50;7484:6;7475;7469:13;7441:50;:::i;:::-;7431:60;-1:-1:-1;7526:4:34;7551:14;;;;7514:17;;;;;7342:1;7335:9;7306:269;;;-1:-1:-1;;;;;;;;;7636:32:34;;;;7629:4;7614:20;;;;7607:62;;;;-1:-1:-1;7592:6:34;6780:895;-1:-1:-1;6780:895:34:o;7680:712::-;7770:6;7778;7786;7794;7847:2;7835:9;7826:7;7822:23;7818:32;7815:52;;;7863:1;7860;7853:12;7815:52;7903:9;7890:23;-1:-1:-1;;;;;7928:6:34;7925:30;7922:50;;;7968:1;7965;7958:12;7922:50;8007:58;8057:7;8048:6;8037:9;8033:22;8007:58;:::i;:::-;8084:8;;-1:-1:-1;7981:84:34;-1:-1:-1;;8172:2:34;8157:18;;8144:32;-1:-1:-1;;;;;8188:32:34;;8185:52;;;8233:1;8230;8223:12;8185:52;8272:60;8324:7;8313:8;8302:9;8298:24;8272:60;:::i;:::-;7680:712;;;;-1:-1:-1;8351:8:34;-1:-1:-1;;;;7680:712:34:o;8397:523::-;8630:3;8619:9;8612:22;8593:4;8651:56;8702:3;8691:9;8687:19;8679:6;8651:56;:::i;:::-;-1:-1:-1;;;;;8743:32:34;;;8738:2;8723:18;;8716:60;8812:32;;;8807:2;8792:18;;8785:60;-1:-1:-1;8881:32:34;;8876:2;8861:18;;;8854:60;;;;8643:64;8397:523;-1:-1:-1;8397:523:34:o;8925:909::-;9082:6;9090;9098;9106;9159:2;9147:9;9138:7;9134:23;9130:32;9127:52;;;9175:1;9172;9165:12;9127:52;9215:9;9202:23;-1:-1:-1;;;;;9240:6:34;9237:30;9234:50;;;9280:1;9277;9270:12;9234:50;9319:58;9369:7;9360:6;9349:9;9345:22;9319:58;:::i;:::-;9396:8;;-1:-1:-1;9293:84:34;-1:-1:-1;;9484:2:34;9469:18;;9456:32;-1:-1:-1;;;;;9500:32:34;;9497:52;;;9545:1;9542;9535:12;9497:52;9568:61;9621:7;9610:8;9599:9;9595:24;9568:61;:::i;10266:1223::-;10424:6;10432;10440;10448;10456;10464;10517:3;10505:9;10496:7;10492:23;10488:33;10485:53;;;10534:1;10531;10524:12;10485:53;10574:9;10561:23;-1:-1:-1;;;;;10599:6:34;10596:30;10593:50;;;10639:1;10636;10629:12;10593:50;10678:58;10728:7;10719:6;10708:9;10704:22;10678:58;:::i;:::-;10755:8;;-1:-1:-1;10652:84:34;-1:-1:-1;;10843:2:34;10828:18;;10815:32;-1:-1:-1;;;;;10859:32:34;;10856:52;;;10904:1;10901;10894:12;10856:52;10927:51;10970:7;10959:8;10948:9;10944:24;10927:51;:::i;:::-;10917:61;;;11031:2;11020:9;11016:18;11003:32;-1:-1:-1;;;;;11050:8:34;11047:32;11044:52;;;11092:1;11089;11082:12;11044:52;11115:62;11169:7;11158:8;11147:9;11143:24;11115:62;:::i;:::-;11105:72;;;11227:2;11216:9;11212:18;11199:32;11240:30;11264:5;11240:30;:::i;:::-;11289:5;-1:-1:-1;11347:3:34;11332:19;;11319:33;-1:-1:-1;;;;;11364:32:34;;11361:52;;;11409:1;11406;11399:12;11361:52;11432:51;11475:7;11464:8;11453:9;11449:24;11432:51;:::i;:::-;11422:61;;;10266:1223;;;;;;;;:::o;11494:357::-;11588:6;11641:2;11629:9;11620:7;11616:23;11612:32;11609:52;;;11657:1;11654;11647:12;11609:52;11697:9;11684:23;-1:-1:-1;;;;;11722:6:34;11719:30;11716:50;;;11762:1;11759;11752:12;11716:50;11785:60;11837:7;11828:6;11817:9;11813:22;11785:60;:::i;:::-;11775:70;11494:357;-1:-1:-1;;;;11494:357:34:o;11856:623::-;11944:6;11952;11960;12013:2;12001:9;11992:7;11988:23;11984:32;11981:52;;;12029:1;12026;12019:12;11981:52;12069:9;12056:23;-1:-1:-1;;;;;12094:6:34;12091:30;12088:50;;;12134:1;12131;12124:12;12088:50;12173:58;12223:7;12214:6;12203:9;12199:22;12173:58;:::i;:::-;12250:8;;-1:-1:-1;12147:84:34;-1:-1:-1;;12338:2:34;12323:18;;12310:32;-1:-1:-1;;;;;12354:32:34;;12351:52;;;12399:1;12396;12389:12;12351:52;12422:51;12465:7;12454:8;12443:9;12439:24;12422:51;:::i;12484:409::-;12554:6;12562;12615:2;12603:9;12594:7;12590:23;12586:32;12583:52;;;12631:1;12628;12621:12;12583:52;12671:9;12658:23;-1:-1:-1;;;;;12696:6:34;12693:30;12690:50;;;12736:1;12733;12726:12;12690:50;12775:58;12825:7;12816:6;12805:9;12801:22;12775:58;:::i;:::-;12852:8;;12749:84;;-1:-1:-1;12484:409:34;-1:-1:-1;;;;12484:409:34:o;13276:180::-;13335:6;13388:2;13376:9;13367:7;13363:23;13359:32;13356:52;;;13404:1;13401;13394:12;13356:52;-1:-1:-1;13427:23:34;;13276:180;-1:-1:-1;13276:180:34:o;13461:230::-;13610:2;13599:9;13592:21;13573:4;13630:55;13681:2;13670:9;13666:18;13658:6;13630:55;:::i;13696:660::-;13810:6;13818;13826;13879:2;13867:9;13858:7;13854:23;13850:32;13847:52;;;13895:1;13892;13885:12;13847:52;13935:9;13922:23;-1:-1:-1;;;;;13960:6:34;13957:30;13954:50;;;14000:1;13997;13990:12;13954:50;14039:58;14089:7;14080:6;14069:9;14065:22;14039:58;:::i;:::-;14116:8;;-1:-1:-1;14013:84:34;-1:-1:-1;;14204:2:34;14189:18;;14176:32;-1:-1:-1;;;;;14220:32:34;;14217:52;;;14265:1;14262;14255:12;14217:52;14288:62;14342:7;14331:8;14320:9;14316:24;14288:62;:::i;14361:131::-;-1:-1:-1;;;;;14436:31:34;;14426:42;;14416:70;;14482:1;14479;14472:12;14497:247;14556:6;14609:2;14597:9;14588:7;14584:23;14580:32;14577:52;;;14625:1;14622;14615:12;14577:52;14664:9;14651:23;14683:31;14708:5;14683:31;:::i;14749:380::-;14828:1;14824:12;;;;14871;;;14892:61;;14946:4;14938:6;14934:17;14924:27;;14892:61;14999:2;14991:6;14988:14;14968:18;14965:38;14962:161;;15045:10;15040:3;15036:20;15033:1;15026:31;15080:4;15077:1;15070:15;15108:4;15105:1;15098:15;14962:161;;14749:380;;;:::o;15134:514::-;15188:5;15241:3;15234:4;15226:6;15222:17;15218:27;15208:55;;15259:1;15256;15249:12;15208:55;15292:6;15286:13;15331:4;15323:6;15319:17;15360:1;15381:52;15397:35;15425:6;15397:35;:::i;15381:52::-;15370:63;;15458:6;15449:7;15442:23;15498:3;15489:6;15484:3;15480:16;15477:25;15474:45;;;15515:1;15512;15505:12;15474:45;15559:6;15554:3;15547:4;15538:7;15534:18;15528:38;15615:1;15586:20;;;15608:4;15582:31;15575:42;;;;-1:-1:-1;15590:7:34;15134:514;-1:-1:-1;;;15134:514:34:o;15653:473::-;15750:6;15758;15811:2;15799:9;15790:7;15786:23;15782:32;15779:52;;;15827:1;15824;15817:12;15779:52;15860:9;15854:16;-1:-1:-1;;;;;15885:6:34;15882:30;15879:50;;;15925:1;15922;15915:12;15879:50;15948:61;16001:7;15992:6;15981:9;15977:22;15948:61;:::i;:::-;15938:71;;;16052:2;16041:9;16037:18;16031:25;16065:31;16090:5;16065:31;:::i;:::-;16115:5;16105:15;;;15653:473;;;;;:::o;16131:127::-;16192:10;16187:3;16183:20;16180:1;16173:31;16223:4;16220:1;16213:15;16247:4;16244:1;16237:15;16263:259;16341:6;16394:2;16382:9;16373:7;16369:23;16365:32;16362:52;;;16410:1;16407;16400:12;16362:52;16442:9;16436:16;16461:31;16486:5;16461:31;:::i;16709:118::-;16795:5;16788:13;16781:21;16774:5;16771:32;16761:60;;16817:1;16814;16807:12;16832:1215;16956:6;16964;17017:2;17005:9;16996:7;16992:23;16988:32;16985:52;;;17033:1;17030;17023:12;16985:52;17073:9;17060:23;-1:-1:-1;;;;;17098:6:34;17095:30;17092:50;;;17138:1;17135;17128:12;17092:50;17161:22;;17214:4;17206:13;;17202:27;-1:-1:-1;17192:55:34;;17243:1;17240;17233:12;17192:55;17283:2;17270:16;17306:63;17322:46;17361:6;17322:46;:::i;17306:63::-;17391:3;17415:6;17410:3;17403:19;17447:4;17442:3;17438:14;17431:21;;17504:4;17494:6;17491:1;17487:14;17483:2;17479:23;17475:34;17461:48;;17532:7;17524:6;17521:19;17518:39;;;17553:1;17550;17543:12;17518:39;17585:4;17581:2;17577:13;17566:24;;17599:218;17615:6;17610:3;17607:15;17599:218;;;17697:3;17684:17;17714:28;17736:5;17714:28;:::i;:::-;17755:18;;17802:4;17632:14;;;;17793;;;;17599:218;;;17836:5;-1:-1:-1;;;;17894:4:34;17879:20;;17866:34;-1:-1:-1;;;;;17912:32:34;;17909:52;;;17957:1;17954;17947:12;17909:52;17980:61;18033:7;18022:8;18011:9;18007:24;17980:61;:::i;18052:2289::-;18262:6;18270;18278;18286;18294;18347:3;18335:9;18326:7;18322:23;18318:33;18315:53;;;18364:1;18361;18354:12;18315:53;18403:9;18390:23;18422:28;18444:5;18422:28;:::i;:::-;18469:5;-1:-1:-1;18526:2:34;18511:18;;18498:32;18539:33;18498:32;18539:33;:::i;:::-;18591:7;-1:-1:-1;18649:2:34;18634:18;;18621:32;-1:-1:-1;;;;;18665:30:34;;18662:50;;;18708:1;18705;18698:12;18662:50;18731:60;18783:7;18774:6;18763:9;18759:22;18731:60;:::i;:::-;18721:70;;;18844:2;18833:9;18829:18;18816:32;-1:-1:-1;;;;;18863:8:34;18860:32;18857:52;;;18905:1;18902;18895:12;18857:52;18928:51;18971:7;18960:8;18949:9;18945:24;18928:51;:::i;:::-;18918:61;;;19032:3;19021:9;19017:19;19004:33;-1:-1:-1;;;;;19052:8:34;19049:32;19046:52;;;19094:1;19091;19084:12;19046:52;19117:24;;19172:4;19164:13;;19160:27;-1:-1:-1;19150:55:34;;19201:1;19198;19191:12;19150:55;19241:2;19228:16;19264:63;19280:46;19319:6;19280:46;:::i;19264:63::-;19349:3;19373:6;19368:3;19361:19;19405:2;19400:3;19396:12;19389:19;;19460:2;19450:6;19447:1;19443:14;19439:2;19435:23;19431:32;19417:46;;19486:7;19478:6;19475:19;19472:39;;;19507:1;19504;19497:12;19472:39;19539:2;19535;19531:11;19551:760;19567:6;19562:3;19559:15;19551:760;;;19653:3;19640:17;-1:-1:-1;;;;;19676:11:34;19673:35;19670:55;;;19721:1;19718;19711:12;19670:55;19748:20;;19820:2;19792:16;;;-1:-1:-1;;19788:30:34;19784:39;19781:59;;;19836:1;19833;19826:12;19781:59;19868:22;;:::i;:::-;19939:2;19935;19931:11;19918:25;19956:32;19980:7;19956:32;:::i;:::-;20001:24;;20075:2;20067:11;;20054:25;-1:-1:-1;;;;;20095:32:34;;20092:52;;;20140:1;20137;20130:12;20092:52;20182:53;20227:7;20222:2;20211:8;20207:2;20203:17;20199:26;20182:53;:::i;:::-;20177:2;20168:7;20164:16;20157:79;;20261:7;20256:3;20249:20;;;20298:2;20293:3;20289:12;20282:19;;19593:2;19588:3;19584:12;19577:19;;19551:760;;;19555:3;20330:5;20320:15;;;;;;18052:2289;;;;;;;;:::o;20346:399::-;20539:2;20528:9;20521:21;20502:4;20565:55;20616:2;20605:9;20601:18;20593:6;20565:55;:::i;:::-;20668:9;20660:6;20656:22;20651:2;20640:9;20636:18;20629:50;20696:43;20732:6;20724;20696:43;:::i;:::-;20688:51;20346:399;-1:-1:-1;;;;;20346:399:34:o;20750:127::-;20811:10;20806:3;20802:20;20799:1;20792:31;20842:4;20839:1;20832:15;20866:4;20863:1;20856:15;20882:125;20947:9;;;20968:10;;;20965:36;;;20981:18;;:::i;21012:337::-;21092:6;21145:2;21133:9;21124:7;21120:23;21116:32;21113:52;;;21161:1;21158;21151:12;21113:52;21194:9;21188:16;-1:-1:-1;;;;;21219:6:34;21216:30;21213:50;;;21259:1;21256;21249:12;21213:50;21282:61;21335:7;21326:6;21315:9;21311:22;21282:61;:::i;21686:589::-;21738:3;21769;21801:5;21795:12;21828:6;21823:3;21816:19;21860:4;21855:3;21851:14;21844:21;;21918:4;21908:6;21905:1;21901:14;21894:5;21890:26;21886:37;21957:4;21950:5;21946:16;21980:1;21990:259;22004:6;22001:1;21998:13;21990:259;;;22091:2;22087:7;22079:5;22073:4;22069:16;22065:30;22060:3;22053:43;22117:48;22160:4;22151:6;22145:13;22117:48;:::i;:::-;22200:4;22225:14;;;;22109:56;;-1:-1:-1;22188:17:34;;;;;22026:1;22019:9;21990:259;;;-1:-1:-1;22265:4:34;;21686:589;-1:-1:-1;;;;;;21686:589:34:o;22280:892::-;22643:3;22632:9;22625:22;22606:4;22670:56;22721:3;22710:9;22706:19;22698:6;22670:56;:::i;:::-;22774:9;22766:6;22762:22;22757:2;22746:9;22742:18;22735:50;22808:43;22844:6;22836;22808:43;:::i;:::-;22794:57;;22899:9;22891:6;22887:22;22882:2;22871:9;22867:18;22860:50;22933:43;22969:6;22961;22933:43;:::i;:::-;-1:-1:-1;;;;;;23012:33:34;;23007:2;22992:18;;22985:61;23083:22;;;23077:3;23062:19;;23055:51;22919:57;-1:-1:-1;23123:43:34;22919:57;23151:6;23123:43;:::i;23646:128::-;23713:9;;;23734:11;;;23731:37;;;23748:18;;:::i;23779:331::-;23884:9;23895;23937:8;23925:10;23922:24;23919:44;;;23959:1;23956;23949:12;23919:44;23988:6;23978:8;23975:20;23972:40;;;24008:1;24005;23998:12;23972:40;-1:-1:-1;;24034:23:34;;;24079:25;;;;;-1:-1:-1;23779:331:34:o;24524:277::-;24713:6;24705;24700:3;24687:33;24669:3;24739:16;;24764:13;;;24739:16;24524:277;-1:-1:-1;24524:277:34:o;25314:135::-;25353:3;25374:17;;;25371:43;;25394:18;;:::i;:::-;-1:-1:-1;25441:1:34;25430:13;;25314:135::o;25812:136::-;25851:3;25879:5;25869:39;;25888:18;;:::i;:::-;-1:-1:-1;;;25924:18:34;;25812:136::o;25953:834::-;26017:5;26070:3;26063:4;26055:6;26051:17;26047:27;26037:55;;26088:1;26085;26078:12;26037:55;26121:6;26115:13;26148:63;26164:46;26203:6;26164:46;:::i;26148:63::-;26235:3;26259:6;26254:3;26247:19;26291:4;26286:3;26282:14;26275:21;;26352:4;26342:6;26339:1;26335:14;26327:6;26323:27;26319:38;26305:52;;26380:3;26372:6;26369:15;26366:35;;;26397:1;26394;26387:12;26366:35;26433:4;26425:6;26421:17;26447:309;26463:6;26458:3;26455:15;26447:309;;;26544:3;26538:10;-1:-1:-1;;;;;26567:11:34;26564:35;26561:55;;;26612:1;26609;26602:12;26561:55;26641:70;26707:3;26700:4;26686:11;26678:6;26674:24;26670:35;26641:70;:::i;:::-;26629:83;;-1:-1:-1;26741:4:34;26732:14;;;;26480;26447:309;;26792:954;26902:6;26955:2;26943:9;26934:7;26930:23;26926:32;26923:52;;;26971:1;26968;26961:12;26923:52;27004:9;26998:16;-1:-1:-1;;;;;27029:6:34;27026:30;27023:50;;;27069:1;27066;27059:12;27023:50;27092:22;;27148:4;27130:16;;;27126:27;27123:47;;;27166:1;27163;27156:12;27123:47;27192:22;;:::i;:::-;27244:2;27238:9;27256:33;27281:7;27256:33;:::i;:::-;27298:22;;27359:2;27351:11;;27345:18;-1:-1:-1;;;;;27375:32:34;;27372:52;;;27420:1;27417;27410:12;27372:52;27456:66;27514:7;27503:8;27499:2;27495:17;27456:66;:::i;:::-;27451:2;27444:5;27440:14;27433:90;;27562:2;27558;27554:11;27548:18;-1:-1:-1;;;;;27581:8:34;27578:32;27575:52;;;27623:1;27620;27613:12;27575:52;27659:56;27707:7;27696:8;27692:2;27688:17;27659:56;:::i;:::-;27654:2;27643:14;;27636:80;-1:-1:-1;27647:5:34;26792:954;-1:-1:-1;;;;26792:954:34:o;28092:473::-;28222:1;28218;28213:3;28209:11;28205:19;28197:5;28191:12;28187:38;28182:3;28175:51;28157:3;28272:4;28265:5;28261:16;28255:23;28310:4;28303;28298:3;28294:14;28287:28;28336:57;28387:4;28382:3;28378:14;28364:12;28336:57;:::i;:::-;28324:69;;28441:4;28434:5;28430:16;28424:23;28489:3;28483:4;28479:14;28472:4;28467:3;28463:14;28456:38;28510:49;28554:4;28538:14;28510:49;:::i;28570:865::-;28792:4;28840:2;28829:9;28825:18;28870:2;28859:9;28852:21;28893:6;28928;28922:13;28959:6;28951;28944:22;28997:2;28986:9;28982:18;28975:25;;29059:2;29049:6;29046:1;29042:14;29031:9;29027:30;29023:39;29009:53;;29097:2;29089:6;29085:15;29118:1;29128:278;29142:6;29139:1;29136:13;29128:278;;;29235:2;29231:7;29219:9;29211:6;29207:22;29203:36;29198:3;29191:49;29263:63;29319:6;29310;29304:13;29263:63;:::i;:::-;29253:73;-1:-1:-1;29361:2:34;29384:12;;;;29349:15;;;;;29164:1;29157:9;29128:278;;;-1:-1:-1;29423:6:34;;28570:865;-1:-1:-1;;;;;;28570:865:34:o;29440:1591::-;29902:14;;29895:22;29877:41;;-1:-1:-1;;;;;29954:32:34;;29949:2;29934:18;;29927:60;29974:3;30018:2;30003:18;;29996:31;;;-1:-1:-1;;30050:56:34;;30086:19;;30078:6;30050:56;:::i;:::-;30154:9;30146:6;30142:22;30137:2;30126:9;30122:18;30115:50;30188:43;30224:6;30216;30188:43;:::i;:::-;30174:57;;30280:9;30272:6;30268:22;30262:3;30251:9;30247:19;30240:51;30311:6;30346;30340:13;30377:6;30369;30362:22;30412:2;30404:6;30400:15;30393:22;;30471:2;30461:6;30458:1;30454:14;30446:6;30442:27;30438:36;30509:2;30501:6;30497:15;30530:1;30540:462;30554:6;30551:1;30548:13;30540:462;;;30619:19;;;-1:-1:-1;;30615:33:34;30603:46;;30672:13;;30717:9;;-1:-1:-1;;;;;;30713:36:34;30698:52;;30797:2;30789:11;;;30783:18;30838:2;30821:15;;;30814:27;;;30783:18;30864:58;;30906:15;;30783:18;30864:58;:::i;:::-;30957:2;30980:12;;;;30854:68;;-1:-1:-1;30945:15:34;;;;;-1:-1:-1;30576:1:34;30569:9;30540:462;;;-1:-1:-1;31019:6:34;;29440:1591;-1:-1:-1;;;;;;;;;;;29440:1591:34:o;31036:818::-;-1:-1:-1;;;;;31381:32:34;;31363:51;;31401:3;31445:2;31430:18;;31423:31;;;-1:-1:-1;;31477:56:34;;31513:19;;31505:6;31477:56;:::i;:::-;31581:9;31573:6;31569:22;31564:2;31553:9;31549:18;31542:50;31615:43;31651:6;31643;31615:43;:::i;31859:209::-;31891:1;31917;31907:132;;31961:10;31956:3;31952:20;31949:1;31942:31;31996:4;31993:1;31986:15;32024:4;32021:1;32014:15;31907:132;-1:-1:-1;32053:9:34;;31859:209::o;32639:245::-;32706:6;32759:2;32747:9;32738:7;32734:23;32730:32;32727:52;;;32775:1;32772;32765:12;32727:52;32807:9;32801:16;32826:28;32848:5;32826:28;:::i;32889:376::-;33006:12;;33054:4;33043:16;;33037:23;-1:-1:-1;;;;;;33078:29:34;;;33006:12;33130:1;33119:13;;33116:143;;;-1:-1:-1;;;;;;33191:1:34;33187:14;;;33184:1;33180:22;33176:49;;;33168:58;;33164:85;;-1:-1:-1;33116:143:34;;;32889:376;;;:::o;33270:1080::-;33436:6;33444;33452;33460;33468;33521:3;33509:9;33500:7;33496:23;33492:33;33489:53;;;33538:1;33535;33528:12;33489:53;33570:9;33564:16;33589:31;33614:5;33589:31;:::i;:::-;33688:2;33673:18;;33667:25;33639:5;;-1:-1:-1;;;;;;33704:30:34;;33701:50;;;33747:1;33744;33737:12;33701:50;33770:71;33833:7;33824:6;33813:9;33809:22;33770:71;:::i;:::-;33760:81;;;33887:2;33876:9;33872:18;33866:25;-1:-1:-1;;;;;33906:8:34;33903:32;33900:52;;;33948:1;33945;33938:12;33900:52;33971:63;34026:7;34015:8;34004:9;34000:24;33971:63;:::i;:::-;33961:73;;;34079:2;34068:9;34064:18;34058:25;34092:32;34116:7;34092:32;:::i;:::-;34196:3;34181:19;;34175:26;34143:7;;-1:-1:-1;;;;;;34213:32:34;;34210:52;;;34258:1;34255;34248:12;34210:52;34281:63;34336:7;34325:8;34314:9;34310:24;34281:63;:::i;:::-;34271:73;;;33270:1080;;;;;;;;:::o;34355:303::-;34564:2;34553:9;34546:21;34527:4;34584:68;34648:2;34637:9;34633:18;34625:6;34584:68;:::i;34663:211::-;34704:3;34742:5;34736:12;34786:6;34779:4;34772:5;34768:16;34763:3;34757:36;34848:1;34812:16;;34837:13;;;-1:-1:-1;34812:16:34;;34663:211;-1:-1:-1;34663:211:34:o;34879:261::-;35054:3;35079:55;35104:29;35129:3;35121:6;35104:29;:::i;:::-;35096:6;35079:55;:::i;35271:518::-;35373:2;35368:3;35365:11;35362:421;;;35409:5;35406:1;35399:16;35453:4;35450:1;35440:18;35523:2;35511:10;35507:19;35504:1;35500:27;35494:4;35490:38;35559:4;35547:10;35544:20;35541:47;;;-1:-1:-1;35582:4:34;35541:47;35637:2;35632:3;35628:12;35625:1;35621:20;35615:4;35611:31;35601:41;;35692:81;35710:2;35703:5;35700:13;35692:81;;;35769:1;35755:16;;35736:1;35725:13;35692:81;;;35696:3;;35362:421;35271:518;;;:::o;35965:1299::-;36091:3;36085:10;-1:-1:-1;;;;;36110:6:34;36107:30;36104:56;;;36140:18;;:::i;:::-;36169:97;36259:6;36219:38;36251:4;36245:11;36219:38;:::i;:::-;36213:4;36169:97;:::i;:::-;36315:4;36346:2;36335:14;;36363:1;36358:649;;;;37051:1;37068:6;37065:89;;;-1:-1:-1;37120:19:34;;;37114:26;37065:89;-1:-1:-1;;35922:1:34;35918:11;;;35914:24;35910:29;35900:40;35946:1;35942:11;;;35897:57;37167:81;;36328:930;;36358:649;35218:1;35211:14;;;35255:4;35242:18;;-1:-1:-1;;36394:20:34;;;36512:222;36526:7;36523:1;36520:14;36512:222;;;36608:19;;;36602:26;36587:42;;36715:4;36700:20;;;;36668:1;36656:14;;;;36542:12;36512:222;;;36516:3;36762:6;36753:7;36750:19;36747:201;;;36823:19;;;36817:26;-1:-1:-1;;36906:1:34;36902:14;;;36918:3;36898:24;36894:37;36890:42;36875:58;36860:74;;36747:201;-1:-1:-1;;;;36994:1:34;36978:14;;;36974:22;36961:36;;-1:-1:-1;35965:1299:34:o
Swarm Source
ipfs://c137a2f87a7ea65f6ad0abfc8b464684e8e7a772ce64993bdb3adc0e46ca6958
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.