Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
BlueprintV12
Compiler Version
v0.8.4+commit.c7e474f2
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-11-09 */ //SPDX-License-Identifier: Unlicense pragma solidity 0.8.4; /** * @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 IERC165Upgradeable { /** * @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); } /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } } /** * @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); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal initializer { __ERC165_init_unchained(); } function __ERC165_init_unchained() internal initializer { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } uint256[50] private __gap; } /** * @dev Storage based implementation of the {IERC165} interface. * * Contracts may inherit from this and call {_registerInterface} to declare * their support of an interface. */ abstract contract ERC165StorageUpgradeable is Initializable, ERC165Upgradeable { function __ERC165Storage_init() internal initializer { __ERC165_init_unchained(); __ERC165Storage_init_unchained(); } function __ERC165Storage_init_unchained() internal initializer { } /** * @dev Mapping of interface ids to whether or not it's supported. */ mapping(bytes4 => bool) private _supportedInterfaces; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId]; } /** * @dev Registers the contract as an implementer of the interface defined by * `interfaceId`. Support of the actual ERC165 interface is automatic and * registering its interface id is not required. * * See {IERC165-supportsInterface}. * * Requirements: * * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`). */ function _registerInterface(bytes4 interfaceId) internal virtual { require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); _supportedInterfaces[interfaceId] = true; } uint256[49] private __gap; } abstract contract HasSecondarySaleFees is ERC165StorageUpgradeable { event SecondarySaleFees( uint256 tokenId, address[] recipients, uint256[] bps ); /* * bytes4(keccak256('getFeeBps(uint256)')) == 0x0ebd4c7f * bytes4(keccak256('getFeeRecipients(uint256)')) == 0xb9c4d9fb * * => 0x0ebd4c7f ^ 0xb9c4d9fb == 0xb7799584 */ bytes4 private constant _INTERFACE_ID_FEES = 0xb7799584; function _initialize() public initializer { _registerInterface(_INTERFACE_ID_FEES); } function getFeeRecipients(uint256 id) public view virtual returns (address[] memory); function getFeeBps(uint256 id) public view virtual returns (uint32[] memory); } abstract contract ERC20 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); /*////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string public name; string public symbol; uint8 public immutable decimals; /*////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; mapping(address => uint256) public nonces; /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _name, string memory _symbol, uint8 _decimals ) { name = _name; symbol = _symbol; decimals = _decimals; INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*////////////////////////////////////////////////////////////// ERC20 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 amount) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transfer(address to, uint256 amount) public virtual returns (bool) { balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } /*////////////////////////////////////////////////////////////// EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { address recoveredAddress = ecrecover( keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256( abi.encode( keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ), owner, spender, value, nonces[owner]++, deadline ) ) ) ), v, r, s ); require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 amount) internal virtual { totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); } } /** * @title ISplitMain * @author 0xSplits <[email protected]> */ interface ISplitMain { /** * FUNCTIONS */ function walletImplementation() external returns (address); function createSplit( address[] calldata accounts, uint32[] calldata percentAllocations, uint32 distributorFee, address controller ) external returns (address); function predictImmutableSplitAddress( address[] calldata accounts, uint32[] calldata percentAllocations, uint32 distributorFee ) external view returns (address); function updateSplit( address split, address[] calldata accounts, uint32[] calldata percentAllocations, uint32 distributorFee ) external; function transferControl(address split, address newController) external; function cancelControlTransfer(address split) external; function acceptControl(address split) external; function makeSplitImmutable(address split) external; function distributeETH( address split, address[] calldata accounts, uint32[] calldata percentAllocations, uint32 distributorFee, address distributorAddress ) external; function updateAndDistributeETH( address split, address[] calldata accounts, uint32[] calldata percentAllocations, uint32 distributorFee, address distributorAddress ) external; function distributeERC20( address split, ERC20 token, address[] calldata accounts, uint32[] calldata percentAllocations, uint32 distributorFee, address distributorAddress ) external; function updateAndDistributeERC20( address split, ERC20 token, address[] calldata accounts, uint32[] calldata percentAllocations, uint32 distributorFee, address distributorAddress ) external; function withdraw( address account, uint256 withdrawETH, ERC20[] calldata tokens ) external; /** * EVENTS */ /** @notice emitted after each successful split creation * @param split Address of the created split */ event CreateSplit(address indexed split); /** @notice emitted after each successful split update * @param split Address of the updated split */ event UpdateSplit(address indexed split); /** @notice emitted after each initiated split control transfer * @param split Address of the split control transfer was initiated for * @param newPotentialController Address of the split's new potential controller */ event InitiateControlTransfer( address indexed split, address indexed newPotentialController ); /** @notice emitted after each canceled split control transfer * @param split Address of the split control transfer was canceled for */ event CancelControlTransfer(address indexed split); /** @notice emitted after each successful split control transfer * @param split Address of the split control was transferred for * @param previousController Address of the split's previous controller * @param newController Address of the split's new controller */ event ControlTransfer( address indexed split, address indexed previousController, address indexed newController ); /** @notice emitted after each successful ETH balance split * @param split Address of the split that distributed its balance * @param amount Amount of ETH distributed * @param distributorAddress Address to credit distributor fee to */ event DistributeETH( address indexed split, uint256 amount, address indexed distributorAddress ); /** @notice emitted after each successful ERC20 balance split * @param split Address of the split that distributed its balance * @param token Address of ERC20 distributed * @param amount Amount of ERC20 distributed * @param distributorAddress Address to credit distributor fee to */ event DistributeERC20( address indexed split, ERC20 indexed token, uint256 amount, address indexed distributorAddress ); /** @notice emitted after each successful withdrawal * @param account Address that funds were withdrawn to * @param ethAmount Amount of ETH withdrawn * @param tokens Addresses of ERC20s withdrawn * @param tokenAmounts Amounts of corresponding ERC20s withdrawn */ event Withdrawal( address indexed account, uint256 ethAmount, ERC20[] tokens, uint256[] tokenAmounts ); } /** * @dev Interface used to share common types between AsyncArt Blueprints contracts * @author Ohimire Labs */ interface IBlueprintTypes { /** * @dev Core administrative accounts * @param platform Platform, holder of DEFAULT_ADMIN role * @param minter Minter, holder of MINTER_ROLE * @param asyncSaleFeesRecipient Recipient of primary sale fees going to platform */ struct Admins { address platform; address minter; address asyncSaleFeesRecipient; } /** * @dev Object passed in when preparing blueprint * @param _capacity Number of NFTs in Blueprint * @param _price Price per NFT in Blueprint * @param _erc20Token Address of ERC20 currency required to buy NFTs, can be zero address if expected currency is native gas token * @param _blueprintMetaData Blueprint metadata uri * @param _baseTokenUri Base URI for token, resultant uri for each token is base uri concatenated with token id * @param _merkleroot Root of Merkle tree holding whitelisted accounts * @param _mintAmountArtist Amount of NFTs of Blueprint mintable by artist * @param _mintAmountPlatform Amount of NFTs of Blueprint mintable by platform * @param _maxPurchaseAmount Max number of NFTs purchasable in a single transaction * @param _saleEndTimestamp Timestamp when the sale ends */ struct BlueprintPreparationConfig { uint64 _capacity; uint128 _price; address _erc20Token; string _blueprintMetaData; string _baseTokenUri; bytes32 _merkleroot; uint32 _mintAmountArtist; uint32 _mintAmountPlatform; uint64 _maxPurchaseAmount; uint128 _saleEndTimestamp; } /** * @dev Object holding primary fee data * @param primaryFeeBPS Primary fee percentage allocations, in basis points * @param primaryFeeRecipients Primary fee recipients */ struct PrimaryFees { uint32[] primaryFeeBPS; address[] primaryFeeRecipients; } } /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; } /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721ReceiverUpgradeable { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721MetadataUpgradeable is IERC721Upgradeable { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } uint256[50] private __gap; } /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } } /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable { using AddressUpgradeable for address; using StringsUpgradeable for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ function __ERC721_init(string memory name_, string memory symbol_) internal initializer { __Context_init_unchained(); __ERC165_init_unchained(); __ERC721_init_unchained(name_, symbol_); } function __ERC721_init_unchained(string memory name_, string memory symbol_) internal initializer { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) { return interfaceId == type(IERC721Upgradeable).interfaceId || interfaceId == type(IERC721MetadataUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: owner query for nonexistent token"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overriden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721Upgradeable.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { require(operator != _msgSender(), "ERC721: approve to caller"); _operatorApprovals[_msgSender()][operator] = approved; emit ApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _safeTransfer(from, to, tokenId, _data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `_data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory _data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _owners[tokenId] != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721Upgradeable.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory _data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721Upgradeable.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721Upgradeable.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { if (to.isContract()) { try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) { return retval == IERC721ReceiverUpgradeable.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} uint256[44] private __gap; } /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControlUpgradeable { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; } /** * @dev External interface of AccessControlEnumerable declared to support ERC165 detection. */ interface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable { /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) external view returns (address); /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) external view returns (uint256); } /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable { function __AccessControl_init() internal initializer { __Context_init_unchained(); __ERC165_init_unchained(); __AccessControl_init_unchained(); } function __AccessControl_init_unchained() internal initializer { } struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role, _msgSender()); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", StringsUpgradeable.toHexString(uint160(account), 20), " is missing role ", StringsUpgradeable.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } function _grantRole(bytes32 role, address account) private { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } function _revokeRole(bytes32 role, address account) private { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } uint256[49] private __gap; } /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSetUpgradeable { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; assembly { result := store } return result; } } /** * @dev Extension of {AccessControl} that allows enumerating the members of each role. */ abstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable { function __AccessControlEnumerable_init() internal initializer { __Context_init_unchained(); __ERC165_init_unchained(); __AccessControl_init_unchained(); __AccessControlEnumerable_init_unchained(); } function __AccessControlEnumerable_init_unchained() internal initializer { } using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet; mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view override returns (address) { return _roleMembers[role].at(index); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view override returns (uint256) { return _roleMembers[role].length(); } /** * @dev Overload {grantRole} to track enumerable memberships */ function grantRole(bytes32 role, address account) public virtual override(AccessControlUpgradeable, IAccessControlUpgradeable) { super.grantRole(role, account); _roleMembers[role].add(account); } /** * @dev Overload {revokeRole} to track enumerable memberships */ function revokeRole(bytes32 role, address account) public virtual override(AccessControlUpgradeable, IAccessControlUpgradeable) { super.revokeRole(role, account); _roleMembers[role].remove(account); } /** * @dev Overload {renounceRole} to track enumerable memberships */ function renounceRole(bytes32 role, address account) public virtual override(AccessControlUpgradeable, IAccessControlUpgradeable) { super.renounceRole(role, account); _roleMembers[role].remove(account); } /** * @dev Overload {_setupRole} to track enumerable memberships */ function _setupRole(bytes32 role, address account) internal virtual override { super._setupRole(role, account); _roleMembers[role].add(account); } uint256[49] private __gap; } // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); } // OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol) /** * @dev These functions deal with verification of Merkle Tree proofs. * * The proofs can be generated using the JavaScript library * https://github.com/miguelmota/merkletreejs[merkletreejs]. * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled. * * See `test/utils/cryptography/MerkleProof.test.js` for some examples. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the merkle tree could be reinterpreted as a leaf value. */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify( bytes32[] memory proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} * * _Available since v4.7._ */ function verifyCalldata( bytes32[] calldata proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _Available since v4.4._ */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} * * _Available since v4.7._ */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * _Available since v4.7._ */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * _Available since v4.7._ */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`, * consuming from one or the other at each step according to the instructions given by * `proofFlags`. * * _Available since v4.7._ */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof} * * _Available since v4.7._ */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } } // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } /** * @dev Global instance of Async Art Blueprint NFTs * @author Async Art, Ohimire Labs */ contract BlueprintV12 is ERC721Upgradeable, HasSecondarySaleFees, AccessControlEnumerableUpgradeable, ReentrancyGuard { using StringsUpgradeable for uint256; /** * @dev Default fee given to platform on primary sales */ uint32 public defaultPlatformPrimaryFeePercentage; /** * @dev Default fee given to artist on secondary sales */ uint32 public defaultBlueprintSecondarySalePercentage; /** * @dev Default fee given to platoform on secondary sales */ uint32 public defaultPlatformSecondarySalePercentage; /** * @dev First token ID of the next Blueprint to be prepared */ uint64 public latestErc721TokenIndex; /** * @dev Id of last blueprint created */ uint256 public blueprintIndex; /** * @dev Platform account receiving fees from primary sales */ address public asyncSaleFeesRecipient; /** * @dev Account representing platform */ address public platform; /** * @dev Account able to perform actions restricted to MINTER_ROLE holder */ address public minterAddress; /** * @dev Royalty manager */ address private _splitMain; /** * @dev Maps NFT ids to id of associated blueprint */ mapping(uint256 => uint256) tokenToBlueprintID; /** * @dev Tracks failed transfers of native gas token */ mapping(address => uint256) failedTransferCredits; /** * @dev Stores all Blueprints */ mapping(uint256 => Blueprints) public blueprints; /** * @dev Holders of this role are given minter privileges */ bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); /** * @dev Tracks the number of whitelisted purchases by each address per blueprint * @dev This mapping is outside of the BP struct because it was added as part of an upgrade, and must be placed at the end of storage to avoid overwriting */ mapping(uint256 => mapping(address => uint32)) whitelistedPurchases; /** * @dev Tracks state of Blueprint sale */ enum SaleState { not_prepared, not_started, started, paused } /** * @dev Object used by contract clients to efficiently pass in desired configuration for royalties for a Blueprint * @param secondaryFeeRecipients Array of royalty recipients * @param secondaryFeeMPS Array of allocations given to each royalty recipients, where 1000000 = 100% * @param totalRoyaltyCutBPS Total percentage of token purchase to be sent to royalty recipients, in basis points * @param royaltyRecipient If/when this is not the zero address, it is used as the de-facto alternative to secondaryFeeRecipients and secondaryFeeBPS */ struct SecondaryFeesInput { address[] secondaryFeeRecipients; uint32[] secondaryFeeMPS; uint32 totalRoyaltyCutBPS; address royaltyRecipient; } /** * @dev Object used by contract clients to efficiently pass in desired configuration for all fees * @param primaryFeeBPS Array of allocations given to each primary fee recipient, in basis points * @param primaryFeeRecipients Array of primary fee recipients * @param secondaryFeesInput Contains desired configuration for royalties * @param deploySplit If true, function taking FeesInput instance will deploy a royalty split */ struct FeesInput { uint32[] primaryFeeBPS; address[] primaryFeeRecipients; SecondaryFeesInput secondaryFeesInput; bool deploySplit; } /** * @dev Object stored per Blueprint defining fee recipients and allocations * @param primaryFeeRecipients Array of primary fee recipients * @param primaryFeeBPS Array of allocations given to each primary fee recipient, in basis points * @param royaltyRecipient Address to receive total share of royalties. Expected to be royalty split or important account * @param totalRoyaltyCutBPS Total percentage of token purchase to be sent to royalty recipients, in basis points */ struct Fees { address[] primaryFeeRecipients; uint32[] primaryFeeBPS; address royaltyRecipient; uint32 totalRoyaltyCutBPS; } /** * @dev Blueprint * @param mintAmountArtist Amount of NFTs of Blueprint mintable by artist * @param mintAmountArtist Amount of NFTs of Blueprint mintable by platform * @param capacity Number of NFTs in Blueprint * @param erc721TokenIndex First token ID of the next Blueprint to be prepared * @param maxPurchaseAmount Max number of NFTs purchasable in a single transaction * @param saleEndTimestamp Timestamp when the sale ends * @param price Price per NFT in Blueprint * @param tokenUriLocked If the token metadata isn't updatable * @param artist Artist of Blueprint * @param ERC20Token Address of ERC20 currency required to buy NFTs, can be zero address if expected currency is native gas token * @param baseTokenUri Base URI for token, resultant uri for each token is base uri concatenated with token id * @param merkleroot Root of Merkle tree holding whitelisted accounts * @param saleState State of sale * @param feeRecipientInfo Object containing primary and secondary fee configuration */ struct Blueprints { uint32 mintAmountArtist; uint32 mintAmountPlatform; uint64 capacity; uint64 erc721TokenIndex; uint64 maxPurchaseAmount; uint128 saleEndTimestamp; uint128 price; bool tokenUriLocked; address artist; address ERC20Token; string baseTokenUri; bytes32 merkleroot; SaleState saleState; Fees feeRecipientInfo; } /** * @dev Emitted when blueprint seed is revealed * @param blueprintID ID of blueprint * @param randomSeed Revealed seed */ event BlueprintSeed(uint256 blueprintID, string randomSeed); /** * @dev Emitted when NFTs of a blueprint are minted * @param blueprintID ID of blueprint * @param artist Blueprint artist * @param purchaser Purchaser of NFTs * @param tokenId NFT minted * @param newCapacity New capacity of tokens left in blueprint * @param seedPrefix Seed prefix hash */ event BlueprintMinted( uint256 blueprintID, address artist, address purchaser, uint128 tokenId, uint64 newCapacity, bytes32 seedPrefix ); /** * @dev Emitted when blueprint is prepared * @param blueprintID ID of blueprint * @param artist Blueprint artist * @param capacity Number of NFTs in blueprint * @param blueprintMetaData Blueprint metadata uri * @param baseTokenUri Blueprint's base token uri. Token uris are a result of the base uri concatenated with token id */ event BlueprintPrepared( uint256 blueprintID, address artist, uint64 capacity, string blueprintMetaData, string baseTokenUri ); /** * @dev Emitted when blueprint sale is started * @param blueprintID ID of blueprint */ event SaleStarted(uint256 blueprintID); /** * @dev Emitted when blueprint sale is paused * @param blueprintID ID of blueprint */ event SalePaused(uint256 blueprintID); /** * @dev Emitted when blueprint sale is unpaused * @param blueprintID ID of blueprint */ event SaleUnpaused(uint256 blueprintID); /** * @dev Emitted when blueprint token uri is updated * @param blueprintID ID of blueprint * @param newBaseTokenUri New base uri */ event BlueprintTokenUriUpdated(uint256 blueprintID, string newBaseTokenUri); /** * @dev Checks blueprint sale state * @param _blueprintID ID of blueprint */ modifier isBlueprintPrepared(uint256 _blueprintID) { require( blueprints[_blueprintID].saleState != SaleState.not_prepared, "!prepared" ); _; } /** * @dev Checks if blueprint sale is ongoing * @param _blueprintID ID of blueprint */ modifier isSaleOngoing(uint256 _blueprintID) { require(_isSaleOngoing(_blueprintID), "!ongoing"); _; } /** * @dev Checks if quantity of NFTs is available for purchase in blueprint * @param _blueprintID ID of blueprint * @param _quantity Quantity of NFTs being checked */ modifier isQuantityAvailableForPurchase( uint256 _blueprintID, uint32 _quantity ) { require( blueprints[_blueprintID].capacity >= _quantity, "quantity >" ); _; } /** * @dev Checks if sale is still valid, given the sale end timestamp * @param _saleEndTimestamp Sale end timestamp */ modifier isSaleEndTimestampCurrentlyValid( uint128 _saleEndTimestamp ) { require(_isSaleEndTimestampCurrentlyValid(_saleEndTimestamp), "ended"); _; } /** * @dev Initialize the implementation * @param name_ Contract name * @param symbol_ Contract symbol * @param blueprintV12Admins Administrative accounts * @param splitMain Royalty manager */ function initialize( string memory name_, string memory symbol_, IBlueprintTypes.Admins calldata blueprintV12Admins, address splitMain ) public initializer { // Intialize parent contracts ERC721Upgradeable.__ERC721_init(name_, symbol_); HasSecondarySaleFees._initialize(); AccessControlUpgradeable.__AccessControl_init(); _setupRole(DEFAULT_ADMIN_ROLE, blueprintV12Admins.platform); _setupRole(MINTER_ROLE, blueprintV12Admins.minter); platform = blueprintV12Admins.platform; minterAddress = blueprintV12Admins.minter; defaultPlatformPrimaryFeePercentage = 2000; // 20% defaultBlueprintSecondarySalePercentage = 750; // 7.5% defaultPlatformSecondarySalePercentage = 250; // 2.5% asyncSaleFeesRecipient = blueprintV12Admins.asyncSaleFeesRecipient; _splitMain = splitMain; } /** * @dev Validates that sale is still ongoing * @param _blueprintID Blueprint ID */ function _isSaleOngoing(uint256 _blueprintID) internal view returns (bool) { return blueprints[_blueprintID].saleState == SaleState.started && _isSaleEndTimestampCurrentlyValid(blueprints[_blueprintID].saleEndTimestamp); } /** * @dev Checks if user whitelisted for presale purchase * @param _blueprintID ID of blueprint * @param _whitelistedQuantity Purchaser's requested quantity. Validated against merkle tree * @param proof Corresponding proof for purchaser in merkle tree */ function _isWhitelistedAndPresale( uint256 _blueprintID, uint32 _whitelistedQuantity, bytes32[] calldata proof ) internal view returns (bool) { return (_isBlueprintPreparedAndNotStarted(_blueprintID) && proof.length != 0 && _verify(_leaf(msg.sender, uint256(_whitelistedQuantity)), blueprints[_blueprintID].merkleroot, proof)); } /** * @dev Checks if sale is still valid, given the sale end timestamp * @param _saleEndTimestamp Sale end timestamp */ function _isSaleEndTimestampCurrentlyValid(uint128 _saleEndTimestamp) internal view returns (bool) { return _saleEndTimestamp > block.timestamp || _saleEndTimestamp == 0; } /** * @dev Checks that blueprint is prepared but sale for it hasn't started * @param _blueprintID ID of blueprint */ function _isBlueprintPreparedAndNotStarted(uint256 _blueprintID) internal view returns (bool) { return blueprints[_blueprintID].saleState == SaleState.not_started; } /** * @dev Checks that the recipients and allocations arrays of royalties are valid * @param _feeRecipients Fee recipients * @param _feeBPS Allocations in percentages for fee recipients (basis points) */ function feeArrayDataValid( address[] memory _feeRecipients, uint32[] memory _feeBPS ) internal pure returns (bool) { require( _feeRecipients.length == _feeBPS.length, "invalid" ); uint32 totalPercent; for (uint256 i; i < _feeBPS.length; i++) { totalPercent = totalPercent + _feeBPS[i]; } require(totalPercent <= 10000, "bps >"); return true; } /** * @dev Sets values after blueprint preparation * @param _blueprintID Blueprint ID * @param _blueprintMetaData Blueprint metadata uri */ function setBlueprintPrepared( uint256 _blueprintID, string memory _blueprintMetaData ) internal { blueprints[_blueprintID].saleState = SaleState.not_started; //assign the erc721 token index to the blueprint blueprints[_blueprintID].erc721TokenIndex = latestErc721TokenIndex; uint64 _capacity = blueprints[_blueprintID].capacity; latestErc721TokenIndex += _capacity; blueprintIndex++; emit BlueprintPrepared( _blueprintID, blueprints[_blueprintID].artist, _capacity, _blueprintMetaData, blueprints[_blueprintID].baseTokenUri ); } /** * @dev Sets the ERC20 token value of a blueprint * @param _blueprintID Blueprint ID * @param _erc20Token ERC20 token being set */ function setErc20Token(uint256 _blueprintID, address _erc20Token) internal { if (_erc20Token != address(0)) { blueprints[_blueprintID].ERC20Token = _erc20Token; } } /** * @dev Sets up most blueprint parameters * @param _blueprintID Blueprint ID * @param _erc20Token ERC20 currency * @param _baseTokenUri Base token uri for blueprint * @param _merkleroot Root of merkle tree allowlist * @param _mintAmountArtist Amount that artist can mint of blueprint * @param _mintAmountPlatform Amount that platform can mint of blueprint * @param _maxPurchaseAmount Max amount of NFTs purchasable in one transaction * @param _saleEndTimestamp When the sale ends */ function _setupBlueprint( uint256 _blueprintID, address _erc20Token, string memory _baseTokenUri, bytes32 _merkleroot, uint32 _mintAmountArtist, uint32 _mintAmountPlatform, uint64 _maxPurchaseAmount, uint128 _saleEndTimestamp ) internal isSaleEndTimestampCurrentlyValid(_saleEndTimestamp) { setErc20Token(_blueprintID, _erc20Token); blueprints[_blueprintID].baseTokenUri = _baseTokenUri; if (_merkleroot != 0) { blueprints[_blueprintID].merkleroot = _merkleroot; } blueprints[_blueprintID].mintAmountArtist = _mintAmountArtist; blueprints[_blueprintID].mintAmountPlatform = _mintAmountPlatform; if (_maxPurchaseAmount != 0) { blueprints[_blueprintID].maxPurchaseAmount = _maxPurchaseAmount; } if (_saleEndTimestamp != 0) { blueprints[_blueprintID].saleEndTimestamp = _saleEndTimestamp; } } /** * @dev Prepare the blueprint (this is the core operation to set up a blueprint) * @param _artist Artist address * @param config Object containing values required to prepare blueprint * @param feesInput Initial primary and secondary fees config */ function prepareBlueprint( address _artist, IBlueprintTypes.BlueprintPreparationConfig calldata config, FeesInput calldata feesInput ) external onlyRole(MINTER_ROLE) { uint256 _blueprintID = blueprintIndex; blueprints[_blueprintID].artist = _artist; blueprints[_blueprintID].capacity = config._capacity; blueprints[_blueprintID].price = config._price; _setupBlueprint( _blueprintID, config._erc20Token, config._baseTokenUri, config._merkleroot, config._mintAmountArtist, config._mintAmountPlatform, config._maxPurchaseAmount, config._saleEndTimestamp ); setBlueprintPrepared(_blueprintID, config._blueprintMetaData); setFeeRecipients(_blueprintID, feesInput); } /** * @dev Update a blueprint's artist * @param _blueprintID Blueprint ID * @param _newArtist New artist */ function updateBlueprintArtist ( uint256 _blueprintID, address _newArtist ) external onlyRole(MINTER_ROLE) { blueprints[_blueprintID].artist = _newArtist; } /** * @dev Update a blueprint's merkleroot * @param _blueprintID Blueprint ID * @param _newMerkleroot New merkleroot */ function updateBlueprintMerkleroot ( uint256 _blueprintID, bytes32 _newMerkleroot ) external onlyRole(MINTER_ROLE) { blueprints[_blueprintID].merkleroot = _newMerkleroot; } /** * @dev Update a blueprint's capacity * @param _blueprintID Blueprint ID * @param _newCapacity New capacity * @param _newLatestErc721TokenIndex Newly adjusted last ERC721 token id */ function updateBlueprintCapacity ( uint256 _blueprintID, uint64 _newCapacity, uint64 _newLatestErc721TokenIndex ) external onlyRole(MINTER_ROLE) { require(blueprints[_blueprintID].capacity > _newCapacity, "cap >"); blueprints[_blueprintID].capacity = _newCapacity; latestErc721TokenIndex = _newLatestErc721TokenIndex; } /** * @dev Set the primary and secondary fees config of a blueprint * @param _blueprintID Blueprint ID * @param _feesInput Fees config */ function setFeeRecipients( uint256 _blueprintID, FeesInput memory _feesInput ) public onlyRole(MINTER_ROLE) { require( blueprints[_blueprintID].saleState != SaleState.not_prepared, "!prepared" ); require( feeArrayDataValid(_feesInput.primaryFeeRecipients, _feesInput.primaryFeeBPS), "primary" ); SecondaryFeesInput memory secondaryFeesInput = _feesInput.secondaryFeesInput; Fees memory feeRecipientInfo = Fees( _feesInput.primaryFeeRecipients, _feesInput.primaryFeeBPS, secondaryFeesInput.royaltyRecipient, secondaryFeesInput.totalRoyaltyCutBPS ); // if pre-existing split isn't passed in, deploy it and set it. if (_feesInput.deploySplit) { feeRecipientInfo.royaltyRecipient = ISplitMain(_splitMain).createSplit( secondaryFeesInput.secondaryFeeRecipients, secondaryFeesInput.secondaryFeeMPS, 0, address(0) // immutable split ); } blueprints[_blueprintID].feeRecipientInfo = feeRecipientInfo; } /** * @dev Begin a blueprint's sale * @param blueprintID Blueprint ID */ function beginSale(uint256 blueprintID) external onlyRole(MINTER_ROLE) isSaleEndTimestampCurrentlyValid(blueprints[blueprintID].saleEndTimestamp) { require( blueprints[blueprintID].saleState == SaleState.not_started, "started" ); blueprints[blueprintID].saleState = SaleState.started; emit SaleStarted(blueprintID); } /** * @dev Pause a blueprint's sale * @param blueprintID Blueprint ID */ function pauseSale(uint256 blueprintID) external onlyRole(MINTER_ROLE) isSaleOngoing(blueprintID) { blueprints[blueprintID].saleState = SaleState.paused; emit SalePaused(blueprintID); } /** * @dev Unpause a blueprint's sale * @param blueprintID Blueprint ID */ function unpauseSale(uint256 blueprintID) external onlyRole(MINTER_ROLE) isSaleEndTimestampCurrentlyValid(blueprints[blueprintID].saleEndTimestamp) { require( blueprints[blueprintID].saleState == SaleState.paused, "!paused" ); blueprints[blueprintID].saleState = SaleState.started; emit SaleUnpaused(blueprintID); } /** * @dev Purchase NFTs of a blueprint to a recipient address * @param blueprintID Blueprint ID * @param purchaseQuantity How many NFTs to purchase * @param whitelistedQuantity How many NFTS are whitelisted for the blueprint * @param tokenAmount Payment amount * @param proof Merkle tree proof * @param nftRecipient Recipient of minted NFTs */ function purchaseBlueprintsTo( uint256 blueprintID, uint32 purchaseQuantity, uint32 whitelistedQuantity, uint256 tokenAmount, bytes32[] calldata proof, address nftRecipient ) external payable nonReentrant isQuantityAvailableForPurchase(blueprintID, purchaseQuantity) { if (_isWhitelistedAndPresale(blueprintID, whitelistedQuantity, proof)) { require(whitelistedPurchases[blueprintID][msg.sender] + purchaseQuantity <= whitelistedQuantity, "> whitelisted amount"); whitelistedPurchases[blueprintID][msg.sender] += purchaseQuantity; } else { require(_isSaleOngoing(blueprintID), "unavailable"); } require( blueprints[blueprintID].maxPurchaseAmount == 0 || purchaseQuantity <= blueprints[blueprintID].maxPurchaseAmount, "> maxPurchaseAmount" ); address artist = blueprints[blueprintID].artist; _confirmPaymentAmountAndSettleSale( blueprintID, purchaseQuantity, tokenAmount, artist ); _mintQuantity(blueprintID, purchaseQuantity, nftRecipient); } /** * @dev Purchase NFTs of a blueprint to the sender * @param blueprintID Blueprint ID * @param purchaseQuantity How many NFTs to purchase * @param whitelistedQuantity How many NFTS are whitelisted for the blueprint * @param tokenAmount Payment amount * @param proof Merkle tree proof */ function purchaseBlueprints( uint256 blueprintID, uint32 purchaseQuantity, uint32 whitelistedQuantity, uint256 tokenAmount, bytes32[] calldata proof ) external payable nonReentrant isQuantityAvailableForPurchase(blueprintID, purchaseQuantity) { if (_isWhitelistedAndPresale(blueprintID, whitelistedQuantity, proof)) { require(whitelistedPurchases[blueprintID][msg.sender] + purchaseQuantity <= whitelistedQuantity, "> whitelisted amount"); whitelistedPurchases[blueprintID][msg.sender] += purchaseQuantity; } else { require(_isSaleOngoing(blueprintID), "unavailable"); } require( blueprints[blueprintID].maxPurchaseAmount == 0 || purchaseQuantity <= blueprints[blueprintID].maxPurchaseAmount, "> maxPurchaseAmount" ); address artist = blueprints[blueprintID].artist; _confirmPaymentAmountAndSettleSale( blueprintID, purchaseQuantity, tokenAmount, artist ); _mintQuantity(blueprintID, purchaseQuantity, msg.sender); } /** * @dev Lets the artist of a blueprint mint NFTs of the blueprint * @param blueprintID Blueprint ID * @param quantity How many NFTs to mint */ function artistMint( uint256 blueprintID, uint32 quantity ) external nonReentrant { require( _isBlueprintPreparedAndNotStarted(blueprintID) || _isSaleOngoing(blueprintID), "not pre/public sale" ); require( minterAddress == msg.sender || blueprints[blueprintID].artist == msg.sender, "unauthorized" ); if (minterAddress == msg.sender) { require( quantity <= blueprints[blueprintID].mintAmountPlatform, "quantity >" ); blueprints[blueprintID].mintAmountPlatform -= quantity; } else if (blueprints[blueprintID].artist == msg.sender) { require( quantity <= blueprints[blueprintID].mintAmountArtist, "quantity >" ); blueprints[blueprintID].mintAmountArtist -= quantity; } _mintQuantity(blueprintID, quantity, msg.sender); } /** * @dev Mint a quantity of NFTs of a blueprint to a recipient * @param _blueprintID Blueprint ID * @param _quantity Quantity to mint * @param _nftRecipient Recipient of minted NFTs */ function _mintQuantity(uint256 _blueprintID, uint32 _quantity, address _nftRecipient) private { uint128 newTokenId = blueprints[_blueprintID].erc721TokenIndex; uint64 newCap = blueprints[_blueprintID].capacity; for (uint16 i; i < _quantity; i++) { require(newCap > 0, "quantity > cap"); _mint(_nftRecipient, newTokenId + i); tokenToBlueprintID[newTokenId + i] = _blueprintID; bytes32 prefixHash = keccak256( abi.encodePacked( block.number, block.timestamp, block.coinbase, newCap ) ); emit BlueprintMinted( _blueprintID, blueprints[_blueprintID].artist, _nftRecipient, newTokenId + i, newCap, prefixHash ); --newCap; } blueprints[_blueprintID].erc721TokenIndex += _quantity; blueprints[_blueprintID].capacity = newCap; } /** * @dev Pay for minting NFTs * @param _blueprintID Blueprint ID * @param _quantity Quantity of NFTs to purchase * @param _tokenAmount Payment amount provided * @param _artist Artist of blueprint */ function _confirmPaymentAmountAndSettleSale( uint256 _blueprintID, uint32 _quantity, uint256 _tokenAmount, address _artist ) internal { address _erc20Token = blueprints[_blueprintID].ERC20Token; uint128 _price = blueprints[_blueprintID].price; if (_erc20Token == address(0)) { require(_tokenAmount == 0, "tokenAmount != 0"); require( msg.value == _quantity * _price, "$ != expected" ); _payFeesAndArtist(_blueprintID, _erc20Token, msg.value, _artist); } else { require(msg.value == 0, "eth value != 0"); require( _tokenAmount == _quantity * _price, "$ != expected" ); IERC20(_erc20Token).transferFrom( msg.sender, address(this), _tokenAmount ); _payFeesAndArtist(_blueprintID, _erc20Token, _tokenAmount, _artist); } } //////////////////////////////////// ////// MERKLEROOT FUNCTIONS //////// //////////////////////////////////// /** * @dev Create a merkle tree with address: quantity pairs as the leaves. * The msg.sender will be verified if it has a corresponding quantity value in the merkletree * @param account Minting account being verified * @param quantity Quantity to mint, being verified */ function _leaf(address account, uint256 quantity) internal pure returns (bytes32) { return keccak256(abi.encodePacked(account, quantity)); } /** * @dev Verify a leaf's inclusion in a merkle tree with its root and corresponding proof * @param leaf Leaf to verify * @param merkleroot Merkle tree's root * @param proof Corresponding proof for leaf */ function _verify( bytes32 leaf, bytes32 merkleroot, bytes32[] memory proof ) internal pure returns (bool) { return MerkleProof.verify(proof, merkleroot, leaf); } //////////////////////////// /// ONLY ADMIN functions /// //////////////////////////// /** * @dev Update blueprint's token uri * @param blueprintID Blueprint ID * @param newBaseTokenUri New base token uri to update to */ function updateBlueprintTokenUri( uint256 blueprintID, string memory newBaseTokenUri ) external onlyRole(MINTER_ROLE) isBlueprintPrepared(blueprintID) { require( !blueprints[blueprintID].tokenUriLocked, "locked" ); blueprints[blueprintID].baseTokenUri = newBaseTokenUri; emit BlueprintTokenUriUpdated(blueprintID, newBaseTokenUri); } /** * @dev Lock blueprint's token uri (from changing) * @param blueprintID Blueprint ID */ function lockBlueprintTokenUri(uint256 blueprintID) external onlyRole(DEFAULT_ADMIN_ROLE) isBlueprintPrepared(blueprintID) { require( !blueprints[blueprintID].tokenUriLocked, "locked" ); blueprints[blueprintID].tokenUriLocked = true; } /** * @dev Return token's uri * @param tokenId ID of token to return uri for * @return Token uri, constructed by taking base uri of blueprint corresponding to token, and concatenating token id */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require( _exists(tokenId), "token dne" ); string memory baseURI = blueprints[tokenToBlueprintID[tokenId]].baseTokenUri; return bytes(baseURI).length > 0 ? string( abi.encodePacked( baseURI, "/", tokenId.toString(), "/", "token.json" ) ) : ""; } /** * @dev Reveal blueprint's seed by emitting public event * @param blueprintID Blueprint ID * @param randomSeed Revealed seed */ function revealBlueprintSeed(uint256 blueprintID, string memory randomSeed) external onlyRole(MINTER_ROLE) isBlueprintPrepared(blueprintID) { emit BlueprintSeed(blueprintID, randomSeed); } /** * @dev Set the contract-wide recipient of primary sale feess * @param _asyncSaleFeesRecipient New async sale fees recipient */ function setAsyncFeeRecipient(address _asyncSaleFeesRecipient) external onlyRole(DEFAULT_ADMIN_ROLE) { asyncSaleFeesRecipient = _asyncSaleFeesRecipient; } /** * @dev Change the default percentage of primary sales sent to platform * @param _basisPoints New default platform primary fee percentage (in basis points) */ function changeDefaultPlatformPrimaryFeePercentage(uint32 _basisPoints) external onlyRole(DEFAULT_ADMIN_ROLE) { require(_basisPoints <= 10000); defaultPlatformPrimaryFeePercentage = _basisPoints; } /** * @dev Change the default secondary sale percentage sent to artist and others * @param _basisPoints New default secondary fee percentage (in basis points) */ function changeDefaultBlueprintSecondarySalePercentage(uint32 _basisPoints) external onlyRole(DEFAULT_ADMIN_ROLE) { require(_basisPoints + defaultPlatformSecondarySalePercentage <= 10000); defaultBlueprintSecondarySalePercentage = _basisPoints; } /** * @dev Change the default secondary sale percentage sent to platform * @param _basisPoints New default secondary fee percentage (in basis points) */ function changeDefaultPlatformSecondarySalePercentage(uint32 _basisPoints) external onlyRole(DEFAULT_ADMIN_ROLE) { require( _basisPoints + defaultBlueprintSecondarySalePercentage <= 10000 ); defaultPlatformSecondarySalePercentage = _basisPoints; } /** * @dev Update contract-wide platform address, and DEFAULT_ADMIN role ownership * @param _platform New platform address */ function updatePlatformAddress(address _platform) external onlyRole(DEFAULT_ADMIN_ROLE) { grantRole(DEFAULT_ADMIN_ROLE, _platform); revokeRole(DEFAULT_ADMIN_ROLE, platform); platform = _platform; } /** * @dev Update contract-wide minter address, and MINTER_ROLE role ownership * @param newMinterAddress New minter address */ function updateMinterAddress(address newMinterAddress) external onlyRole(DEFAULT_ADMIN_ROLE) { grantRole(MINTER_ROLE, newMinterAddress); revokeRole(MINTER_ROLE, minterAddress); minterAddress = newMinterAddress; } //////////////////////////////////// /// Secondary Fees implementation // //////////////////////////////////// /** * @dev Pay primary fees owed to primary fee recipients * @param _blueprintID Blueprint ID * @param _erc20Token ERC20 token used for payment (if used) * @param _amount Payment amount * @param _artist Artist being paid */ function _payFeesAndArtist( uint256 _blueprintID, address _erc20Token, uint256 _amount, address _artist ) internal { address[] memory _primaryFeeRecipients = getPrimaryFeeRecipients( _blueprintID ); uint32[] memory _primaryFeeBPS = getPrimaryFeeBps(_blueprintID); uint256 feesPaid; for (uint256 i; i < _primaryFeeRecipients.length; i++) { uint256 fee = (_amount * _primaryFeeBPS[i])/10000; feesPaid = feesPaid + fee; _payout(_primaryFeeRecipients[i], _erc20Token, fee); } if (_amount - feesPaid > 0) { _payout(_artist, _erc20Token, (_amount - feesPaid)); } } /** * @dev Simple payment function to pay an amount of currency to a recipient * @param _recipient Recipient of payment * @param _erc20Token ERC20 token used for payment (if used) * @param _amount Payment amount */ function _payout( address _recipient, address _erc20Token, uint256 _amount ) internal { if (_erc20Token != address(0)) { IERC20(_erc20Token).transfer(_recipient, _amount); } else { // attempt to send the funds to the recipient (bool success, ) = payable(_recipient).call{ value: _amount, gas: 20000 }(""); // if it failed, update their credit balance so they can pull it later if (!success) { failedTransferCredits[_recipient] = failedTransferCredits[_recipient] + _amount; } } } /** * @dev When a native gas token payment fails, credits are stored so that the would-be recipient can withdraw them later. * Withdraw failed credits for a recipient * @param recipient Recipient owed some amount of native gas token */ function withdrawAllFailedCredits(address payable recipient) external { uint256 amount = failedTransferCredits[msg.sender]; require(amount != 0, "!credits"); failedTransferCredits[msg.sender] = 0; (bool successfulWithdraw, ) = recipient.call{value: amount, gas: 20000}( "" ); require(successfulWithdraw, "failed"); } /** * @dev Get primary fee recipients of a blueprint * @param id Blueprint ID */ function getPrimaryFeeRecipients(uint256 id) public view returns (address[] memory) { if (blueprints[id].feeRecipientInfo.primaryFeeRecipients.length == 0) { address[] memory primaryFeeRecipients = new address[](1); primaryFeeRecipients[0] = (asyncSaleFeesRecipient); return primaryFeeRecipients; } else { return blueprints[id].feeRecipientInfo.primaryFeeRecipients; } } /** * @dev Get primary fee bps (allocations) of a blueprint * @param id Blueprint ID */ function getPrimaryFeeBps(uint256 id) public view returns (uint32[] memory) { if (blueprints[id].feeRecipientInfo.primaryFeeBPS.length == 0) { uint32[] memory primaryFeeBPS = new uint32[](1); primaryFeeBPS[0] = defaultPlatformPrimaryFeePercentage; return primaryFeeBPS; } else { return blueprints[id].feeRecipientInfo.primaryFeeBPS; } } /** * @dev Get secondary fee recipients of a token * @param tokenId Token ID */ function getFeeRecipients(uint256 tokenId) public view override returns (address[] memory) { address[] memory feeRecipients = new address[](1); feeRecipients[0] = blueprints[tokenToBlueprintID[tokenId]].feeRecipientInfo.royaltyRecipient; return feeRecipients; } /** * @dev Get secondary fee bps (allocations) of a token * @param tokenId Token ID */ function getFeeBps(uint256 tokenId) public view override returns (uint32[] memory) { uint32[] memory feeBPS = new uint32[](1); feeBPS[0] = blueprints[tokenToBlueprintID[tokenId]].feeRecipientInfo.totalRoyaltyCutBPS; return feeBPS; } //////////////////////////////////// /// Required function overide ////// //////////////////////////////////// /** * @dev Override isApprovedForAll to also let the DEFAULT_ADMIN_ROLE move tokens * @param account Account holding tokens being moved * @param operator Operator moving tokens */ function isApprovedForAll(address account, address operator) public view override returns (bool) { return super.isApprovedForAll(account, operator) || hasRole(DEFAULT_ADMIN_ROLE, operator); } /** * @dev ERC165 - Validate that the contract supports a interface * @param interfaceId ID of interface being validated * @return Returns true if contract supports interface */ function supportsInterface(bytes4 interfaceId) public view virtual override( ERC721Upgradeable, ERC165StorageUpgradeable, AccessControlEnumerableUpgradeable ) returns (bool) { return interfaceId == type(HasSecondarySaleFees).interfaceId || ERC721Upgradeable.supportsInterface(interfaceId) || ERC165StorageUpgradeable.supportsInterface(interfaceId) || AccessControlEnumerableUpgradeable.supportsInterface(interfaceId); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"blueprintID","type":"uint256"},{"indexed":false,"internalType":"address","name":"artist","type":"address"},{"indexed":false,"internalType":"address","name":"purchaser","type":"address"},{"indexed":false,"internalType":"uint128","name":"tokenId","type":"uint128"},{"indexed":false,"internalType":"uint64","name":"newCapacity","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"seedPrefix","type":"bytes32"}],"name":"BlueprintMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"blueprintID","type":"uint256"},{"indexed":false,"internalType":"address","name":"artist","type":"address"},{"indexed":false,"internalType":"uint64","name":"capacity","type":"uint64"},{"indexed":false,"internalType":"string","name":"blueprintMetaData","type":"string"},{"indexed":false,"internalType":"string","name":"baseTokenUri","type":"string"}],"name":"BlueprintPrepared","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"blueprintID","type":"uint256"},{"indexed":false,"internalType":"string","name":"randomSeed","type":"string"}],"name":"BlueprintSeed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"blueprintID","type":"uint256"},{"indexed":false,"internalType":"string","name":"newBaseTokenUri","type":"string"}],"name":"BlueprintTokenUriUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"blueprintID","type":"uint256"}],"name":"SalePaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"blueprintID","type":"uint256"}],"name":"SaleStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"blueprintID","type":"uint256"}],"name":"SaleUnpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address[]","name":"recipients","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"bps","type":"uint256[]"}],"name":"SecondarySaleFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"blueprintID","type":"uint256"},{"internalType":"uint32","name":"quantity","type":"uint32"}],"name":"artistMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"asyncSaleFeesRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blueprintID","type":"uint256"}],"name":"beginSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"blueprintIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"blueprints","outputs":[{"internalType":"uint32","name":"mintAmountArtist","type":"uint32"},{"internalType":"uint32","name":"mintAmountPlatform","type":"uint32"},{"internalType":"uint64","name":"capacity","type":"uint64"},{"internalType":"uint64","name":"erc721TokenIndex","type":"uint64"},{"internalType":"uint64","name":"maxPurchaseAmount","type":"uint64"},{"internalType":"uint128","name":"saleEndTimestamp","type":"uint128"},{"internalType":"uint128","name":"price","type":"uint128"},{"internalType":"bool","name":"tokenUriLocked","type":"bool"},{"internalType":"address","name":"artist","type":"address"},{"internalType":"address","name":"ERC20Token","type":"address"},{"internalType":"string","name":"baseTokenUri","type":"string"},{"internalType":"bytes32","name":"merkleroot","type":"bytes32"},{"internalType":"enum BlueprintV12.SaleState","name":"saleState","type":"uint8"},{"components":[{"internalType":"address[]","name":"primaryFeeRecipients","type":"address[]"},{"internalType":"uint32[]","name":"primaryFeeBPS","type":"uint32[]"},{"internalType":"address","name":"royaltyRecipient","type":"address"},{"internalType":"uint32","name":"totalRoyaltyCutBPS","type":"uint32"}],"internalType":"struct BlueprintV12.Fees","name":"feeRecipientInfo","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_basisPoints","type":"uint32"}],"name":"changeDefaultBlueprintSecondarySalePercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_basisPoints","type":"uint32"}],"name":"changeDefaultPlatformPrimaryFeePercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_basisPoints","type":"uint32"}],"name":"changeDefaultPlatformSecondarySalePercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"defaultBlueprintSecondarySalePercentage","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultPlatformPrimaryFeePercentage","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultPlatformSecondarySalePercentage","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getFeeBps","outputs":[{"internalType":"uint32[]","name":"","type":"uint32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getFeeRecipients","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getPrimaryFeeBps","outputs":[{"internalType":"uint32[]","name":"","type":"uint32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getPrimaryFeeRecipients","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"components":[{"internalType":"address","name":"platform","type":"address"},{"internalType":"address","name":"minter","type":"address"},{"internalType":"address","name":"asyncSaleFeesRecipient","type":"address"}],"internalType":"struct IBlueprintTypes.Admins","name":"blueprintV12Admins","type":"tuple"},{"internalType":"address","name":"splitMain","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestErc721TokenIndex","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blueprintID","type":"uint256"}],"name":"lockBlueprintTokenUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minterAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blueprintID","type":"uint256"}],"name":"pauseSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"platform","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_artist","type":"address"},{"components":[{"internalType":"uint64","name":"_capacity","type":"uint64"},{"internalType":"uint128","name":"_price","type":"uint128"},{"internalType":"address","name":"_erc20Token","type":"address"},{"internalType":"string","name":"_blueprintMetaData","type":"string"},{"internalType":"string","name":"_baseTokenUri","type":"string"},{"internalType":"bytes32","name":"_merkleroot","type":"bytes32"},{"internalType":"uint32","name":"_mintAmountArtist","type":"uint32"},{"internalType":"uint32","name":"_mintAmountPlatform","type":"uint32"},{"internalType":"uint64","name":"_maxPurchaseAmount","type":"uint64"},{"internalType":"uint128","name":"_saleEndTimestamp","type":"uint128"}],"internalType":"struct IBlueprintTypes.BlueprintPreparationConfig","name":"config","type":"tuple"},{"components":[{"internalType":"uint32[]","name":"primaryFeeBPS","type":"uint32[]"},{"internalType":"address[]","name":"primaryFeeRecipients","type":"address[]"},{"components":[{"internalType":"address[]","name":"secondaryFeeRecipients","type":"address[]"},{"internalType":"uint32[]","name":"secondaryFeeMPS","type":"uint32[]"},{"internalType":"uint32","name":"totalRoyaltyCutBPS","type":"uint32"},{"internalType":"address","name":"royaltyRecipient","type":"address"}],"internalType":"struct BlueprintV12.SecondaryFeesInput","name":"secondaryFeesInput","type":"tuple"},{"internalType":"bool","name":"deploySplit","type":"bool"}],"internalType":"struct BlueprintV12.FeesInput","name":"feesInput","type":"tuple"}],"name":"prepareBlueprint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"blueprintID","type":"uint256"},{"internalType":"uint32","name":"purchaseQuantity","type":"uint32"},{"internalType":"uint32","name":"whitelistedQuantity","type":"uint32"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"purchaseBlueprints","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"blueprintID","type":"uint256"},{"internalType":"uint32","name":"purchaseQuantity","type":"uint32"},{"internalType":"uint32","name":"whitelistedQuantity","type":"uint32"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"address","name":"nftRecipient","type":"address"}],"name":"purchaseBlueprintsTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"blueprintID","type":"uint256"},{"internalType":"string","name":"randomSeed","type":"string"}],"name":"revealBlueprintSeed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asyncSaleFeesRecipient","type":"address"}],"name":"setAsyncFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blueprintID","type":"uint256"},{"components":[{"internalType":"uint32[]","name":"primaryFeeBPS","type":"uint32[]"},{"internalType":"address[]","name":"primaryFeeRecipients","type":"address[]"},{"components":[{"internalType":"address[]","name":"secondaryFeeRecipients","type":"address[]"},{"internalType":"uint32[]","name":"secondaryFeeMPS","type":"uint32[]"},{"internalType":"uint32","name":"totalRoyaltyCutBPS","type":"uint32"},{"internalType":"address","name":"royaltyRecipient","type":"address"}],"internalType":"struct BlueprintV12.SecondaryFeesInput","name":"secondaryFeesInput","type":"tuple"},{"internalType":"bool","name":"deploySplit","type":"bool"}],"internalType":"struct BlueprintV12.FeesInput","name":"_feesInput","type":"tuple"}],"name":"setFeeRecipients","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":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"blueprintID","type":"uint256"}],"name":"unpauseSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blueprintID","type":"uint256"},{"internalType":"address","name":"_newArtist","type":"address"}],"name":"updateBlueprintArtist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blueprintID","type":"uint256"},{"internalType":"uint64","name":"_newCapacity","type":"uint64"},{"internalType":"uint64","name":"_newLatestErc721TokenIndex","type":"uint64"}],"name":"updateBlueprintCapacity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blueprintID","type":"uint256"},{"internalType":"bytes32","name":"_newMerkleroot","type":"bytes32"}],"name":"updateBlueprintMerkleroot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"blueprintID","type":"uint256"},{"internalType":"string","name":"newBaseTokenUri","type":"string"}],"name":"updateBlueprintTokenUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newMinterAddress","type":"address"}],"name":"updateMinterAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_platform","type":"address"}],"name":"updatePlatformAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"recipient","type":"address"}],"name":"withdrawAllFailedCredits","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50600161012d55615cac80620000276000396000f3fe6080604052600436106102915760003560e01c8063018a62a61461029657806301a94950146102b857806301ffc9a7146102d857806306fdde031461030d578063081812fc1461032f578063095ea7b3146103675780630a21a211146103875780630ebd4c7f146103b45780630f61513b146103e157806320ceaf8d1461040157806322235d691461042157806323b872dd14610454578063248a9ca3146104745780632c34c7f2146104a25780632f2ff15d146104c25780632fcfb95a146104e257806334d722c91461050257806336568abe146105235780633a66e4b61461054357806342842e0e146105635780634bde38c8146105835780634d073a5a146105a45780636352211e146105e457806366bf33be1461060457806366c083d31461063e57806368c31e261461065e57806370a082311461067e578063745ba66a1461069e5780637b4252c0146106be57806380ae4ebc146106d55780638f9f193f146106ea5780639010d07c1461070a57806391d148541461072a57806395d89b411461074a5780639aa4740e1461075f578063a217fddf1461077f578063a22cb46514610794578063aec970b0146107b4578063b88d4fde146107d4578063b9c4d9fb146107f4578063bf79e16e14610814578063c2bce59c14610827578063c87b56dd14610847578063c8950e6014610867578063c90941b114610887578063c9f2bd93146108a7578063ca15c873146108c7578063cba991bf146108e7578063ce43fcc91461090c578063ced360431461092c578063d53913931461094c578063d547741f1461096e578063deb941481461098e578063e15af0b2146109af578063e985e9c5146109c2578063eaf2115d146109e2578063f0b68ea314610a07578063fce212f314610a27575b600080fd5b3480156102a257600080fd5b506102b66102b1366004614fd6565b610a47565b005b3480156102c457600080fd5b506102b66102d33660046151b8565b610afd565b3480156102e457600080fd5b506102f86102f3366004614ee9565b610b61565b60405190151581526020015b60405180910390f35b34801561031957600080fd5b50610322610baa565b60405161030491906154a0565b34801561033b57600080fd5b5061034f61034a366004614e8c565b610c3c565b6040516001600160a01b039091168152602001610304565b34801561037357600080fd5b506102b6610382366004614e45565b610cc4565b34801561039357600080fd5b506103a76103a2366004614e8c565b610dd5565b604051610304919061542d565b3480156103c057600080fd5b506103d46103cf366004614e8c565b610ed1565b604051610304919061548d565b3480156103ed57600080fd5b506102b66103fc366004614f21565b610f61565b34801561040d57600080fd5b506102b661041c36600461517d565b6110e0565b34801561042d57600080fd5b5061012e5461043f9063ffffffff1681565b60405163ffffffff9091168152602001610304565b34801561046057600080fd5b506102b661046f366004614cdc565b6111ab565b34801561048057600080fd5b5061049461048f366004614e8c565b6111dc565b604051908152602001610304565b3480156104ae57600080fd5b506102b66104bd366004614ec8565b6111f1565b3480156104ce57600080fd5b506102b66104dd366004614ea4565b611221565b3480156104ee57600080fd5b506102b66104fd366004614c6c565b611243565b34801561050e57600080fd5b506101325461034f906001600160a01b031681565b34801561052f57600080fd5b506102b661053e366004614ea4565b6112b1565b34801561054f57600080fd5b506102b661055e366004614e8c565b6112d3565b34801561056f57600080fd5b506102b661057e366004614cdc565b611384565b34801561058f57600080fd5b506101315461034f906001600160a01b031681565b3480156105b057600080fd5b5061012e546105cc90600160601b90046001600160401b031681565b6040516001600160401b039091168152602001610304565b3480156105f057600080fd5b5061034f6105ff366004614e8c565b61139f565b34801561061057600080fd5b5061062461061f366004614e8c565b611416565b6040516103049e9d9c9b9a99989796959493929190615809565b34801561064a57600080fd5b506102b66106593660046151b8565b61165d565b34801561066a57600080fd5b506102b6610679366004614e8c565b6116c1565b34801561068a57600080fd5b50610494610699366004614c6c565b6117d7565b3480156106aa57600080fd5b506102b66106b9366004614dc5565b61185e565b3480156106ca57600080fd5b5061049461012f5481565b3480156106e157600080fd5b506102b6611a34565b3480156106f657600080fd5b506102b6610705366004614c6c565b611ab0565b34801561071657600080fd5b5061034f610725366004614ec8565b611b04565b34801561073657600080fd5b506102f8610745366004614ea4565b611b23565b34801561075657600080fd5b50610322611b4e565b34801561076b57600080fd5b506102b661077a366004614ea4565b611b5d565b34801561078b57600080fd5b50610494600081565b3480156107a057600080fd5b506102b66107af366004614d98565b611bb0565b3480156107c057600080fd5b506102b66107cf366004614c6c565b611c71565b3480156107e057600080fd5b506102b66107ef366004614d1c565b611ca1565b34801561080057600080fd5b506103a761080f366004614e8c565b611cd9565b6102b661082236600461507f565b611d49565b34801561083357600080fd5b506102b6610842366004614e8c565b611f50565b34801561085357600080fd5b50610322610862366004614e8c565b612005565b34801561087357600080fd5b506102b6610882366004614fd6565b612142565b34801561089357600080fd5b506102b66108a2366004614c6c565b61223b565b3480156108b357600080fd5b506102b66108c2366004614e8c565b612322565b3480156108d357600080fd5b506104946108e2366004614e8c565b612438565b3480156108f357600080fd5b5061012e5461043f90600160401b900463ffffffff1681565b34801561091857600080fd5b506102b661092736600461501a565b61244f565b34801561093857600080fd5b506103d4610947366004614e8c565b612676565b34801561095857600080fd5b50610494600080516020615c3783398151915281565b34801561097a57600080fd5b506102b6610989366004614ea4565b61276c565b34801561099a57600080fd5b506101305461034f906001600160a01b031681565b6102b66109bd3660046150f4565b612776565b3480156109ce57600080fd5b506102f86109dd366004614ca4565b61297e565b3480156109ee57600080fd5b5061012e5461043f90600160201b900463ffffffff1681565b348015610a1357600080fd5b506102b6610a22366004615054565b6129ba565b348015610a3357600080fd5b506102b6610a423660046151b8565b612c12565b600080516020615c37833981519152610a608133612c51565b82600080828152610136602052604090206006015460ff166003811115610a9757634e487b7160e01b600052602160045260246000fd5b1415610abe5760405162461bcd60e51b8152600401610ab5906154b3565b60405180910390fd5b7f703604f30bacc0494165473e817b003a6db41ed8c598a9ff96093768d701f0958484604051610aef9291906157f0565b60405180910390a150505050565b6000610b098133612c51565b61012e5461271090610b2890600160401b900463ffffffff16846159de565b63ffffffff161115610b3957600080fd5b5061012e805463ffffffff909216600160201b0263ffffffff60201b19909216919091179055565b60006001600160e01b031982166306fafb6760e31b1480610b865750610b8682612cb9565b80610b955750610b9582612d09565b80610ba45750610ba482612d3a565b92915050565b606060658054610bb990615b2f565b80601f0160208091040260200160405190810160405280929190818152602001828054610be590615b2f565b8015610c325780601f10610c0757610100808354040283529160200191610c32565b820191906000526020600020905b815481529060010190602001808311610c1557829003601f168201915b5050505050905090565b6000610c4782612d5f565b610ca85760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ab5565b506000908152606960205260409020546001600160a01b031690565b6000610ccf8261139f565b9050806001600160a01b0316836001600160a01b03161415610d3d5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610ab5565b336001600160a01b0382161480610d595750610d59813361297e565b610dc65760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776044820152771b995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b60421b6064820152608401610ab5565b610dd08383612d7c565b505050565b60008181526101366020526040902060070154606090610e5e576040805160018082528183019092526000916020808301908036833750506101305482519293506001600160a01b031691839150600090610e4057634e487b7160e01b600052603260045260246000fd5b6001600160a01b039092166020928302919091019091015292915050565b6000828152610136602090815260409182902060070180548351818402810184019094528084529091830182828015610ec057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ea2575b50505050509050919050565b919050565b6040805160018082528183019092526060916000919060208083019080368337019050506000848152610134602090815260408083205483526101369091528120600901548251929350600160a01b900463ffffffff1691839190610f4657634e487b7160e01b600052603260045260246000fd5b63ffffffff9092166020928302919091019091015292915050565b600054610100900460ff1680610f7a575060005460ff16155b610f965760405162461bcd60e51b8152600401610ab590615574565b600054610100900460ff16158015610fb8576000805461ffff19166101011790555b610fc28585612dea565b610fca611a34565b610fd2612e71565b610fe96000610fe46020860186614c6c565b612ee0565b61100b600080516020615c37833981519152610fe46040860160208701614c6c565b6110186020840184614c6c565b61013180546001600160a01b0319166001600160a01b03929092169190911790556110496040840160208501614c6c565b61013280546001600160a01b0319166001600160a01b039290921691909117905561012e80546001600160601b03191668fa000002ee000007d01790556110966060840160408501614c6c565b61013080546001600160a01b03199081166001600160a01b0393841617909155610133805490911691841691909117905580156110d9576000805461ff00191690555b5050505050565b600080516020615c378339815191526110f98133612c51565b600084815261013660205260409020546001600160401b03808516600160401b90920416116111525760405162461bcd60e51b815260206004820152600560248201526431b0b8101f60d91b6044820152606401610ab5565b506000928352610136602052604090922080546001600160401b03928316600160401b02600160401b600160801b031990911617905561012e805491909216600160601b02600160601b600160a01b0319909116179055565b6111b53382612eea565b6111d15760405162461bcd60e51b8152600401610ab59061560f565b610dd0838383612fb4565b600090815260c9602052604090206001015490565b600080516020615c3783398151915261120a8133612c51565b506000918252610136602052604090912060050155565b61122b8282613142565b600082815260fb60205260409020610dd0908261315f565b600061124f8133612c51565b611267600080516020615c3783398151915283611221565b6101325461128d90600080516020615c37833981519152906001600160a01b031661276c565b5061013280546001600160a01b0319166001600160a01b0392909216919091179055565b6112bb8282613174565b600082815260fb60205260409020610dd090826131ee565b600080516020615c378339815191526112ec8133612c51565b816112f681613203565b61132d5760405162461bcd60e51b8152602060048201526008602482015267216f6e676f696e6760c01b6044820152606401610ab5565b60008381526101366020908152604091829020600601805460ff1916600317905590518481527f4616a0782e5635981b28be1cd36934a60655b462c370d8bd8092c969abc990d091015b60405180910390a1505050565b610dd083838360405180602001604052806000815250611ca1565b6000818152606760205260408120546001600160a01b031680610ba45760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610ab5565b610136602052600090815260409020805460018201546002830154600384015460048501805463ffffffff80871697600160201b8804909116966001600160401b03600160401b8204811697600160801b808404831698600160c01b909404909216966001600160801b0380831697939092049091169460ff8416946001600160a01b036101009095048516949290921692906114b290615b2f565b80601f01602080910402602001604051908101604052809291908181526020018280546114de90615b2f565b801561152b5780601f106115005761010080835404028352916020019161152b565b820191906000526020600020905b81548152906001019060200180831161150e57829003601f168201915b50505050600583015460068401546040805160078701805460a06020820284018101909452608083018181529798959760ff909516965091939092849284918401828280156115a357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611585575b505050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561162757602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116115ea5790505b5050509183525050600291909101546001600160a01b0381166020830152600160a01b900463ffffffff1660409091015290508e565b60006116698133612c51565b61012e546127109061168890600160201b900463ffffffff16846159de565b63ffffffff16111561169957600080fd5b5061012e805463ffffffff909216600160401b0263ffffffff60401b19909216919091179055565b600080516020615c378339815191526116da8133612c51565b600082815261013660205260409020600101546001600160801b03166116ff81613265565b61171b5760405162461bcd60e51b8152600401610ab5906156e9565b60036000848152610136602052604090206006015460ff16600381111561175257634e487b7160e01b600052602160045260246000fd5b146117895760405162461bcd60e51b8152602060048201526007602482015266085c185d5cd95960ca1b6044820152606401610ab5565b60008381526101366020908152604091829020600601805460ff1916600217905590518481527fdcba7a000ef2740d4daa9c60f3235ec53ea38eb4164b31d5470f76e01e52d7bd9101611377565b60006001600160a01b0382166118425760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610ab5565b506001600160a01b031660009081526068602052604090205490565b600080516020615c378339815191526118778133612c51565b61012f546000818152610136602090815260409091206002018054610100600160a81b0319166101006001600160a01b038916021790556118ba908501856151d2565b6000828152610136602090815260409182902080546001600160401b0394909416600160401b02600160401b600160801b03199094169390931790925561190691908601908601614faf565b600082815261013660205260409081902060010180546001600160801b03938416600160801b029316929092179091556119dc90829061194c9060608801908801614c6c565b61195960808801886158dc565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050505060a08801356119a260e08a0160c08b016151b8565b6119b36101008b0160e08c016151b8565b6119c56101208c016101008d016151d2565b6119d76101408d016101208e01614faf565b613287565b611a27816119ed60608701876158dc565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506133af92505050565b6110d98161092785615abd565b600054610100900460ff1680611a4d575060005460ff16155b611a695760405162461bcd60e51b8152600401610ab590615574565b600054610100900460ff16158015611a8b576000805461ffff19166101011790555b611a9b632dde656160e21b6134c2565b8015611aad576000805461ff00191690555b50565b6000611abc8133612c51565b611ac7600083611221565b61013154611ae0906000906001600160a01b031661276c565b5061013180546001600160a01b0319166001600160a01b0392909216919091179055565b600082815260fb60205260408120611b1c9083613540565b9392505050565b600091825260c9602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060668054610bb990615b2f565b600080516020615c37833981519152611b768133612c51565b506000918252610136602052604090912060020180546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b6001600160a01b038216331415611c055760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b6044820152606401610ab5565b336000818152606a602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6000611c7d8133612c51565b5061013080546001600160a01b0319166001600160a01b0392909216919091179055565b611cab3383612eea565b611cc75760405162461bcd60e51b8152600401610ab59061560f565b611cd38484848461354c565b50505050565b604080516001808252818301909252606091600091906020808301908036833750505060008481526101346020908152604080832054835261013690915281206009015482519293506001600160a01b031691839190610e4057634e487b7160e01b600052603260045260246000fd5b600261012d541415611d6d5760405162461bcd60e51b8152600401610ab5906156b2565b600261012d55600086815261013660205260409020548690869063ffffffff8216600160401b9091046001600160401b03161015611dbd5760405162461bcd60e51b8152600401610ab59061568e565b611dc98887868661357f565b15611e755760008881526101376020908152604080832033845290915290205463ffffffff80881691611dfe918a91166159de565b63ffffffff161115611e225760405162461bcd60e51b8152600401610ab590615660565b60008881526101376020908152604080832033845290915281208054899290611e5290849063ffffffff166159de565b92506101000a81548163ffffffff021916908363ffffffff160217905550611e9a565b611e7e88613203565b611e9a5760405162461bcd60e51b8152600401610ab590615528565b60008881526101366020526040902054600160c01b90046001600160401b03161580611eeb575060008881526101366020526040902054600160c01b90046001600160401b031663ffffffff881611155b611f075760405162461bcd60e51b8152600401610ab5906155c2565b6000888152610136602052604090206002015461010090046001600160a01b0316611f3489898884613646565b611f3f89893361381b565b5050600161012d5550505050505050565b6000611f5c8133612c51565b81600080828152610136602052604090206006015460ff166003811115611f9357634e487b7160e01b600052602160045260246000fd5b1415611fb15760405162461bcd60e51b8152600401610ab5906154b3565b6000838152610136602052604090206002015460ff1615611fe45760405162461bcd60e51b8152600401610ab5906155ef565b5050600090815261013660205260409020600201805460ff19166001179055565b606061201082612d5f565b6120485760405162461bcd60e51b8152602060048201526009602482015268746f6b656e20646e6560b81b6044820152606401610ab5565b6000828152610134602090815260408083205483526101369091528120600401805461207390615b2f565b80601f016020809104026020016040519081016040528092919081815260200182805461209f90615b2f565b80156120ec5780601f106120c1576101008083540402835291602001916120ec565b820191906000526020600020905b8154815290600101906020018083116120cf57829003601f168201915b5050505050905060008151116121115760405180602001604052806000815250611b1c565b8061211b84613aa7565b60405160200161212c929190615329565b6040516020818303038152906040529392505050565b600080516020615c3783398151915261215b8133612c51565b82600080828152610136602052604090206006015460ff16600381111561219257634e487b7160e01b600052602160045260246000fd5b14156121b05760405162461bcd60e51b8152600401610ab5906154b3565b6000848152610136602052604090206002015460ff16156121e35760405162461bcd60e51b8152600401610ab5906155ef565b6000848152610136602090815260409091208451612209926004909201918601906147de565b507f36ab8e0ce3828485b4d98e97c3f5851331257ffe2b61a43e7e0e9875242f96378484604051610aef9291906157f0565b3360009081526101356020526040902054806122845760405162461bcd60e51b8152602060048201526008602482015267216372656469747360c01b6044820152606401610ab5565b3360009081526101356020526040808220829055516001600160a01b03841690614e2090849084818181858888f193505050503d80600081146122e3576040519150601f19603f3d011682016040523d82523d6000602084013e6122e8565b606091505b5050905080610dd05760405162461bcd60e51b815260206004820152600660248201526519985a5b195960d21b6044820152606401610ab5565b600080516020615c3783398151915261233b8133612c51565b600082815261013660205260409020600101546001600160801b031661236081613265565b61237c5760405162461bcd60e51b8152600401610ab5906156e9565b60016000848152610136602052604090206006015460ff1660038111156123b357634e487b7160e01b600052602160045260246000fd5b146123ea5760405162461bcd60e51b81526020600482015260076024820152661cdd185c9d195960ca1b6044820152606401610ab5565b60008381526101366020908152604091829020600601805460ff1916600217905590518481527fa78c547613f6306e7a70d1bd161c18a496cae1eeb8d4f9e58b60d69ad72ddf589101611377565b600081815260fb60205260408120610ba490613bc0565b600080516020615c378339815191526124688133612c51565b6000838152610136602052604081206006015460ff16600381111561249d57634e487b7160e01b600052602160045260246000fd5b14156124bb5760405162461bcd60e51b8152600401610ab5906154b3565b6124cd82602001518360000151613bca565b6125035760405162461bcd60e51b81526020600482015260076024820152667072696d61727960c81b6044820152606401610ab5565b604080830151815160808101835260208086015182528551908201526060808301516001600160a01b0316828501529282015163ffffffff168382015291840151909190156125ea576101335482516020840151604051633b00fbc160e11b81526001600160a01b0390931692637601f782926125899290916000908190600401615440565b602060405180830381600087803b1580156125a357600080fd5b505af11580156125b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125db9190614c88565b6001600160a01b031660408201525b600085815261013660209081526040909120825180518493600790930192612616928492910190614862565b50602082810151805161262f92600185019201906148b7565b5060408201516002909101805460609093015163ffffffff16600160a01b026001600160c01b03199093166001600160a01b03909216919091179190911790555050505050565b600081815261013660205260409020600801546060906126de5760408051600180825281830190925260009160208083019080368337505061012e54825192935063ffffffff1691839150600090610f4657634e487b7160e01b600052603260045260246000fd5b6000828152610136602090815260409182902060080180548351818402810184019094528084529091830182828015610ec057602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612725575094979650505050505050565b6112bb8282613ca6565b600261012d54141561279a5760405162461bcd60e51b8152600401610ab5906156b2565b600261012d55600087815261013660205260409020548790879063ffffffff8216600160401b9091046001600160401b031610156127ea5760405162461bcd60e51b8152600401610ab59061568e565b6127f68988878761357f565b156128a25760008981526101376020908152604080832033845290915290205463ffffffff8089169161282b918b91166159de565b63ffffffff16111561284f5760405162461bcd60e51b8152600401610ab590615660565b600089815261013760209081526040808320338452909152812080548a929061287f90849063ffffffff166159de565b92506101000a81548163ffffffff021916908363ffffffff1602179055506128c7565b6128ab89613203565b6128c75760405162461bcd60e51b8152600401610ab590615528565b60008981526101366020526040902054600160c01b90046001600160401b03161580612918575060008981526101366020526040902054600160c01b90046001600160401b031663ffffffff891611155b6129345760405162461bcd60e51b8152600401610ab5906155c2565b6000898152610136602052604090206002015461010090046001600160a01b03166129618a8a8984613646565b61296c8a8a8661381b565b5050600161012d555050505050505050565b6001600160a01b038083166000908152606a6020908152604080832093851683529290529081205460ff1680611b1c5750611b1c600083611b23565b600261012d5414156129de5760405162461bcd60e51b8152600401610ab5906156b2565b600261012d556129ed82613cc3565b806129fc57506129fc82613203565b612a3e5760405162461bcd60e51b81526020600482015260136024820152726e6f74207072652f7075626c69632073616c6560681b6044820152606401610ab5565b610132546001600160a01b0316331480612a7757506000828152610136602052604090206002015461010090046001600160a01b031633145b612ab25760405162461bcd60e51b815260206004820152600c60248201526b1d5b985d5d1a1bdc9a5e995960a21b6044820152606401610ab5565b610132546001600160a01b0316331415612b58576000828152610136602052604090205463ffffffff600160201b90910481169082161115612b065760405162461bcd60e51b8152600401610ab59061568e565b6000828152610136602052604090208054829190600490612b35908490600160201b900463ffffffff16615a98565b92506101000a81548163ffffffff021916908363ffffffff160217905550612bfd565b6000828152610136602052604090206002015461010090046001600160a01b0316331415612bfd576000828152610136602052604090205463ffffffff9081169082161115612bb95760405162461bcd60e51b8152600401610ab59061568e565b6000828152610136602052604081208054839290612bde90849063ffffffff16615a98565b92506101000a81548163ffffffff021916908363ffffffff1602179055505b612c0882823361381b565b5050600161012d55565b6000612c1e8133612c51565b6127108263ffffffff161115612c3357600080fd5b5061012e805463ffffffff191663ffffffff92909216919091179055565b612c5b8282611b23565b612cb557612c73816001600160a01b03166014613d03565b612c7e836020613d03565b604051602001612c8f929190615381565b60408051601f198184030181529082905262461bcd60e51b8252610ab5916004016154a0565b5050565b60006001600160e01b031982166380ac58cd60e01b1480612cea57506001600160e01b03198216635b5e139f60e01b145b80610ba457506301ffc9a760e01b6001600160e01b0319831614610ba4565b6000612d1482612cb9565b80610ba45750506001600160e01b03191660009081526097602052604090205460ff1690565b60006001600160e01b03198216635a05180f60e01b1480610ba45750610ba482613ee4565b6000908152606760205260409020546001600160a01b0316151590565b600081815260696020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612db18261139f565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600054610100900460ff1680612e03575060005460ff16155b612e1f5760405162461bcd60e51b8152600401610ab590615574565b600054610100900460ff16158015612e41576000805461ffff19166101011790555b612e49613f09565b612e51613f09565b612e5b8383613f73565b8015610dd0576000805461ff0019169055505050565b600054610100900460ff1680612e8a575060005460ff16155b612ea65760405162461bcd60e51b8152600401610ab590615574565b600054610100900460ff16158015612ec8576000805461ffff19166101011790555b612ed0613f09565b612ed8613f09565b611a9b613f09565b61122b8282614008565b6000612ef582612d5f565b612f565760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ab5565b6000612f618361139f565b9050806001600160a01b0316846001600160a01b03161480612f9c5750836001600160a01b0316612f9184610c3c565b6001600160a01b0316145b80612fac5750612fac818561297e565b949350505050565b826001600160a01b0316612fc78261139f565b6001600160a01b03161461302f5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610ab5565b6001600160a01b0382166130915760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610ab5565b61309c600082612d7c565b6001600160a01b03831660009081526068602052604081208054600192906130c5908490615a81565b90915550506001600160a01b03821660009081526068602052604081208054600192906130f39084906159c6565b909155505060008181526067602052604080822080546001600160a01b0319166001600160a01b038681169182179092559151849391871691600080516020615c5783398151915291a4505050565b61314b826111dc565b6131558133612c51565b610dd0838361400e565b6000611b1c836001600160a01b038416614094565b6001600160a01b03811633146131e45760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610ab5565b612cb582826140e3565b6000611b1c836001600160a01b03841661414a565b600060026000838152610136602052604090206006015460ff16600381111561323c57634e487b7160e01b600052602160045260246000fd5b148015610ba4575060008281526101366020526040902060010154610ba4906001600160801b03165b600042826001600160801b03161180610ba45750506001600160801b03161590565b8061329181613265565b6132ad5760405162461bcd60e51b8152600401610ab5906156e9565b6132b78989614267565b60008981526101366020908152604090912088516132dd926004909201918a01906147de565b5085156132fa576000898152610136602052604090206005018690555b600089815261013660205260409020805463ffffffff868116600160201b026001600160401b0319909216908816171790556001600160401b038316156133695760008981526101366020526040902080546001600160c01b0316600160c01b6001600160401b038616021790555b6001600160801b038216156133a45760008981526101366020526040902060010180546001600160801b0319166001600160801b0384161790555b505050505050505050565b600082815261013660205260409020600681018054600160ff1990911617905561012e80548254600160801b600160c01b031916600160601b918290046001600160401b03908116600160801b0291909117938490558254600160401b909404811693849392600c926134269286929004166159fd565b92506101000a8154816001600160401b0302191690836001600160401b0316021790555061012f600081548092919061345e90615b8c565b90915550506000838152610136602052604090819020600281015491517f97660d9bc329402e809d4aabb7261513a7d331d8762d407be7e3316d08d188fd926113779287926101009092046001600160a01b03169186918891600490910190615708565b6001600160e01b0319808216141561351b5760405162461bcd60e51b815260206004820152601c60248201527b115490cc4d8d4e881a5b9d985b1a59081a5b9d195c999858d9481a5960221b6044820152606401610ab5565b6001600160e01b0319166000908152609760205260409020805460ff19166001179055565b6000611b1c83836142a7565b613557848484612fb4565b613563848484846142df565b611cd35760405162461bcd60e51b8152600401610ab5906154d6565b600061358a85613cc3565b801561359557508115155b801561363d575061363d6135ec338663ffffffff166040516001600160601b0319606084901b1660208201526034810182905260009060540160405160208183030381529060405280519060200120905092915050565b6101366000888152602001908152602001600020600501548585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506143e992505050565b95945050505050565b60008481526101366020526040902060038101546001909101546001600160a01b0390911690600160801b90046001600160801b03168161370a5783156136c25760405162461bcd60e51b815260206004820152601060248201526f0746f6b656e416d6f756e7420213d20360841b6044820152606401610ab5565b6136d28163ffffffff8716615a33565b6001600160801b031634146136f95760405162461bcd60e51b8152600401610ab59061554d565b613705868334866143f6565b613813565b34156137495760405162461bcd60e51b815260206004820152600e60248201526d06574682076616c756520213d20360941b6044820152606401610ab5565b6137598163ffffffff8716615a33565b6001600160801b031684146137805760405162461bcd60e51b8152600401610ab59061554d565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038316906323b872dd90606401602060405180830381600087803b1580156137ce57600080fd5b505af11580156137e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138069190614e70565b50613813868386866143f6565b505050505050565b600083815261013660205260408120546001600160401b03600160801b8204811692600160401b90920416905b8463ffffffff168161ffff161015613a16576000826001600160401b0316116138a45760405162461bcd60e51b815260206004820152600e60248201526d07175616e74697479203e206361760941b6044820152606401610ab5565b6138c4846138b661ffff84168661599b565b6001600160801b03166144e8565b8561013460006138d861ffff85168761599b565b6001600160801b031681526020019081526020016000208190555060004342418560405160200161393c9493929190938452602084019290925260601b6001600160601b031916604083015260c01b6001600160c01b0319166054820152605c0190565b60408051808303601f19018152918152815160209283012060008a81526101369093529120600201549091507fbe53bef0e08aa61aa51091a6fa77b4a68c6da179f64097fa01f92beda583eecc90889061010090046001600160a01b0316876139a961ffff87168961599b565b604080519485526001600160a01b03938416602086015291909216908301526001600160801b031660608201526001600160401b038516608082015260a0810183905260c00160405180910390a1613a0083615b0c565b9250508080613a0e90615b6a565b915050613848565b50600085815261013660205260409020805463ffffffff86169190601090613a4f908490600160801b90046001600160401b03166159fd565b82546101009290920a6001600160401b03818102199093169183160217909155600096875261013660205260409096208054600160401b600160801b031916600160401b939097169290920295909517905550505050565b606081613acb5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115613af55780613adf81615b8c565b9150613aee9050600a83615a1f565b9150613acf565b6000816001600160401b03811115613b1d57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015613b47576020820181803683370190505b5090505b8415612fac57613b5c600183615a81565b9150613b69600a86615ba7565b613b749060306159c6565b60f81b818381518110613b9757634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350613bb9600a86615a1f565b9450613b4b565b6000610ba4825490565b60008151835114613c075760405162461bcd60e51b81526020600482015260076024820152661a5b9d985b1a5960ca1b6044820152606401610ab5565b6000805b8351811015613c5b57838181518110613c3457634e487b7160e01b600052603260045260246000fd5b602002602001015182613c4791906159de565b915080613c5381615b8c565b915050613c0b565b506127108163ffffffff161115613c9c5760405162461bcd60e51b8152602060048201526005602482015264313839901f60d91b6044820152606401610ab5565b5060019392505050565b613caf826111dc565b613cb98133612c51565b610dd083836140e3565b600060016000838152610136602052604090206006015460ff166003811115613cfc57634e487b7160e01b600052602160045260246000fd5b1492915050565b60606000613d12836002615a62565b613d1d9060026159c6565b6001600160401b03811115613d4257634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015613d6c576020820181803683370190505b509050600360fc1b81600081518110613d9557634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613dd257634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506000613df6846002615a62565b613e019060016159c6565b90505b6001811115613e95576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613e4357634e487b7160e01b600052603260045260246000fd5b1a60f81b828281518110613e6757634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c93613e8e81615af5565b9050613e04565b508315611b1c5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610ab5565b60006001600160e01b03198216637965db0b60e01b1480610ba45750610ba482612d09565b600054610100900460ff1680613f22575060005460ff16155b613f3e5760405162461bcd60e51b8152600401610ab590615574565b600054610100900460ff16158015611a9b576000805461ffff19166101011790558015611aad576000805461ff001916905550565b600054610100900460ff1680613f8c575060005460ff16155b613fa85760405162461bcd60e51b8152600401610ab590615574565b600054610100900460ff16158015613fca576000805461ffff19166101011790555b8251613fdd9060659060208601906147de565b508151613ff19060669060208501906147de565b508015610dd0576000805461ff0019169055505050565b612cb582825b6140188282611b23565b612cb557600082815260c9602090815260408083206001600160a01b03851684529091529020805460ff191660011790556140503390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008181526001830160205260408120546140db57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ba4565b506000610ba4565b6140ed8282611b23565b15612cb557600082815260c9602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000818152600183016020526040812054801561425d57600061416e600183615a81565b855490915060009061418290600190615a81565b90508181146142035760008660000182815481106141b057634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050808760000184815481106141e157634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255918252600188019052604090208390555b855486908061422257634e487b7160e01b600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610ba4565b6000915050610ba4565b6001600160a01b03811615612cb55760008281526101366020526040902060030180546001600160a01b0383166001600160a01b03199091161790555050565b60008260000182815481106142cc57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905092915050565b60006001600160a01b0384163b156143e157604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906143239033908990889088906004016153f0565b602060405180830381600087803b15801561433d57600080fd5b505af192505050801561436d575060408051601f3d908101601f1916820190925261436a91810190614f05565b60015b6143c7573d80801561439b576040519150601f19603f3d011682016040523d82523d6000602084013e6143a0565b606091505b5080516143bf5760405162461bcd60e51b8152600401610ab5906154d6565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612fac565b506001612fac565b6000612fac828486614608565b600061440185610dd5565b9050600061440e86612676565b90506000805b83518110156144b857600061271084838151811061444257634e487b7160e01b600052603260045260246000fd5b602002602001015163ffffffff168861445b9190615a62565b6144659190615a1f565b905061447181846159c6565b92506144a585838151811061449657634e487b7160e01b600052603260045260246000fd5b6020026020010151898361461e565b50806144b081615b8c565b915050614414565b5060006144c58287615a81565b11156144df576144df84876144da8489615a81565b61461e565b50505050505050565b6001600160a01b03821661453e5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610ab5565b61454781612d5f565b156145935760405162461bcd60e51b815260206004820152601c60248201527b115490cdcc8c4e881d1bdad95b88185b1c9958591e481b5a5b9d195960221b6044820152606401610ab5565b6001600160a01b03821660009081526068602052604081208054600192906145bc9084906159c6565b909155505060008181526067602052604080822080546001600160a01b0319166001600160a01b0386169081179091559051839290600080516020615c57833981519152908290a45050565b6000826146158584614754565b14949350505050565b6001600160a01b038216156146af5760405163a9059cbb60e01b81526001600160a01b0384811660048301526024820183905283169063a9059cbb90604401602060405180830381600087803b15801561467757600080fd5b505af115801561468b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cd39190614e70565b6000836001600160a01b031682614e2090604051600060405180830381858888f193505050503d8060008114614701576040519150601f19603f3d011682016040523d82523d6000602084013e614706565b606091505b5050905080611cd3576001600160a01b038416600090815261013560205260409020546147349083906159c6565b6001600160a01b0385166000908152610135602052604090205550505050565b600081815b84518110156147a7576147938286838151811061478657634e487b7160e01b600052603260045260246000fd5b60200260200101516147af565b91508061479f81615b8c565b915050614759565b509392505050565b60008183106147cb576000828152602084905260409020611b1c565b6000838152602083905260409020611b1c565b8280546147ea90615b2f565b90600052602060002090601f01602090048101928261480c5760008555614852565b82601f1061482557805160ff1916838001178555614852565b82800160010185558215614852579182015b82811115614852578251825591602001919060010190614837565b5061485e92915061495d565b5090565b828054828255906000526020600020908101928215614852579160200282015b8281111561485257825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614882565b828054828255906000526020600020906007016008900481019282156148525791602002820160005b8382111561492457835183826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026148e0565b80156149545782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614924565b505061485e9291505b5b8082111561485e576000815560010161495e565b60006001600160401b0383111561498b5761498b615be7565b61499e601f8401601f1916602001615948565b90508281528383830111156149b257600080fd5b828260208301376000602084830101529392505050565b600082601f8301126149d9578081fd5b813560206149ee6149e983615978565b615948565b80838252828201915082860187848660051b8901011115614a0d578586fd5b855b85811015614a34578135614a2281615bfd565b84529284019290840190600101614a0f565b5090979650505050505050565b60008083601f840112614a52578182fd5b5081356001600160401b03811115614a68578182fd5b6020830191508360208260051b8501011115614a8357600080fd5b9250929050565b600082601f830112614a9a578081fd5b81356020614aaa6149e983615978565b80838252828201915082860187848660051b8901011115614ac9578586fd5b855b85811015614a3457614adc82614c41565b84529284019290840190600101614acb565b8035610ecc81615c12565b600082601f830112614b09578081fd5b611b1c83833560208501614972565b600060808284031215614b29578081fd5b614b31615920565b905081356001600160401b0380821115614b4a57600080fd5b614b5685838601614a8a565b83526020840135915080821115614b6c57600080fd5b614b78858386016149c9565b60208401526040840135915080821115614b9157600080fd5b50614b9e84828501614bbb565b604083015250614bb060608301614aee565b606082015292915050565b600060808284031215614bcc578081fd5b614bd4615920565b905081356001600160401b0380821115614bed57600080fd5b614bf9858386016149c9565b83526020840135915080821115614c0f57600080fd5b50614c1c84828501614a8a565b602083015250614c2e60408301614c41565b60408201526060820135614bb081615bfd565b803563ffffffff81168114610ecc57600080fd5b80356001600160401b0381168114610ecc57600080fd5b600060208284031215614c7d578081fd5b8135611b1c81615bfd565b600060208284031215614c99578081fd5b8151611b1c81615bfd565b60008060408385031215614cb6578081fd5b8235614cc181615bfd565b91506020830135614cd181615bfd565b809150509250929050565b600080600060608486031215614cf0578081fd5b8335614cfb81615bfd565b92506020840135614d0b81615bfd565b929592945050506040919091013590565b60008060008060808587031215614d31578182fd5b8435614d3c81615bfd565b93506020850135614d4c81615bfd565b92506040850135915060608501356001600160401b03811115614d6d578182fd5b8501601f81018713614d7d578182fd5b614d8c87823560208401614972565b91505092959194509250565b60008060408385031215614daa578182fd5b8235614db581615bfd565b91506020830135614cd181615c12565b600080600060608486031215614dd9578081fd5b8335614de481615bfd565b925060208401356001600160401b0380821115614dff578283fd5b908501906101408288031215614e13578283fd5b90925060408501359080821115614e28578283fd5b50840160808187031215614e3a578182fd5b809150509250925092565b60008060408385031215614e57578182fd5b8235614e6281615bfd565b946020939093013593505050565b600060208284031215614e81578081fd5b8151611b1c81615c12565b600060208284031215614e9d578081fd5b5035919050565b60008060408385031215614eb6578182fd5b823591506020830135614cd181615bfd565b60008060408385031215614eda578182fd5b50508035926020909101359150565b600060208284031215614efa578081fd5b8135611b1c81615c20565b600060208284031215614f16578081fd5b8151611b1c81615c20565b60008060008084860360c0811215614f37578283fd5b85356001600160401b0380821115614f4d578485fd5b614f5989838a01614af9565b96506020880135915080821115614f6e578485fd5b50614f7b88828901614af9565b9450506060603f1982011215614f8f578283fd5b5060408501915060a0850135614fa481615bfd565b939692955090935050565b600060208284031215614fc0578081fd5b81356001600160801b0381168114611b1c578182fd5b60008060408385031215614fe8578182fd5b8235915060208301356001600160401b03811115615004578182fd5b61501085828601614af9565b9150509250929050565b6000806040838503121561502c578182fd5b8235915060208301356001600160401b03811115615048578182fd5b61501085828601614b18565b60008060408385031215615066578182fd5b8235915061507660208401614c41565b90509250929050565b60008060008060008060a08789031215615097578384fd5b863595506150a760208801614c41565b94506150b560408801614c41565b93506060870135925060808701356001600160401b038111156150d6578283fd5b6150e289828a01614a41565b979a9699509497509295939492505050565b600080600080600080600060c0888a03121561510e578485fd5b8735965061511e60208901614c41565b955061512c60408901614c41565b94506060880135935060808801356001600160401b0381111561514d578182fd5b6151598a828b01614a41565b90945092505060a088013561516d81615bfd565b8091505092959891949750929550565b600080600060608486031215615191578081fd5b833592506151a160208501614c55565b91506151af60408501614c55565b90509250925092565b6000602082840312156151c9578081fd5b611b1c82614c41565b6000602082840312156151e3578081fd5b611b1c82614c55565b6001600160a01b03169052565b6000815180845260208085019450808401835b838110156152315781516001600160a01b03168752958201959082019060010161520c565b509495945050505050565b6000815180845260208085019450808401835b8381101561523157815163ffffffff168752958201959082019060010161524f565b60008151808452615289816020860160208601615ac9565b601f01601f19169290920160200192915050565b600481106152bb57634e487b7160e01b600052602160045260246000fd5b9052565b60008151608084526152d460808501826151f9565b9050602083015184820360208601526152ed828261523c565b6040858101516001600160a01b03169087015260609485015163ffffffff169490950193909352509192915050565b6001600160801b03169052565b6000835161533b818460208801615ac9565b8083019050602f60f81b808252845161535b816001850160208901615ac9565b6001920191820152693a37b5b2b7173539b7b760b11b6002820152600c01949350505050565b76020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8152600083516153b3816017850160208801615ac9565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516153e4816028840160208801615ac9565b01602801949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061542390830184615271565b9695505050505050565b602081526000611b1c60208301846151f9565b60808152600061545360808301876151f9565b8281036020840152615465818761523c565b63ffffffff95909516604084015250506001600160a01b039190911660609091015292915050565b602081526000611b1c602083018461523c565b602081526000611b1c6020830184615271565b602080825260099082015268085c1c995c185c995960ba1b604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252600b908201526a756e617661696c61626c6560a81b604082015260600190565b6020808252600d908201526c0908084f48195e1c1958dd1959609a1b604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252601390820152720f881b585e141d5c98da185cd9505b5bdd5b9d606a1b604082015260600190565b6020808252600690820152651b1bd8dad95960d21b604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601490820152730f881dda1a5d195b1a5cdd195908185b5bdd5b9d60621b604082015260600190565b6020808252600a908201526938bab0b73a34ba3c901f60b11b604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b602080825260059082015264195b99195960da1b604082015260600190565b8581526001600160a01b0385166020808301919091526001600160401b038516604083015260a0606083018190526000919061574690840186615271565b838103608085015284548390600181811c908083168061576757607f831692505b86831081141561578557634e487b7160e01b88526022600452602488fd5b8286526020860195508080156157a257600181146157b3576157dd565b60ff198516875287870195506157dd565b60008b815260209020895b858110156157d7578154898201529084019089016157be565b88019650505b50939d9c50505050505050505050505050565b828152604060208201526000612fac6040830184615271565b63ffffffff8f811682528e1660208201526001600160401b038d1660408201526001600160401b038c1660608201526001600160401b038b16608082015261585460a082018b61531c565b61586160c082018a61531c565b87151560e08201526158776101008201886151ec565b6158856101208201876151ec565b6101c0610140820152600061589e6101c0830187615271565b856101608401526158b361018084018661529d565b8281036101a08401526158c681856152bf565b9150509f9e505050505050505050505050505050565b6000808335601e198436030181126158f2578283fd5b8301803591506001600160401b0382111561590b578283fd5b602001915036819003821315614a8357600080fd5b604051608081016001600160401b038111828210171561594257615942615be7565b60405290565b604051601f8201601f191681016001600160401b038111828210171561597057615970615be7565b604052919050565b60006001600160401b0382111561599157615991615be7565b5060051b60200190565b60006001600160801b038281168482168083038211156159bd576159bd615bbb565b01949350505050565b600082198211156159d9576159d9615bbb565b500190565b600063ffffffff8083168185168083038211156159bd576159bd615bbb565b60006001600160401b038281168482168083038211156159bd576159bd615bbb565b600082615a2e57615a2e615bd1565b500490565b60006001600160801b0382811684821681151582840482111615615a5957615a59615bbb565b02949350505050565b6000816000190483118215151615615a7c57615a7c615bbb565b500290565b600082821015615a9357615a93615bbb565b500390565b600063ffffffff83811690831681811015615ab557615ab5615bbb565b039392505050565b6000610ba43683614b18565b60005b83811015615ae4578181015183820152602001615acc565b83811115611cd35750506000910152565b600081615b0457615b04615bbb565b506000190190565b60006001600160401b03821680615b2557615b25615bbb565b6000190192915050565b600181811c90821680615b4357607f821691505b60208210811415615b6457634e487b7160e01b600052602260045260246000fd5b50919050565b600061ffff80831681811415615b8257615b82615bbb565b6001019392505050565b6000600019821415615ba057615ba0615bbb565b5060010190565b600082615bb657615bb6615bd1565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114611aad57600080fd5b8015158114611aad57600080fd5b6001600160e01b031981168114611aad57600080fdfe9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220c1dc08b2a8d4ca269fdc070089575e43de6f4c2b0b0f431aa0758c58bdca470764736f6c63430008040033
Deployed Bytecode
0x6080604052600436106102915760003560e01c8063018a62a61461029657806301a94950146102b857806301ffc9a7146102d857806306fdde031461030d578063081812fc1461032f578063095ea7b3146103675780630a21a211146103875780630ebd4c7f146103b45780630f61513b146103e157806320ceaf8d1461040157806322235d691461042157806323b872dd14610454578063248a9ca3146104745780632c34c7f2146104a25780632f2ff15d146104c25780632fcfb95a146104e257806334d722c91461050257806336568abe146105235780633a66e4b61461054357806342842e0e146105635780634bde38c8146105835780634d073a5a146105a45780636352211e146105e457806366bf33be1461060457806366c083d31461063e57806368c31e261461065e57806370a082311461067e578063745ba66a1461069e5780637b4252c0146106be57806380ae4ebc146106d55780638f9f193f146106ea5780639010d07c1461070a57806391d148541461072a57806395d89b411461074a5780639aa4740e1461075f578063a217fddf1461077f578063a22cb46514610794578063aec970b0146107b4578063b88d4fde146107d4578063b9c4d9fb146107f4578063bf79e16e14610814578063c2bce59c14610827578063c87b56dd14610847578063c8950e6014610867578063c90941b114610887578063c9f2bd93146108a7578063ca15c873146108c7578063cba991bf146108e7578063ce43fcc91461090c578063ced360431461092c578063d53913931461094c578063d547741f1461096e578063deb941481461098e578063e15af0b2146109af578063e985e9c5146109c2578063eaf2115d146109e2578063f0b68ea314610a07578063fce212f314610a27575b600080fd5b3480156102a257600080fd5b506102b66102b1366004614fd6565b610a47565b005b3480156102c457600080fd5b506102b66102d33660046151b8565b610afd565b3480156102e457600080fd5b506102f86102f3366004614ee9565b610b61565b60405190151581526020015b60405180910390f35b34801561031957600080fd5b50610322610baa565b60405161030491906154a0565b34801561033b57600080fd5b5061034f61034a366004614e8c565b610c3c565b6040516001600160a01b039091168152602001610304565b34801561037357600080fd5b506102b6610382366004614e45565b610cc4565b34801561039357600080fd5b506103a76103a2366004614e8c565b610dd5565b604051610304919061542d565b3480156103c057600080fd5b506103d46103cf366004614e8c565b610ed1565b604051610304919061548d565b3480156103ed57600080fd5b506102b66103fc366004614f21565b610f61565b34801561040d57600080fd5b506102b661041c36600461517d565b6110e0565b34801561042d57600080fd5b5061012e5461043f9063ffffffff1681565b60405163ffffffff9091168152602001610304565b34801561046057600080fd5b506102b661046f366004614cdc565b6111ab565b34801561048057600080fd5b5061049461048f366004614e8c565b6111dc565b604051908152602001610304565b3480156104ae57600080fd5b506102b66104bd366004614ec8565b6111f1565b3480156104ce57600080fd5b506102b66104dd366004614ea4565b611221565b3480156104ee57600080fd5b506102b66104fd366004614c6c565b611243565b34801561050e57600080fd5b506101325461034f906001600160a01b031681565b34801561052f57600080fd5b506102b661053e366004614ea4565b6112b1565b34801561054f57600080fd5b506102b661055e366004614e8c565b6112d3565b34801561056f57600080fd5b506102b661057e366004614cdc565b611384565b34801561058f57600080fd5b506101315461034f906001600160a01b031681565b3480156105b057600080fd5b5061012e546105cc90600160601b90046001600160401b031681565b6040516001600160401b039091168152602001610304565b3480156105f057600080fd5b5061034f6105ff366004614e8c565b61139f565b34801561061057600080fd5b5061062461061f366004614e8c565b611416565b6040516103049e9d9c9b9a99989796959493929190615809565b34801561064a57600080fd5b506102b66106593660046151b8565b61165d565b34801561066a57600080fd5b506102b6610679366004614e8c565b6116c1565b34801561068a57600080fd5b50610494610699366004614c6c565b6117d7565b3480156106aa57600080fd5b506102b66106b9366004614dc5565b61185e565b3480156106ca57600080fd5b5061049461012f5481565b3480156106e157600080fd5b506102b6611a34565b3480156106f657600080fd5b506102b6610705366004614c6c565b611ab0565b34801561071657600080fd5b5061034f610725366004614ec8565b611b04565b34801561073657600080fd5b506102f8610745366004614ea4565b611b23565b34801561075657600080fd5b50610322611b4e565b34801561076b57600080fd5b506102b661077a366004614ea4565b611b5d565b34801561078b57600080fd5b50610494600081565b3480156107a057600080fd5b506102b66107af366004614d98565b611bb0565b3480156107c057600080fd5b506102b66107cf366004614c6c565b611c71565b3480156107e057600080fd5b506102b66107ef366004614d1c565b611ca1565b34801561080057600080fd5b506103a761080f366004614e8c565b611cd9565b6102b661082236600461507f565b611d49565b34801561083357600080fd5b506102b6610842366004614e8c565b611f50565b34801561085357600080fd5b50610322610862366004614e8c565b612005565b34801561087357600080fd5b506102b6610882366004614fd6565b612142565b34801561089357600080fd5b506102b66108a2366004614c6c565b61223b565b3480156108b357600080fd5b506102b66108c2366004614e8c565b612322565b3480156108d357600080fd5b506104946108e2366004614e8c565b612438565b3480156108f357600080fd5b5061012e5461043f90600160401b900463ffffffff1681565b34801561091857600080fd5b506102b661092736600461501a565b61244f565b34801561093857600080fd5b506103d4610947366004614e8c565b612676565b34801561095857600080fd5b50610494600080516020615c3783398151915281565b34801561097a57600080fd5b506102b6610989366004614ea4565b61276c565b34801561099a57600080fd5b506101305461034f906001600160a01b031681565b6102b66109bd3660046150f4565b612776565b3480156109ce57600080fd5b506102f86109dd366004614ca4565b61297e565b3480156109ee57600080fd5b5061012e5461043f90600160201b900463ffffffff1681565b348015610a1357600080fd5b506102b6610a22366004615054565b6129ba565b348015610a3357600080fd5b506102b6610a423660046151b8565b612c12565b600080516020615c37833981519152610a608133612c51565b82600080828152610136602052604090206006015460ff166003811115610a9757634e487b7160e01b600052602160045260246000fd5b1415610abe5760405162461bcd60e51b8152600401610ab5906154b3565b60405180910390fd5b7f703604f30bacc0494165473e817b003a6db41ed8c598a9ff96093768d701f0958484604051610aef9291906157f0565b60405180910390a150505050565b6000610b098133612c51565b61012e5461271090610b2890600160401b900463ffffffff16846159de565b63ffffffff161115610b3957600080fd5b5061012e805463ffffffff909216600160201b0263ffffffff60201b19909216919091179055565b60006001600160e01b031982166306fafb6760e31b1480610b865750610b8682612cb9565b80610b955750610b9582612d09565b80610ba45750610ba482612d3a565b92915050565b606060658054610bb990615b2f565b80601f0160208091040260200160405190810160405280929190818152602001828054610be590615b2f565b8015610c325780601f10610c0757610100808354040283529160200191610c32565b820191906000526020600020905b815481529060010190602001808311610c1557829003601f168201915b5050505050905090565b6000610c4782612d5f565b610ca85760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ab5565b506000908152606960205260409020546001600160a01b031690565b6000610ccf8261139f565b9050806001600160a01b0316836001600160a01b03161415610d3d5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610ab5565b336001600160a01b0382161480610d595750610d59813361297e565b610dc65760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776044820152771b995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b60421b6064820152608401610ab5565b610dd08383612d7c565b505050565b60008181526101366020526040902060070154606090610e5e576040805160018082528183019092526000916020808301908036833750506101305482519293506001600160a01b031691839150600090610e4057634e487b7160e01b600052603260045260246000fd5b6001600160a01b039092166020928302919091019091015292915050565b6000828152610136602090815260409182902060070180548351818402810184019094528084529091830182828015610ec057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ea2575b50505050509050919050565b919050565b6040805160018082528183019092526060916000919060208083019080368337019050506000848152610134602090815260408083205483526101369091528120600901548251929350600160a01b900463ffffffff1691839190610f4657634e487b7160e01b600052603260045260246000fd5b63ffffffff9092166020928302919091019091015292915050565b600054610100900460ff1680610f7a575060005460ff16155b610f965760405162461bcd60e51b8152600401610ab590615574565b600054610100900460ff16158015610fb8576000805461ffff19166101011790555b610fc28585612dea565b610fca611a34565b610fd2612e71565b610fe96000610fe46020860186614c6c565b612ee0565b61100b600080516020615c37833981519152610fe46040860160208701614c6c565b6110186020840184614c6c565b61013180546001600160a01b0319166001600160a01b03929092169190911790556110496040840160208501614c6c565b61013280546001600160a01b0319166001600160a01b039290921691909117905561012e80546001600160601b03191668fa000002ee000007d01790556110966060840160408501614c6c565b61013080546001600160a01b03199081166001600160a01b0393841617909155610133805490911691841691909117905580156110d9576000805461ff00191690555b5050505050565b600080516020615c378339815191526110f98133612c51565b600084815261013660205260409020546001600160401b03808516600160401b90920416116111525760405162461bcd60e51b815260206004820152600560248201526431b0b8101f60d91b6044820152606401610ab5565b506000928352610136602052604090922080546001600160401b03928316600160401b02600160401b600160801b031990911617905561012e805491909216600160601b02600160601b600160a01b0319909116179055565b6111b53382612eea565b6111d15760405162461bcd60e51b8152600401610ab59061560f565b610dd0838383612fb4565b600090815260c9602052604090206001015490565b600080516020615c3783398151915261120a8133612c51565b506000918252610136602052604090912060050155565b61122b8282613142565b600082815260fb60205260409020610dd0908261315f565b600061124f8133612c51565b611267600080516020615c3783398151915283611221565b6101325461128d90600080516020615c37833981519152906001600160a01b031661276c565b5061013280546001600160a01b0319166001600160a01b0392909216919091179055565b6112bb8282613174565b600082815260fb60205260409020610dd090826131ee565b600080516020615c378339815191526112ec8133612c51565b816112f681613203565b61132d5760405162461bcd60e51b8152602060048201526008602482015267216f6e676f696e6760c01b6044820152606401610ab5565b60008381526101366020908152604091829020600601805460ff1916600317905590518481527f4616a0782e5635981b28be1cd36934a60655b462c370d8bd8092c969abc990d091015b60405180910390a1505050565b610dd083838360405180602001604052806000815250611ca1565b6000818152606760205260408120546001600160a01b031680610ba45760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610ab5565b610136602052600090815260409020805460018201546002830154600384015460048501805463ffffffff80871697600160201b8804909116966001600160401b03600160401b8204811697600160801b808404831698600160c01b909404909216966001600160801b0380831697939092049091169460ff8416946001600160a01b036101009095048516949290921692906114b290615b2f565b80601f01602080910402602001604051908101604052809291908181526020018280546114de90615b2f565b801561152b5780601f106115005761010080835404028352916020019161152b565b820191906000526020600020905b81548152906001019060200180831161150e57829003601f168201915b50505050600583015460068401546040805160078701805460a06020820284018101909452608083018181529798959760ff909516965091939092849284918401828280156115a357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611585575b505050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561162757602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116115ea5790505b5050509183525050600291909101546001600160a01b0381166020830152600160a01b900463ffffffff1660409091015290508e565b60006116698133612c51565b61012e546127109061168890600160201b900463ffffffff16846159de565b63ffffffff16111561169957600080fd5b5061012e805463ffffffff909216600160401b0263ffffffff60401b19909216919091179055565b600080516020615c378339815191526116da8133612c51565b600082815261013660205260409020600101546001600160801b03166116ff81613265565b61171b5760405162461bcd60e51b8152600401610ab5906156e9565b60036000848152610136602052604090206006015460ff16600381111561175257634e487b7160e01b600052602160045260246000fd5b146117895760405162461bcd60e51b8152602060048201526007602482015266085c185d5cd95960ca1b6044820152606401610ab5565b60008381526101366020908152604091829020600601805460ff1916600217905590518481527fdcba7a000ef2740d4daa9c60f3235ec53ea38eb4164b31d5470f76e01e52d7bd9101611377565b60006001600160a01b0382166118425760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610ab5565b506001600160a01b031660009081526068602052604090205490565b600080516020615c378339815191526118778133612c51565b61012f546000818152610136602090815260409091206002018054610100600160a81b0319166101006001600160a01b038916021790556118ba908501856151d2565b6000828152610136602090815260409182902080546001600160401b0394909416600160401b02600160401b600160801b03199094169390931790925561190691908601908601614faf565b600082815261013660205260409081902060010180546001600160801b03938416600160801b029316929092179091556119dc90829061194c9060608801908801614c6c565b61195960808801886158dc565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050505060a08801356119a260e08a0160c08b016151b8565b6119b36101008b0160e08c016151b8565b6119c56101208c016101008d016151d2565b6119d76101408d016101208e01614faf565b613287565b611a27816119ed60608701876158dc565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506133af92505050565b6110d98161092785615abd565b600054610100900460ff1680611a4d575060005460ff16155b611a695760405162461bcd60e51b8152600401610ab590615574565b600054610100900460ff16158015611a8b576000805461ffff19166101011790555b611a9b632dde656160e21b6134c2565b8015611aad576000805461ff00191690555b50565b6000611abc8133612c51565b611ac7600083611221565b61013154611ae0906000906001600160a01b031661276c565b5061013180546001600160a01b0319166001600160a01b0392909216919091179055565b600082815260fb60205260408120611b1c9083613540565b9392505050565b600091825260c9602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060668054610bb990615b2f565b600080516020615c37833981519152611b768133612c51565b506000918252610136602052604090912060020180546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b6001600160a01b038216331415611c055760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b6044820152606401610ab5565b336000818152606a602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6000611c7d8133612c51565b5061013080546001600160a01b0319166001600160a01b0392909216919091179055565b611cab3383612eea565b611cc75760405162461bcd60e51b8152600401610ab59061560f565b611cd38484848461354c565b50505050565b604080516001808252818301909252606091600091906020808301908036833750505060008481526101346020908152604080832054835261013690915281206009015482519293506001600160a01b031691839190610e4057634e487b7160e01b600052603260045260246000fd5b600261012d541415611d6d5760405162461bcd60e51b8152600401610ab5906156b2565b600261012d55600086815261013660205260409020548690869063ffffffff8216600160401b9091046001600160401b03161015611dbd5760405162461bcd60e51b8152600401610ab59061568e565b611dc98887868661357f565b15611e755760008881526101376020908152604080832033845290915290205463ffffffff80881691611dfe918a91166159de565b63ffffffff161115611e225760405162461bcd60e51b8152600401610ab590615660565b60008881526101376020908152604080832033845290915281208054899290611e5290849063ffffffff166159de565b92506101000a81548163ffffffff021916908363ffffffff160217905550611e9a565b611e7e88613203565b611e9a5760405162461bcd60e51b8152600401610ab590615528565b60008881526101366020526040902054600160c01b90046001600160401b03161580611eeb575060008881526101366020526040902054600160c01b90046001600160401b031663ffffffff881611155b611f075760405162461bcd60e51b8152600401610ab5906155c2565b6000888152610136602052604090206002015461010090046001600160a01b0316611f3489898884613646565b611f3f89893361381b565b5050600161012d5550505050505050565b6000611f5c8133612c51565b81600080828152610136602052604090206006015460ff166003811115611f9357634e487b7160e01b600052602160045260246000fd5b1415611fb15760405162461bcd60e51b8152600401610ab5906154b3565b6000838152610136602052604090206002015460ff1615611fe45760405162461bcd60e51b8152600401610ab5906155ef565b5050600090815261013660205260409020600201805460ff19166001179055565b606061201082612d5f565b6120485760405162461bcd60e51b8152602060048201526009602482015268746f6b656e20646e6560b81b6044820152606401610ab5565b6000828152610134602090815260408083205483526101369091528120600401805461207390615b2f565b80601f016020809104026020016040519081016040528092919081815260200182805461209f90615b2f565b80156120ec5780601f106120c1576101008083540402835291602001916120ec565b820191906000526020600020905b8154815290600101906020018083116120cf57829003601f168201915b5050505050905060008151116121115760405180602001604052806000815250611b1c565b8061211b84613aa7565b60405160200161212c929190615329565b6040516020818303038152906040529392505050565b600080516020615c3783398151915261215b8133612c51565b82600080828152610136602052604090206006015460ff16600381111561219257634e487b7160e01b600052602160045260246000fd5b14156121b05760405162461bcd60e51b8152600401610ab5906154b3565b6000848152610136602052604090206002015460ff16156121e35760405162461bcd60e51b8152600401610ab5906155ef565b6000848152610136602090815260409091208451612209926004909201918601906147de565b507f36ab8e0ce3828485b4d98e97c3f5851331257ffe2b61a43e7e0e9875242f96378484604051610aef9291906157f0565b3360009081526101356020526040902054806122845760405162461bcd60e51b8152602060048201526008602482015267216372656469747360c01b6044820152606401610ab5565b3360009081526101356020526040808220829055516001600160a01b03841690614e2090849084818181858888f193505050503d80600081146122e3576040519150601f19603f3d011682016040523d82523d6000602084013e6122e8565b606091505b5050905080610dd05760405162461bcd60e51b815260206004820152600660248201526519985a5b195960d21b6044820152606401610ab5565b600080516020615c3783398151915261233b8133612c51565b600082815261013660205260409020600101546001600160801b031661236081613265565b61237c5760405162461bcd60e51b8152600401610ab5906156e9565b60016000848152610136602052604090206006015460ff1660038111156123b357634e487b7160e01b600052602160045260246000fd5b146123ea5760405162461bcd60e51b81526020600482015260076024820152661cdd185c9d195960ca1b6044820152606401610ab5565b60008381526101366020908152604091829020600601805460ff1916600217905590518481527fa78c547613f6306e7a70d1bd161c18a496cae1eeb8d4f9e58b60d69ad72ddf589101611377565b600081815260fb60205260408120610ba490613bc0565b600080516020615c378339815191526124688133612c51565b6000838152610136602052604081206006015460ff16600381111561249d57634e487b7160e01b600052602160045260246000fd5b14156124bb5760405162461bcd60e51b8152600401610ab5906154b3565b6124cd82602001518360000151613bca565b6125035760405162461bcd60e51b81526020600482015260076024820152667072696d61727960c81b6044820152606401610ab5565b604080830151815160808101835260208086015182528551908201526060808301516001600160a01b0316828501529282015163ffffffff168382015291840151909190156125ea576101335482516020840151604051633b00fbc160e11b81526001600160a01b0390931692637601f782926125899290916000908190600401615440565b602060405180830381600087803b1580156125a357600080fd5b505af11580156125b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125db9190614c88565b6001600160a01b031660408201525b600085815261013660209081526040909120825180518493600790930192612616928492910190614862565b50602082810151805161262f92600185019201906148b7565b5060408201516002909101805460609093015163ffffffff16600160a01b026001600160c01b03199093166001600160a01b03909216919091179190911790555050505050565b600081815261013660205260409020600801546060906126de5760408051600180825281830190925260009160208083019080368337505061012e54825192935063ffffffff1691839150600090610f4657634e487b7160e01b600052603260045260246000fd5b6000828152610136602090815260409182902060080180548351818402810184019094528084529091830182828015610ec057602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612725575094979650505050505050565b6112bb8282613ca6565b600261012d54141561279a5760405162461bcd60e51b8152600401610ab5906156b2565b600261012d55600087815261013660205260409020548790879063ffffffff8216600160401b9091046001600160401b031610156127ea5760405162461bcd60e51b8152600401610ab59061568e565b6127f68988878761357f565b156128a25760008981526101376020908152604080832033845290915290205463ffffffff8089169161282b918b91166159de565b63ffffffff16111561284f5760405162461bcd60e51b8152600401610ab590615660565b600089815261013760209081526040808320338452909152812080548a929061287f90849063ffffffff166159de565b92506101000a81548163ffffffff021916908363ffffffff1602179055506128c7565b6128ab89613203565b6128c75760405162461bcd60e51b8152600401610ab590615528565b60008981526101366020526040902054600160c01b90046001600160401b03161580612918575060008981526101366020526040902054600160c01b90046001600160401b031663ffffffff891611155b6129345760405162461bcd60e51b8152600401610ab5906155c2565b6000898152610136602052604090206002015461010090046001600160a01b03166129618a8a8984613646565b61296c8a8a8661381b565b5050600161012d555050505050505050565b6001600160a01b038083166000908152606a6020908152604080832093851683529290529081205460ff1680611b1c5750611b1c600083611b23565b600261012d5414156129de5760405162461bcd60e51b8152600401610ab5906156b2565b600261012d556129ed82613cc3565b806129fc57506129fc82613203565b612a3e5760405162461bcd60e51b81526020600482015260136024820152726e6f74207072652f7075626c69632073616c6560681b6044820152606401610ab5565b610132546001600160a01b0316331480612a7757506000828152610136602052604090206002015461010090046001600160a01b031633145b612ab25760405162461bcd60e51b815260206004820152600c60248201526b1d5b985d5d1a1bdc9a5e995960a21b6044820152606401610ab5565b610132546001600160a01b0316331415612b58576000828152610136602052604090205463ffffffff600160201b90910481169082161115612b065760405162461bcd60e51b8152600401610ab59061568e565b6000828152610136602052604090208054829190600490612b35908490600160201b900463ffffffff16615a98565b92506101000a81548163ffffffff021916908363ffffffff160217905550612bfd565b6000828152610136602052604090206002015461010090046001600160a01b0316331415612bfd576000828152610136602052604090205463ffffffff9081169082161115612bb95760405162461bcd60e51b8152600401610ab59061568e565b6000828152610136602052604081208054839290612bde90849063ffffffff16615a98565b92506101000a81548163ffffffff021916908363ffffffff1602179055505b612c0882823361381b565b5050600161012d55565b6000612c1e8133612c51565b6127108263ffffffff161115612c3357600080fd5b5061012e805463ffffffff191663ffffffff92909216919091179055565b612c5b8282611b23565b612cb557612c73816001600160a01b03166014613d03565b612c7e836020613d03565b604051602001612c8f929190615381565b60408051601f198184030181529082905262461bcd60e51b8252610ab5916004016154a0565b5050565b60006001600160e01b031982166380ac58cd60e01b1480612cea57506001600160e01b03198216635b5e139f60e01b145b80610ba457506301ffc9a760e01b6001600160e01b0319831614610ba4565b6000612d1482612cb9565b80610ba45750506001600160e01b03191660009081526097602052604090205460ff1690565b60006001600160e01b03198216635a05180f60e01b1480610ba45750610ba482613ee4565b6000908152606760205260409020546001600160a01b0316151590565b600081815260696020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612db18261139f565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600054610100900460ff1680612e03575060005460ff16155b612e1f5760405162461bcd60e51b8152600401610ab590615574565b600054610100900460ff16158015612e41576000805461ffff19166101011790555b612e49613f09565b612e51613f09565b612e5b8383613f73565b8015610dd0576000805461ff0019169055505050565b600054610100900460ff1680612e8a575060005460ff16155b612ea65760405162461bcd60e51b8152600401610ab590615574565b600054610100900460ff16158015612ec8576000805461ffff19166101011790555b612ed0613f09565b612ed8613f09565b611a9b613f09565b61122b8282614008565b6000612ef582612d5f565b612f565760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ab5565b6000612f618361139f565b9050806001600160a01b0316846001600160a01b03161480612f9c5750836001600160a01b0316612f9184610c3c565b6001600160a01b0316145b80612fac5750612fac818561297e565b949350505050565b826001600160a01b0316612fc78261139f565b6001600160a01b03161461302f5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610ab5565b6001600160a01b0382166130915760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610ab5565b61309c600082612d7c565b6001600160a01b03831660009081526068602052604081208054600192906130c5908490615a81565b90915550506001600160a01b03821660009081526068602052604081208054600192906130f39084906159c6565b909155505060008181526067602052604080822080546001600160a01b0319166001600160a01b038681169182179092559151849391871691600080516020615c5783398151915291a4505050565b61314b826111dc565b6131558133612c51565b610dd0838361400e565b6000611b1c836001600160a01b038416614094565b6001600160a01b03811633146131e45760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610ab5565b612cb582826140e3565b6000611b1c836001600160a01b03841661414a565b600060026000838152610136602052604090206006015460ff16600381111561323c57634e487b7160e01b600052602160045260246000fd5b148015610ba4575060008281526101366020526040902060010154610ba4906001600160801b03165b600042826001600160801b03161180610ba45750506001600160801b03161590565b8061329181613265565b6132ad5760405162461bcd60e51b8152600401610ab5906156e9565b6132b78989614267565b60008981526101366020908152604090912088516132dd926004909201918a01906147de565b5085156132fa576000898152610136602052604090206005018690555b600089815261013660205260409020805463ffffffff868116600160201b026001600160401b0319909216908816171790556001600160401b038316156133695760008981526101366020526040902080546001600160c01b0316600160c01b6001600160401b038616021790555b6001600160801b038216156133a45760008981526101366020526040902060010180546001600160801b0319166001600160801b0384161790555b505050505050505050565b600082815261013660205260409020600681018054600160ff1990911617905561012e80548254600160801b600160c01b031916600160601b918290046001600160401b03908116600160801b0291909117938490558254600160401b909404811693849392600c926134269286929004166159fd565b92506101000a8154816001600160401b0302191690836001600160401b0316021790555061012f600081548092919061345e90615b8c565b90915550506000838152610136602052604090819020600281015491517f97660d9bc329402e809d4aabb7261513a7d331d8762d407be7e3316d08d188fd926113779287926101009092046001600160a01b03169186918891600490910190615708565b6001600160e01b0319808216141561351b5760405162461bcd60e51b815260206004820152601c60248201527b115490cc4d8d4e881a5b9d985b1a59081a5b9d195c999858d9481a5960221b6044820152606401610ab5565b6001600160e01b0319166000908152609760205260409020805460ff19166001179055565b6000611b1c83836142a7565b613557848484612fb4565b613563848484846142df565b611cd35760405162461bcd60e51b8152600401610ab5906154d6565b600061358a85613cc3565b801561359557508115155b801561363d575061363d6135ec338663ffffffff166040516001600160601b0319606084901b1660208201526034810182905260009060540160405160208183030381529060405280519060200120905092915050565b6101366000888152602001908152602001600020600501548585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506143e992505050565b95945050505050565b60008481526101366020526040902060038101546001909101546001600160a01b0390911690600160801b90046001600160801b03168161370a5783156136c25760405162461bcd60e51b815260206004820152601060248201526f0746f6b656e416d6f756e7420213d20360841b6044820152606401610ab5565b6136d28163ffffffff8716615a33565b6001600160801b031634146136f95760405162461bcd60e51b8152600401610ab59061554d565b613705868334866143f6565b613813565b34156137495760405162461bcd60e51b815260206004820152600e60248201526d06574682076616c756520213d20360941b6044820152606401610ab5565b6137598163ffffffff8716615a33565b6001600160801b031684146137805760405162461bcd60e51b8152600401610ab59061554d565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038316906323b872dd90606401602060405180830381600087803b1580156137ce57600080fd5b505af11580156137e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138069190614e70565b50613813868386866143f6565b505050505050565b600083815261013660205260408120546001600160401b03600160801b8204811692600160401b90920416905b8463ffffffff168161ffff161015613a16576000826001600160401b0316116138a45760405162461bcd60e51b815260206004820152600e60248201526d07175616e74697479203e206361760941b6044820152606401610ab5565b6138c4846138b661ffff84168661599b565b6001600160801b03166144e8565b8561013460006138d861ffff85168761599b565b6001600160801b031681526020019081526020016000208190555060004342418560405160200161393c9493929190938452602084019290925260601b6001600160601b031916604083015260c01b6001600160c01b0319166054820152605c0190565b60408051808303601f19018152918152815160209283012060008a81526101369093529120600201549091507fbe53bef0e08aa61aa51091a6fa77b4a68c6da179f64097fa01f92beda583eecc90889061010090046001600160a01b0316876139a961ffff87168961599b565b604080519485526001600160a01b03938416602086015291909216908301526001600160801b031660608201526001600160401b038516608082015260a0810183905260c00160405180910390a1613a0083615b0c565b9250508080613a0e90615b6a565b915050613848565b50600085815261013660205260409020805463ffffffff86169190601090613a4f908490600160801b90046001600160401b03166159fd565b82546101009290920a6001600160401b03818102199093169183160217909155600096875261013660205260409096208054600160401b600160801b031916600160401b939097169290920295909517905550505050565b606081613acb5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115613af55780613adf81615b8c565b9150613aee9050600a83615a1f565b9150613acf565b6000816001600160401b03811115613b1d57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015613b47576020820181803683370190505b5090505b8415612fac57613b5c600183615a81565b9150613b69600a86615ba7565b613b749060306159c6565b60f81b818381518110613b9757634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350613bb9600a86615a1f565b9450613b4b565b6000610ba4825490565b60008151835114613c075760405162461bcd60e51b81526020600482015260076024820152661a5b9d985b1a5960ca1b6044820152606401610ab5565b6000805b8351811015613c5b57838181518110613c3457634e487b7160e01b600052603260045260246000fd5b602002602001015182613c4791906159de565b915080613c5381615b8c565b915050613c0b565b506127108163ffffffff161115613c9c5760405162461bcd60e51b8152602060048201526005602482015264313839901f60d91b6044820152606401610ab5565b5060019392505050565b613caf826111dc565b613cb98133612c51565b610dd083836140e3565b600060016000838152610136602052604090206006015460ff166003811115613cfc57634e487b7160e01b600052602160045260246000fd5b1492915050565b60606000613d12836002615a62565b613d1d9060026159c6565b6001600160401b03811115613d4257634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015613d6c576020820181803683370190505b509050600360fc1b81600081518110613d9557634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613dd257634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506000613df6846002615a62565b613e019060016159c6565b90505b6001811115613e95576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613e4357634e487b7160e01b600052603260045260246000fd5b1a60f81b828281518110613e6757634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c93613e8e81615af5565b9050613e04565b508315611b1c5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610ab5565b60006001600160e01b03198216637965db0b60e01b1480610ba45750610ba482612d09565b600054610100900460ff1680613f22575060005460ff16155b613f3e5760405162461bcd60e51b8152600401610ab590615574565b600054610100900460ff16158015611a9b576000805461ffff19166101011790558015611aad576000805461ff001916905550565b600054610100900460ff1680613f8c575060005460ff16155b613fa85760405162461bcd60e51b8152600401610ab590615574565b600054610100900460ff16158015613fca576000805461ffff19166101011790555b8251613fdd9060659060208601906147de565b508151613ff19060669060208501906147de565b508015610dd0576000805461ff0019169055505050565b612cb582825b6140188282611b23565b612cb557600082815260c9602090815260408083206001600160a01b03851684529091529020805460ff191660011790556140503390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008181526001830160205260408120546140db57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ba4565b506000610ba4565b6140ed8282611b23565b15612cb557600082815260c9602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000818152600183016020526040812054801561425d57600061416e600183615a81565b855490915060009061418290600190615a81565b90508181146142035760008660000182815481106141b057634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050808760000184815481106141e157634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255918252600188019052604090208390555b855486908061422257634e487b7160e01b600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610ba4565b6000915050610ba4565b6001600160a01b03811615612cb55760008281526101366020526040902060030180546001600160a01b0383166001600160a01b03199091161790555050565b60008260000182815481106142cc57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905092915050565b60006001600160a01b0384163b156143e157604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906143239033908990889088906004016153f0565b602060405180830381600087803b15801561433d57600080fd5b505af192505050801561436d575060408051601f3d908101601f1916820190925261436a91810190614f05565b60015b6143c7573d80801561439b576040519150601f19603f3d011682016040523d82523d6000602084013e6143a0565b606091505b5080516143bf5760405162461bcd60e51b8152600401610ab5906154d6565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612fac565b506001612fac565b6000612fac828486614608565b600061440185610dd5565b9050600061440e86612676565b90506000805b83518110156144b857600061271084838151811061444257634e487b7160e01b600052603260045260246000fd5b602002602001015163ffffffff168861445b9190615a62565b6144659190615a1f565b905061447181846159c6565b92506144a585838151811061449657634e487b7160e01b600052603260045260246000fd5b6020026020010151898361461e565b50806144b081615b8c565b915050614414565b5060006144c58287615a81565b11156144df576144df84876144da8489615a81565b61461e565b50505050505050565b6001600160a01b03821661453e5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610ab5565b61454781612d5f565b156145935760405162461bcd60e51b815260206004820152601c60248201527b115490cdcc8c4e881d1bdad95b88185b1c9958591e481b5a5b9d195960221b6044820152606401610ab5565b6001600160a01b03821660009081526068602052604081208054600192906145bc9084906159c6565b909155505060008181526067602052604080822080546001600160a01b0319166001600160a01b0386169081179091559051839290600080516020615c57833981519152908290a45050565b6000826146158584614754565b14949350505050565b6001600160a01b038216156146af5760405163a9059cbb60e01b81526001600160a01b0384811660048301526024820183905283169063a9059cbb90604401602060405180830381600087803b15801561467757600080fd5b505af115801561468b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cd39190614e70565b6000836001600160a01b031682614e2090604051600060405180830381858888f193505050503d8060008114614701576040519150601f19603f3d011682016040523d82523d6000602084013e614706565b606091505b5050905080611cd3576001600160a01b038416600090815261013560205260409020546147349083906159c6565b6001600160a01b0385166000908152610135602052604090205550505050565b600081815b84518110156147a7576147938286838151811061478657634e487b7160e01b600052603260045260246000fd5b60200260200101516147af565b91508061479f81615b8c565b915050614759565b509392505050565b60008183106147cb576000828152602084905260409020611b1c565b6000838152602083905260409020611b1c565b8280546147ea90615b2f565b90600052602060002090601f01602090048101928261480c5760008555614852565b82601f1061482557805160ff1916838001178555614852565b82800160010185558215614852579182015b82811115614852578251825591602001919060010190614837565b5061485e92915061495d565b5090565b828054828255906000526020600020908101928215614852579160200282015b8281111561485257825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614882565b828054828255906000526020600020906007016008900481019282156148525791602002820160005b8382111561492457835183826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026148e0565b80156149545782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614924565b505061485e9291505b5b8082111561485e576000815560010161495e565b60006001600160401b0383111561498b5761498b615be7565b61499e601f8401601f1916602001615948565b90508281528383830111156149b257600080fd5b828260208301376000602084830101529392505050565b600082601f8301126149d9578081fd5b813560206149ee6149e983615978565b615948565b80838252828201915082860187848660051b8901011115614a0d578586fd5b855b85811015614a34578135614a2281615bfd565b84529284019290840190600101614a0f565b5090979650505050505050565b60008083601f840112614a52578182fd5b5081356001600160401b03811115614a68578182fd5b6020830191508360208260051b8501011115614a8357600080fd5b9250929050565b600082601f830112614a9a578081fd5b81356020614aaa6149e983615978565b80838252828201915082860187848660051b8901011115614ac9578586fd5b855b85811015614a3457614adc82614c41565b84529284019290840190600101614acb565b8035610ecc81615c12565b600082601f830112614b09578081fd5b611b1c83833560208501614972565b600060808284031215614b29578081fd5b614b31615920565b905081356001600160401b0380821115614b4a57600080fd5b614b5685838601614a8a565b83526020840135915080821115614b6c57600080fd5b614b78858386016149c9565b60208401526040840135915080821115614b9157600080fd5b50614b9e84828501614bbb565b604083015250614bb060608301614aee565b606082015292915050565b600060808284031215614bcc578081fd5b614bd4615920565b905081356001600160401b0380821115614bed57600080fd5b614bf9858386016149c9565b83526020840135915080821115614c0f57600080fd5b50614c1c84828501614a8a565b602083015250614c2e60408301614c41565b60408201526060820135614bb081615bfd565b803563ffffffff81168114610ecc57600080fd5b80356001600160401b0381168114610ecc57600080fd5b600060208284031215614c7d578081fd5b8135611b1c81615bfd565b600060208284031215614c99578081fd5b8151611b1c81615bfd565b60008060408385031215614cb6578081fd5b8235614cc181615bfd565b91506020830135614cd181615bfd565b809150509250929050565b600080600060608486031215614cf0578081fd5b8335614cfb81615bfd565b92506020840135614d0b81615bfd565b929592945050506040919091013590565b60008060008060808587031215614d31578182fd5b8435614d3c81615bfd565b93506020850135614d4c81615bfd565b92506040850135915060608501356001600160401b03811115614d6d578182fd5b8501601f81018713614d7d578182fd5b614d8c87823560208401614972565b91505092959194509250565b60008060408385031215614daa578182fd5b8235614db581615bfd565b91506020830135614cd181615c12565b600080600060608486031215614dd9578081fd5b8335614de481615bfd565b925060208401356001600160401b0380821115614dff578283fd5b908501906101408288031215614e13578283fd5b90925060408501359080821115614e28578283fd5b50840160808187031215614e3a578182fd5b809150509250925092565b60008060408385031215614e57578182fd5b8235614e6281615bfd565b946020939093013593505050565b600060208284031215614e81578081fd5b8151611b1c81615c12565b600060208284031215614e9d578081fd5b5035919050565b60008060408385031215614eb6578182fd5b823591506020830135614cd181615bfd565b60008060408385031215614eda578182fd5b50508035926020909101359150565b600060208284031215614efa578081fd5b8135611b1c81615c20565b600060208284031215614f16578081fd5b8151611b1c81615c20565b60008060008084860360c0811215614f37578283fd5b85356001600160401b0380821115614f4d578485fd5b614f5989838a01614af9565b96506020880135915080821115614f6e578485fd5b50614f7b88828901614af9565b9450506060603f1982011215614f8f578283fd5b5060408501915060a0850135614fa481615bfd565b939692955090935050565b600060208284031215614fc0578081fd5b81356001600160801b0381168114611b1c578182fd5b60008060408385031215614fe8578182fd5b8235915060208301356001600160401b03811115615004578182fd5b61501085828601614af9565b9150509250929050565b6000806040838503121561502c578182fd5b8235915060208301356001600160401b03811115615048578182fd5b61501085828601614b18565b60008060408385031215615066578182fd5b8235915061507660208401614c41565b90509250929050565b60008060008060008060a08789031215615097578384fd5b863595506150a760208801614c41565b94506150b560408801614c41565b93506060870135925060808701356001600160401b038111156150d6578283fd5b6150e289828a01614a41565b979a9699509497509295939492505050565b600080600080600080600060c0888a03121561510e578485fd5b8735965061511e60208901614c41565b955061512c60408901614c41565b94506060880135935060808801356001600160401b0381111561514d578182fd5b6151598a828b01614a41565b90945092505060a088013561516d81615bfd565b8091505092959891949750929550565b600080600060608486031215615191578081fd5b833592506151a160208501614c55565b91506151af60408501614c55565b90509250925092565b6000602082840312156151c9578081fd5b611b1c82614c41565b6000602082840312156151e3578081fd5b611b1c82614c55565b6001600160a01b03169052565b6000815180845260208085019450808401835b838110156152315781516001600160a01b03168752958201959082019060010161520c565b509495945050505050565b6000815180845260208085019450808401835b8381101561523157815163ffffffff168752958201959082019060010161524f565b60008151808452615289816020860160208601615ac9565b601f01601f19169290920160200192915050565b600481106152bb57634e487b7160e01b600052602160045260246000fd5b9052565b60008151608084526152d460808501826151f9565b9050602083015184820360208601526152ed828261523c565b6040858101516001600160a01b03169087015260609485015163ffffffff169490950193909352509192915050565b6001600160801b03169052565b6000835161533b818460208801615ac9565b8083019050602f60f81b808252845161535b816001850160208901615ac9565b6001920191820152693a37b5b2b7173539b7b760b11b6002820152600c01949350505050565b76020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8152600083516153b3816017850160208801615ac9565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516153e4816028840160208801615ac9565b01602801949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061542390830184615271565b9695505050505050565b602081526000611b1c60208301846151f9565b60808152600061545360808301876151f9565b8281036020840152615465818761523c565b63ffffffff95909516604084015250506001600160a01b039190911660609091015292915050565b602081526000611b1c602083018461523c565b602081526000611b1c6020830184615271565b602080825260099082015268085c1c995c185c995960ba1b604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252600b908201526a756e617661696c61626c6560a81b604082015260600190565b6020808252600d908201526c0908084f48195e1c1958dd1959609a1b604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252601390820152720f881b585e141d5c98da185cd9505b5bdd5b9d606a1b604082015260600190565b6020808252600690820152651b1bd8dad95960d21b604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601490820152730f881dda1a5d195b1a5cdd195908185b5bdd5b9d60621b604082015260600190565b6020808252600a908201526938bab0b73a34ba3c901f60b11b604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b602080825260059082015264195b99195960da1b604082015260600190565b8581526001600160a01b0385166020808301919091526001600160401b038516604083015260a0606083018190526000919061574690840186615271565b838103608085015284548390600181811c908083168061576757607f831692505b86831081141561578557634e487b7160e01b88526022600452602488fd5b8286526020860195508080156157a257600181146157b3576157dd565b60ff198516875287870195506157dd565b60008b815260209020895b858110156157d7578154898201529084019089016157be565b88019650505b50939d9c50505050505050505050505050565b828152604060208201526000612fac6040830184615271565b63ffffffff8f811682528e1660208201526001600160401b038d1660408201526001600160401b038c1660608201526001600160401b038b16608082015261585460a082018b61531c565b61586160c082018a61531c565b87151560e08201526158776101008201886151ec565b6158856101208201876151ec565b6101c0610140820152600061589e6101c0830187615271565b856101608401526158b361018084018661529d565b8281036101a08401526158c681856152bf565b9150509f9e505050505050505050505050505050565b6000808335601e198436030181126158f2578283fd5b8301803591506001600160401b0382111561590b578283fd5b602001915036819003821315614a8357600080fd5b604051608081016001600160401b038111828210171561594257615942615be7565b60405290565b604051601f8201601f191681016001600160401b038111828210171561597057615970615be7565b604052919050565b60006001600160401b0382111561599157615991615be7565b5060051b60200190565b60006001600160801b038281168482168083038211156159bd576159bd615bbb565b01949350505050565b600082198211156159d9576159d9615bbb565b500190565b600063ffffffff8083168185168083038211156159bd576159bd615bbb565b60006001600160401b038281168482168083038211156159bd576159bd615bbb565b600082615a2e57615a2e615bd1565b500490565b60006001600160801b0382811684821681151582840482111615615a5957615a59615bbb565b02949350505050565b6000816000190483118215151615615a7c57615a7c615bbb565b500290565b600082821015615a9357615a93615bbb565b500390565b600063ffffffff83811690831681811015615ab557615ab5615bbb565b039392505050565b6000610ba43683614b18565b60005b83811015615ae4578181015183820152602001615acc565b83811115611cd35750506000910152565b600081615b0457615b04615bbb565b506000190190565b60006001600160401b03821680615b2557615b25615bbb565b6000190192915050565b600181811c90821680615b4357607f821691505b60208210811415615b6457634e487b7160e01b600052602260045260246000fd5b50919050565b600061ffff80831681811415615b8257615b82615bbb565b6001019392505050565b6000600019821415615ba057615ba0615bbb565b5060010190565b600082615bb657615bb6615bd1565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114611aad57600080fd5b8015158114611aad57600080fd5b6001600160e01b031981168114611aad57600080fdfe9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220c1dc08b2a8d4ca269fdc070089575e43de6f4c2b0b0f431aa0758c58bdca470764736f6c63430008040033
Deployed Bytecode Sourcemap
90695:40936:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;122497:234;;;;;;;;;;-1:-1:-1;122497:234:0;;;;;:::i;:::-;;:::i;:::-;;123723:292;;;;;;;;;;-1:-1:-1;123723:292:0;;;;;:::i;:::-;;:::i;131045:583::-;;;;;;;;;;-1:-1:-1;131045:583:0;;;;;:::i;:::-;;:::i;:::-;;;23746:14:1;;23739:22;23721:41;;23709:2;23694:18;131045:583:0;;;;;;;;38067:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;39637:221::-;;;;;;;;;;-1:-1:-1;39637:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;21195:32:1;;;21177:51;;21165:2;21150:18;39637:221:0;21132:102:1;39149:422:0;;;;;;;;;;-1:-1:-1;39149:422:0;;;;;:::i;:::-;;:::i;128280:486::-;;;;;;;;;;-1:-1:-1;128280:486:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;129905:307::-;;;;;;;;;;-1:-1:-1;129905:307:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;100376:944::-;;;;;;;;;;-1:-1:-1;100376:944:0;;;;;:::i;:::-;;:::i;108846:387::-;;;;;;;;;;-1:-1:-1;108846:387:0;;;;;:::i;:::-;;:::i;90964:49::-;;;;;;;;;;-1:-1:-1;90964:49:0;;;;;;;;;;;42011:10:1;41999:23;;;41981:42;;41969:2;41954:18;90964:49:0;41936:93:1;40527:339:0;;;;;;;;;;-1:-1:-1;40527:339:0;;;;;:::i;:::-;;:::i;57540:123::-;;;;;;;;;;-1:-1:-1;57540:123:0;;;;;:::i;:::-;;:::i;:::-;;;23919:25:1;;;23907:2;23892:18;57540:123:0;23874:76:1;108406:209:0;;;;;;;;;;-1:-1:-1;108406:209:0;;;;;:::i;:::-;;:::i;75370:218::-;;;;;;;;;;-1:-1:-1;75370:218:0;;;;;:::i;:::-;;:::i;125090:269::-;;;;;;;;;;-1:-1:-1;125090:269:0;;;;;:::i;:::-;;:::i;91854:28::-;;;;;;;;;;-1:-1:-1;91854:28:0;;;;-1:-1:-1;;;;;91854:28:0;;;75999:227;;;;;;;;;;-1:-1:-1;75999:227:0;;;;;:::i;:::-;;:::i;111278:240::-;;;;;;;;;;-1:-1:-1;111278:240:0;;;;;:::i;:::-;;:::i;40937:185::-;;;;;;;;;;-1:-1:-1;40937:185:0;;;;;:::i;:::-;;:::i;91726:23::-;;;;;;;;;;-1:-1:-1;91726:23:0;;;;-1:-1:-1;;;;;91726:23:0;;;91393:36;;;;;;;;;;-1:-1:-1;91393:36:0;;;;-1:-1:-1;;;91393:36:0;;-1:-1:-1;;;;;91393:36:0;;;;;;-1:-1:-1;;;;;43617:31:1;;;43599:50;;43587:2;43572:18;91393:36:0;43554:101:1;37761:239:0;;;;;;;;;;-1:-1:-1;37761:239:0;;;;;:::i;:::-;;:::i;92297:48::-;;;;;;;;;;-1:-1:-1;92297:48:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;;;;;;;:::i;124202:315::-;;;;;;;;;;-1:-1:-1;124202:315:0;;;;;:::i;:::-;;:::i;111625:382::-;;;;;;;;;;-1:-1:-1;111625:382:0;;;;;:::i;:::-;;:::i;37491:208::-;;;;;;;;;;-1:-1:-1;37491:208:0;;;;;:::i;:::-;;:::i;107014:896::-;;;;;;;;;;-1:-1:-1;107014:896:0;;;;;:::i;:::-;;:::i;91498:29::-;;;;;;;;;;;;;;;;5675:99;;;;;;;;;;;;;:::i;124677:254::-;;;;;;;;;;-1:-1:-1;124677:254:0;;;;;:::i;:::-;;:::i;74825:145::-;;;;;;;;;;-1:-1:-1;74825:145:0;;;;;:::i;:::-;;:::i;56403:139::-;;;;;;;;;;-1:-1:-1;56403:139:0;;;;;:::i;:::-;;:::i;38236:104::-;;;;;;;;;;;;;:::i;108056:193::-;;;;;;;;;;-1:-1:-1;108056:193:0;;;;;:::i;:::-;;:::i;55483:49::-;;;;;;;;;;-1:-1:-1;55483:49:0;55528:4;55483:49;;39930:295;;;;;;;;;;-1:-1:-1;39930:295:0;;;;;:::i;:::-;;:::i;122894:191::-;;;;;;;;;;-1:-1:-1;122894:191:0;;;;;:::i;:::-;;:::i;41193:328::-;;;;;;;;;;-1:-1:-1;41193:328:0;;;;;:::i;:::-;;:::i;129452:334::-;;;;;;;;;;-1:-1:-1;129452:334:0;;;;;:::i;:::-;;:::i;114032:1231::-;;;;;;:::i;:::-;;:::i;121083:327::-;;;;;;;;;;-1:-1:-1;121083:327:0;;;;;:::i;:::-;;:::i;121643:684::-;;;;;;;;;;-1:-1:-1;121643:684:0;;;;;:::i;:::-;;:::i;120533:427::-;;;;;;;;;;-1:-1:-1;120533:427:0;;;;;:::i;:::-;;:::i;127773:394::-;;;;;;;;;;-1:-1:-1;127773:394:0;;;;;:::i;:::-;;:::i;110756:417::-;;;;;;;;;;-1:-1:-1;110756:417:0;;;;;:::i;:::-;;:::i;75144:134::-;;;;;;;;;;-1:-1:-1;75144:134:0;;;;;:::i;:::-;;:::i;91248:52::-;;;;;;;;;;-1:-1:-1;91248:52:0;;;;-1:-1:-1;;;91248:52:0;;;;;;109409:1242;;;;;;;;;;-1:-1:-1;109409:1242:0;;;;;:::i;:::-;;:::i;128886:454::-;;;;;;;;;;-1:-1:-1;128886:454:0;;;;;:::i;:::-;;:::i;92435:62::-;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;92435:62:0;;75681:223;;;;;;;;;;-1:-1:-1;75681:223:0;;;;;:::i;:::-;;:::i;91618:37::-;;;;;;;;;;-1:-1:-1;91618:37:0;;;;-1:-1:-1;;;;;91618:37:0;;;112417:1266;;;;;;:::i;:::-;;:::i;130557:272::-;;;;;;;;;;-1:-1:-1;130557:272:0;;;;;:::i;:::-;;:::i;91104:53::-;;;;;;;;;;-1:-1:-1;91104:53:0;;;;-1:-1:-1;;;91104:53:0;;;;;;115446:1059;;;;;;;;;;-1:-1:-1;115446:1059:0;;;;;:::i;:::-;;:::i;123282:243::-;;;;;;;;;;-1:-1:-1;123282:243:0;;;;;:::i;:::-;;:::i;122497:234::-;-1:-1:-1;;;;;;;;;;;55974:30:0;92473:24;33332:10;55974;:30::i;:::-;122651:11;99017:22:::1;98979:24:::0;;;;:10:::1;:24;::::0;;;;:34:::1;;::::0;::::1;;:60;::::0;::::1;;;;-1:-1:-1::0;;;98979:60:0::1;;;;;;;;;;;98957:119;;;;-1:-1:-1::0;;;98957:119:0::1;;;;;;;:::i;:::-;;;;;;;;;122685:38:::2;122699:11;122712:10;122685:38;;;;;;;:::i;:::-;;;;;;;;56015:1:::1;122497:234:::0;;;:::o;123723:292::-;55528:4;55974:30;55528:4;33332:10;55974;:30::i;:::-;123894:38:::1;::::0;123936:5:::1;::::0;123879:53:::1;::::0;-1:-1:-1;;;123894:38:0;::::1;;;123879:12:::0;:53:::1;:::i;:::-;:62;;;;123871:71;;;::::0;::::1;;-1:-1:-1::0;123953:39:0::1;:54:::0;;::::1;::::0;;::::1;-1:-1:-1::0;;;123953:54:0::1;-1:-1:-1::0;;;;123953:54:0;;::::1;::::0;;;::::1;::::0;;123723:292::o;131045:583::-;131306:4;-1:-1:-1;;;;;;131348:53:0;;-1:-1:-1;;;131348:53:0;;:118;;;131418:48;131454:11;131418:35;:48::i;:::-;131348:190;;;;131483:55;131526:11;131483:42;:55::i;:::-;131348:272;;;;131555:65;131608:11;131555:52;:65::i;:::-;131328:292;131045:583;-1:-1:-1;;131045:583:0:o;38067:100::-;38121:13;38154:5;38147:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38067:100;:::o;39637:221::-;39713:7;39741:16;39749:7;39741;:16::i;:::-;39733:73;;;;-1:-1:-1;;;39733:73:0;;33155:2:1;39733:73:0;;;33137:21:1;33194:2;33174:18;;;33167:30;33233:34;33213:18;;;33206:62;-1:-1:-1;;;33284:18:1;;;33277:42;33336:19;;39733:73:0;33127:234:1;39733:73:0;-1:-1:-1;39826:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;39826:24:0;;39637:221::o;39149:422::-;39230:13;39246:34;39272:7;39246:25;:34::i;:::-;39230:50;;39305:5;-1:-1:-1;;;;;39299:11:0;:2;-1:-1:-1;;;;;39299:11:0;;;39291:57;;;;-1:-1:-1;;;39291:57:0;;34980:2:1;39291:57:0;;;34962:21:1;35019:2;34999:18;;;34992:30;35058:34;35038:18;;;35031:62;-1:-1:-1;;;35109:18:1;;;35102:31;35150:19;;39291:57:0;34952:223:1;39291:57:0;33332:10;-1:-1:-1;;;;;39383:21:0;;;;:62;;-1:-1:-1;39408:37:0;39425:5;33332:10;130557:272;:::i;39408:37::-;39361:168;;;;-1:-1:-1;;;39361:168:0;;29095:2:1;39361:168:0;;;29077:21:1;29134:2;29114:18;;;29107:30;29173:34;29153:18;;;29146:62;-1:-1:-1;;;29224:18:1;;;29217:54;29288:19;;39361:168:0;29067:246:1;39361:168:0;39542:21;39551:2;39555:7;39542:8;:21::i;:::-;39149:422;;;:::o;128280:486::-;128411:14;;;;:10;:14;;;;;:31;;:59;128373:16;;128407:352;;128532:16;;;128546:1;128532:16;;;;;;;;;128492:37;;128532:16;;;;;;;;;-1:-1:-1;;128590:22:0;;128563:23;;;;-1:-1:-1;;;;;;128590:22:0;;128563:23;;-1:-1:-1;128590:22:0;;128563:23;;-1:-1:-1;;;128563:23:0;;;;;;;;;-1:-1:-1;;;;;128563:50:0;;;:23;;;;;;;;;;;:50;128635:20;128280:486;-1:-1:-1;;128280:486:0:o;128407:352::-;128695:14;;;;:10;:14;;;;;;;;;:31;;128688:59;;;;;;;;;;;;;;;;;128695:31;;128688:59;;128695:31;128688:59;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;128688:59:0;;;;;;;;;;;;;;;;;;;;;;;128280:486;;;:::o;128407:352::-;128280:486;;;:::o;129905:307::-;130066:15;;;130079:1;130066:15;;;;;;;;;130007;;130040:22;;130066:15;;;;;;;;;;;;-1:-1:-1;;130104:39:0;130115:27;;;:18;:27;;;;;;;;;130104:39;;:10;:39;;;;;:75;;;130092:9;;;;-1:-1:-1;;;;130104:75:0;;;;;130092:9;;130104:39;130092:9;;-1:-1:-1;;;130092:9:0;;;;;;;;;:87;;;;:9;;;;;;;;;;;:87;130197:6;129905:307;-1:-1:-1;;129905:307:0:o;100376:944::-;2201:13;;;;;;;;:30;;-1:-1:-1;2219:12:0;;;;2218:13;2201:30;2193:89;;;;-1:-1:-1;;;2193:89:0;;;;;;;:::i;:::-;2295:19;2318:13;;;;;;2317:14;2342:101;;;;2377:13;:20;;-1:-1:-1;;2412:19:0;;;;;2342:101;100623:47:::1;100655:5;100662:7;100623:31;:47::i;:::-;100681:34;:32;:34::i;:::-;100726:47;:45;:47::i;:::-;100786:59;55528:4;100817:27;;::::0;::::1;:18:::0;:27:::1;:::i;:::-;100786:10;:59::i;:::-;100856:50;-1:-1:-1::0;;;;;;;;;;;100880:25:0::1;::::0;;;::::1;::::0;::::1;;:::i;100856:50::-;100930:27;;::::0;::::1;:18:::0;:27:::1;:::i;:::-;100919:8;:38:::0;;-1:-1:-1;;;;;;100919:38:0::1;-1:-1:-1::0;;;;;100919:38:0;;;::::1;::::0;;;::::1;::::0;;100984:25:::1;::::0;;;::::1;::::0;::::1;;:::i;:::-;100968:13;:41:::0;;-1:-1:-1;;;;;;100968:41:0::1;-1:-1:-1::0;;;;;100968:41:0;;;::::1;::::0;;;::::1;::::0;;101022:35:::1;:42:::0;;-1:-1:-1;;;;;;101148:44:0;;;;;101238:41:::1;::::0;;;::::1;::::0;::::1;;:::i;:::-;101213:22;:66:::0;;-1:-1:-1;;;;;;101213:66:0;;::::1;-1:-1:-1::0;;;;;101213:66:0;;::::1;;::::0;;;101290:10:::1;:22:::0;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;2469:68;;;;2520:5;2504:21;;-1:-1:-1;;2504:21:0;;;2469:68;100376:944;;;;;:::o;108846:387::-;-1:-1:-1;;;;;;;;;;;55974:30:0;92473:24;33332:10;55974;:30::i;:::-;109042:24:::1;::::0;;;:10:::1;:24;::::0;;;;:33;-1:-1:-1;;;;;109042:48:0;;::::1;-1:-1:-1::0;;;109042:33:0;;::::1;;:48;109034:66;;;::::0;-1:-1:-1;;;109034:66:0;;37502:2:1;109034:66:0::1;::::0;::::1;37484:21:1::0;37541:1;37521:18;;;37514:29;-1:-1:-1;;;37559:18:1;;;37552:35;37604:18;;109034:66:0::1;37474:154:1::0;109034:66:0::1;-1:-1:-1::0;109113:24:0::1;::::0;;;:10:::1;:24;::::0;;;;;:48;;-1:-1:-1;;;;;109113:48:0;;::::1;-1:-1:-1::0;;;109113:48:0::1;-1:-1:-1::0;;;;;;;;109113:48:0;;::::1;;::::0;;109174:22:::1;:51:::0;;;;;::::1;-1:-1:-1::0;;;109174:51:0::1;-1:-1:-1::0;;;;;;;;109174:51:0;;::::1;;::::0;;108846:387::o;40527:339::-;40722:41;33332:10;40755:7;40722:18;:41::i;:::-;40714:103;;;;-1:-1:-1;;;40714:103:0;;;;;;;:::i;:::-;40830:28;40840:4;40846:2;40850:7;40830:9;:28::i;57540:123::-;57606:7;57633:12;;;:6;:12;;;;;:22;;;;57540:123::o;108406:209::-;-1:-1:-1;;;;;;;;;;;55974:30:0;92473:24;33332:10;55974;:30::i;:::-;-1:-1:-1;108555:24:0::1;::::0;;;:10:::1;:24;::::0;;;;;:35:::1;;:52:::0;108406:209::o;75370:218::-;75508:30;75524:4;75530:7;75508:15;:30::i;:::-;75549:18;;;;:12;:18;;;;;:31;;75572:7;75549:22;:31::i;125090:269::-;55528:4;55974:30;55528:4;33332:10;55974;:30::i;:::-;125217:40:::1;-1:-1:-1::0;;;;;;;;;;;125240:16:0::1;125217:9;:40::i;:::-;125294:13;::::0;125270:38:::1;::::0;-1:-1:-1;;;;;;;;;;;92473:24:0;-1:-1:-1;;;;;125294:13:0::1;125270:10;:38::i;:::-;-1:-1:-1::0;125319:13:0::1;:32:::0;;-1:-1:-1;;;;;;125319:32:0::1;-1:-1:-1::0;;;;;125319:32:0;;;::::1;::::0;;;::::1;::::0;;125090:269::o;75999:227::-;76140:33;76159:4;76165:7;76140:18;:33::i;:::-;76184:18;;;;:12;:18;;;;;:34;;76210:7;76184:25;:34::i;111278:240::-;-1:-1:-1;;;;;;;;;;;55974:30:0;92473:24;33332:10;55974;:30::i;:::-;111390:11:::1;99280:28;99295:12;99280:14;:28::i;:::-;99272:49;;;::::0;-1:-1:-1;;;99272:49:0;;27656:2:1;99272:49:0::1;::::0;::::1;27638:21:1::0;27695:1;27675:18;;;27668:29;-1:-1:-1;;;27713:18:1;;;27706:38;27761:18;;99272:49:0::1;27628:157:1::0;99272:49:0::1;111419:23:::2;::::0;;;:10:::2;:23;::::0;;;;;;;;:33:::2;;:52:::0;;-1:-1:-1;;111419:52:0::2;111455:16;111419:52;::::0;;111487:23;;23919:25:1;;;111487:23:0::2;::::0;23892:18:1;111487:23:0::2;;;;;;;;56015:1:::1;111278:240:::0;;:::o;40937:185::-;41075:39;41092:4;41098:2;41102:7;41075:39;;;;;;;;;;;;:16;:39::i;37761:239::-;37833:7;37869:16;;;:7;:16;;;;;;-1:-1:-1;;;;;37869:16:0;37904:19;37896:73;;;;-1:-1:-1;;;37896:73:0;;29931:2:1;37896:73:0;;;29913:21:1;29970:2;29950:18;;;29943:30;30009:34;29989:18;;;29982:62;-1:-1:-1;;;30060:18:1;;;30053:39;30109:19;;37896:73:0;29903:231:1;92297:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;92297:48:0;;;;;;-1:-1:-1;;;;;;;;92297:48:0;;;;;-1:-1:-1;;;92297:48:0;;;;;;-1:-1:-1;;;92297:48:0;;;;;;;-1:-1:-1;;;;;92297:48:0;;;;;;;;;;;;;;;;-1:-1:-1;;;;;92297:48:0;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;92297:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;92297:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;92297:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;92297:48:0;;;-1:-1:-1;;92297:48:0;;;;;;-1:-1:-1;;;;;92297:48:0;;;;;;-1:-1:-1;;;92297:48:0;;;;;;;;;;-1:-1:-1;92297:48:0;:::o;124202:315::-;55528:4;55974:30;55528:4;33332:10;55974;:30::i;:::-;124386:39:::1;::::0;124429:5:::1;::::0;124371:54:::1;::::0;-1:-1:-1;;;124386:39:0;::::1;;;124371:12:::0;:54:::1;:::i;:::-;:63;;;;124349:96;;;::::0;::::1;;-1:-1:-1::0;124456:38:0::1;:53:::0;;::::1;::::0;;::::1;-1:-1:-1::0;;;124456:53:0::1;-1:-1:-1::0;;;;124456:53:0;;::::1;::::0;;;::::1;::::0;;124202:315::o;111625:382::-;-1:-1:-1;;;;;;;;;;;55974:30:0;92473:24;33332:10;55974;:30::i;:::-;111731:23:::1;::::0;;;:10:::1;:23;::::0;;;;:40:::1;;::::0;-1:-1:-1;;;;;111731:40:0::1;100049:52;111731:40:::0;100049:33:::1;:52::i;:::-;100041:70;;;;-1:-1:-1::0;;;100041:70:0::1;;;;;;;:::i;:::-;111843:16:::2;111806:23;::::0;;;:10:::2;:23;::::0;;;;:33:::2;;::::0;::::2;;:53;::::0;::::2;;;;-1:-1:-1::0;;;111806:53:0::2;;;;;;;;;;111784:110;;;::::0;-1:-1:-1;;;111784:110:0;;30684:2:1;111784:110:0::2;::::0;::::2;30666:21:1::0;30723:1;30703:18;;;30696:29;-1:-1:-1;;;30741:18:1;;;30734:37;30788:18;;111784:110:0::2;30656:156:1::0;111784:110:0::2;111905:23;::::0;;;:10:::2;:23;::::0;;;;;;;;:33:::2;;:53:::0;;-1:-1:-1;;111905:53:0::2;111941:17;111905:53;::::0;;111974:25;;23919::1;;;111974::0::2;::::0;23892:18:1;111974:25:0::2;23874:76:1::0;37491:208:0;37563:7;-1:-1:-1;;;;;37591:19:0;;37583:74;;;;-1:-1:-1;;;37583:74:0;;29520:2:1;37583:74:0;;;29502:21:1;29559:2;29539:18;;;29532:30;29598:34;29578:18;;;29571:62;-1:-1:-1;;;29649:18:1;;;29642:40;29699:19;;37583:74:0;29492:232:1;37583:74:0;-1:-1:-1;;;;;;37675:16:0;;;;;:9;:16;;;;;;;37491:208::o;107014:896::-;-1:-1:-1;;;;;;;;;;;55974:30:0;92473:24;33332:10;55974;:30::i;:::-;107263:14:::1;::::0;107240:20:::1;107288:24:::0;;;:10:::1;:24;::::0;;;;;;;:31:::1;;:41:::0;;-1:-1:-1;;;;;;107288:41:0::1;;-1:-1:-1::0;;;;;107288:41:0;::::1;;;::::0;;107376:16:::1;::::0;;::::1;::::0;::::1;:::i;:::-;107340:24;::::0;;;:10:::1;:24;::::0;;;;;;;;:52;;-1:-1:-1;;;;;107340:52:0;;;::::1;-1:-1:-1::0;;;107340:52:0::1;-1:-1:-1::0;;;;;;;;107340:52:0;;::::1;::::0;;;::::1;::::0;;;107436:13:::1;::::0;;;;;;::::1;;:::i;:::-;107403:24;::::0;;;:10:::1;:24;::::0;;;;;;:30:::1;;:46:::0;;-1:-1:-1;;;;;107403:46:0;;::::1;-1:-1:-1::0;;;107403:46:0::1;::::0;::::1;::::0;;;::::1;::::0;;;107462:313:::1;::::0;107414:12;;107519:18:::1;::::0;;;;;;::::1;;:::i;:::-;107552:20;;::::0;::::1;:6:::0;:20:::1;:::i;:::-;107462:313;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;;;;107587:18:0::1;::::0;::::1;;107620:24;::::0;;;::::1;::::0;::::1;;:::i;:::-;107659:26;::::0;;;::::1;::::0;::::1;;:::i;:::-;107700:25;::::0;;;::::1;::::0;::::1;;:::i;:::-;107740:24;::::0;;;::::1;::::0;::::1;;:::i;:::-;107462:15;:313::i;:::-;107789:61;107810:12:::0;107824:25:::1;;::::0;::::1;:6:::0;:25:::1;:::i;:::-;107789:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;107789:20:0::1;::::0;-1:-1:-1;;;107789:61:0:i:1;:::-;107861:41;107878:12:::0;107861:41:::1;107892:9:::0;107861:41:::1;:::i;5675:99::-:0;2201:13;;;;;;;;:30;;-1:-1:-1;2219:12:0;;;;2218:13;2201:30;2193:89;;;;-1:-1:-1;;;2193:89:0;;;;;;;:::i;:::-;2295:19;2318:13;;;;;;2317:14;2342:101;;;;2377:13;:20;;-1:-1:-1;;2412:19:0;;;;;2342:101;5728:38:::1;-1:-1:-1::0;;;5728:18:0::1;:38::i;:::-;2473:14:::0;2469:68;;;2520:5;2504:21;;-1:-1:-1;;2504:21:0;;;2469:68;5675:99;:::o;124677:254::-;55528:4;55974:30;55528:4;33332:10;55974;:30::i;:::-;124799:40:::1;55528:4;124829:9:::0;124799::::1;:40::i;:::-;124883:8;::::0;124852:40:::1;::::0;55528:4:::1;::::0;-1:-1:-1;;;;;124883:8:0::1;124852:10;:40::i;:::-;-1:-1:-1::0;124903:8:0::1;:20:::0;;-1:-1:-1;;;;;;124903:20:0::1;-1:-1:-1::0;;;;;124903:20:0;;;::::1;::::0;;;::::1;::::0;;124677:254::o;74825:145::-;74907:7;74934:18;;;:12;:18;;;;;:28;;74956:5;74934:21;:28::i;:::-;74927:35;74825:145;-1:-1:-1;;;74825:145:0:o;56403:139::-;56481:4;56505:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;56505:29:0;;;;;;;;;;;;;;;56403:139::o;38236:104::-;38292:13;38325:7;38318:14;;;;;:::i;108056:193::-;-1:-1:-1;;;;;;;;;;;55974:30:0;92473:24;33332:10;55974;:30::i;:::-;-1:-1:-1;108197:24:0::1;::::0;;;:10:::1;:24;::::0;;;;;:31:::1;;:44:::0;;-1:-1:-1;;;;;108197:44:0;;::::1;;;-1:-1:-1::0;;;;;;108197:44:0;;::::1;::::0;;;::::1;::::0;;108056:193::o;39930:295::-;-1:-1:-1;;;;;40033:24:0;;33332:10;40033:24;;40025:62;;;;-1:-1:-1;;;40025:62:0;;27302:2:1;40025:62:0;;;27284:21:1;27341:2;27321:18;;;27314:30;-1:-1:-1;;;27360:18:1;;;27353:55;27425:18;;40025:62:0;27274:175:1;40025:62:0;33332:10;40100:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;40100:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;40100:53:0;;;;;;;;;;40169:48;;23721:41:1;;;40100:42:0;;33332:10;40169:48;;23694:18:1;40169:48:0;;;;;;;39930:295;;:::o;122894:191::-;55528:4;55974:30;55528:4;33332:10;55974;:30::i;:::-;-1:-1:-1;123029:22:0::1;:48:::0;;-1:-1:-1;;;;;;123029:48:0::1;-1:-1:-1::0;;;;;123029:48:0;;;::::1;::::0;;;::::1;::::0;;122894:191::o;41193:328::-;41368:41;33332:10;41401:7;41368:18;:41::i;:::-;41360:103;;;;-1:-1:-1;;;41360:103:0;;;;;;;:::i;:::-;41474:39;41488:4;41494:2;41498:7;41507:5;41474:13;:39::i;:::-;41193:328;;;;:::o;129452:334::-;129628:16;;;129642:1;129628:16;;;;;;;;;129561;;129595:30;;129628:16;;;;;;;;;;-1:-1:-1;;;129674:39:0;129685:27;;;:18;:27;;;;;;;;;129674:39;;:10;:39;;;;;:73;;;129655:16;;;;-1:-1:-1;;;;;;129674:73:0;;129655:16;;129674:39;129655:16;;-1:-1:-1;;;129655:16:0;;;;;;;;114032:1231;89649:1;90247:7;;:19;;90239:63;;;;-1:-1:-1;;;90239:63:0;;;;;;;:::i;:::-;89649:1;90380:7;:18;99687:24:::1;::::0;;;:10:::1;:24;::::0;;;;:33;:24;;114343:16;;99687:46:::1;::::0;::::1;-1:-1:-1::0;;;99687:33:0;;::::1;-1:-1:-1::0;;;;;99687:33:0::1;:46;;99665:106;;;;-1:-1:-1::0;;;99665:106:0::1;;;;;;;:::i;:::-;114381:65:::2;114406:11;114419:19;114440:5;;114381:24;:65::i;:::-;114377:382;;;114471:33;::::0;;;:20:::2;:33;::::0;;;;;;;114505:10:::2;114471:45:::0;;;;;;;;:87:::2;::::0;;::::2;::::0;:64:::2;::::0;114519:16;;114471:45:::2;:64;:::i;:::-;:87;;;;114463:120;;;;-1:-1:-1::0;;;114463:120:0::2;;;;;;;:::i;:::-;114598:33;::::0;;;:20:::2;:33;::::0;;;;;;;114632:10:::2;114598:45:::0;;;;;;;:65;;114647:16;;114598:33;:65:::2;::::0;114647:16;;114598:65:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;114377:382;;;114704:27;114719:11;114704:14;:27::i;:::-;114696:51;;;;-1:-1:-1::0;;;114696:51:0::2;;;;;;;:::i;:::-;114793:23;::::0;;;:10:::2;:23;::::0;;;;:41;-1:-1:-1;;;114793:41:0;::::2;-1:-1:-1::0;;;;;114793:41:0::2;:46:::0;;:128:::2;;-1:-1:-1::0;114880:23:0::2;::::0;;;:10:::2;:23;::::0;;;;:41;-1:-1:-1;;;114880:41:0;::::2;-1:-1:-1::0;;;;;114880:41:0::2;114860:61;::::0;::::2;;;114793:128;114771:197;;;;-1:-1:-1::0;;;114771:197:0::2;;;;;;;:::i;:::-;114981:14;114998:23:::0;;;:10:::2;:23;::::0;;;;:30:::2;;::::0;::::2;::::0;::::2;-1:-1:-1::0;;;;;114998:30:0::2;115039:149;114998:23:::0;115114:16;115145:11;114998:30;115039:34:::2;:149::i;:::-;115199:56;115213:11;115226:16;115244:10;115199:13;:56::i;:::-;-1:-1:-1::0;;89605:1:0;90559:7;:22;-1:-1:-1;;;;;;;114032:1231:0:o;121083:327::-;55528:4;55974:30;55528:4;33332:10;55974;:30::i;:::-;121220:11;99017:22:::1;98979:24:::0;;;;:10:::1;:24;::::0;;;;:34:::1;;::::0;::::1;;:60;::::0;::::1;;;;-1:-1:-1::0;;;98979:60:0::1;;;;;;;;;;;98957:119;;;;-1:-1:-1::0;;;98957:119:0::1;;;;;;;:::i;:::-;121272:23:::2;::::0;;;:10:::2;:23;::::0;;;;:38:::2;;::::0;::::2;;121271:39;121249:95;;;;-1:-1:-1::0;;;121249:95:0::2;;;;;;;:::i;:::-;-1:-1:-1::0;;121357:23:0::2;::::0;;;:10:::2;:23;::::0;;;;:38:::2;;:45:::0;;-1:-1:-1;;121357:45:0::2;121398:4;121357:45;::::0;;121083:327::o;121643:684::-;121761:13;121814:16;121822:7;121814;:16::i;:::-;121792:75;;;;-1:-1:-1;;;121792:75:0;;31795:2:1;121792:75:0;;;31777:21:1;31834:1;31814:18;;;31807:29;-1:-1:-1;;;31852:18:1;;;31845:39;31901:18;;121792:75:0;31767:158:1;121792:75:0;121880:21;121915:27;;;:18;:27;;;;;;;;;121904:39;;:10;:39;;;;;:52;;121880:76;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;122011:1;121993:7;121987:21;:25;:332;;;;;;;;;;;;;;;;;122104:7;122168:18;:7;:16;:18::i;:::-;122061:217;;;;;;;;;:::i;:::-;;;;;;;;;;;;;121967:352;121643:684;-1:-1:-1;;;121643:684:0:o;120533:427::-;-1:-1:-1;;;;;;;;;;;55974:30:0;92473:24;33332:10;55974;:30::i;:::-;120694:11;99017:22:::1;98979:24:::0;;;;:10:::1;:24;::::0;;;;:34:::1;;::::0;::::1;;:60;::::0;::::1;;;;-1:-1:-1::0;;;98979:60:0::1;;;;;;;;;;;98957:119;;;;-1:-1:-1::0;;;98957:119:0::1;;;;;;;:::i;:::-;120741:23:::2;::::0;;;:10:::2;:23;::::0;;;;:38:::2;;::::0;::::2;;120740:39;120718:95;;;;-1:-1:-1::0;;;120718:95:0::2;;;;;;;:::i;:::-;120826:23;::::0;;;:10:::2;:23;::::0;;;;;;;:54;;::::2;::::0;:36:::2;::::0;;::::2;::::0;:54;::::2;::::0;::::2;:::i;:::-;;120898;120923:11;120936:15;120898:54;;;;;;;:::i;127773:394::-:0;127893:10;127854:14;127871:33;;;:21;:33;;;;;;127925:11;127917:32;;;;-1:-1:-1;;;127917:32:0;;35382:2:1;127917:32:0;;;35364:21:1;35421:1;35401:18;;;35394:29;-1:-1:-1;;;35439:18:1;;;35432:38;35487:18;;127917:32:0;35354:157:1;127917:32:0;127984:10;127998:1;127962:33;;;:21;:33;;;;;;:37;;;128042:69;-1:-1:-1;;;;;128042:14:0;;;128077:5;;128064:6;;127998:1;128042:69;127998:1;128042:69;128064:6;128042:14;128077:5;128042:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;128012:99;;;128130:18;128122:37;;;;-1:-1:-1;;;128122:37:0;;32132:2:1;128122:37:0;;;32114:21:1;32171:1;32151:18;;;32144:29;-1:-1:-1;;;32189:18:1;;;32182:36;32235:18;;128122:37:0;32104:155:1;110756:417:0;-1:-1:-1;;;;;;;;;;;55974:30:0;92473:24;33332:10;55974;:30::i;:::-;110887:23:::1;::::0;;;:10:::1;:23;::::0;;;;:40:::1;;::::0;-1:-1:-1;;;;;110887:40:0::1;100049:52;110887:40:::0;100049:33:::1;:52::i;:::-;100041:70;;;;-1:-1:-1::0;;;100041:70:0::1;;;;;;;:::i;:::-;111005:21:::2;110968:23;::::0;;;:10:::2;:23;::::0;;;;:33:::2;;::::0;::::2;;:58;::::0;::::2;;;;-1:-1:-1::0;;;110968:58:0::2;;;;;;;;;;110946:115;;;::::0;-1:-1:-1;;;110946:115:0;;35718:2:1;110946:115:0::2;::::0;::::2;35700:21:1::0;35757:1;35737:18;;;35730:29;-1:-1:-1;;;35775:18:1;;;35768:37;35822:18;;110946:115:0::2;35690:156:1::0;110946:115:0::2;111072:23;::::0;;;:10:::2;:23;::::0;;;;;;;;:33:::2;;:53:::0;;-1:-1:-1;;111072:53:0::2;111108:17;111072:53;::::0;;111141:24;;23919:25:1;;;111141:24:0::2;::::0;23892:18:1;111141:24:0::2;23874:76:1::0;75144:134:0;75216:7;75243:18;;;:12;:18;;;;;:27;;:25;:27::i;109409:1242::-;-1:-1:-1;;;;;;;;;;;55974:30:0;92473:24;33332:10;55974;:30::i;:::-;109611:22:::1;109573:24:::0;;;:10:::1;:24;::::0;;;;:34:::1;;::::0;::::1;;:60;::::0;::::1;;;;-1:-1:-1::0;;;109573:60:0::1;;;;;;;;;;;109551:119;;;;-1:-1:-1::0;;;109551:119:0::1;;;;;;;:::i;:::-;109703:76;109721:10;:31;;;109754:10;:24;;;109703:17;:76::i;:::-;109681:133;;;::::0;-1:-1:-1;;;109681:133:0;;33901:2:1;109681:133:0::1;::::0;::::1;33883:21:1::0;33940:1;33920:18;;;33913:29;-1:-1:-1;;;33958:18:1;;;33951:37;34005:18;;109681:133:0::1;33873:156:1::0;109681:133:0::1;109875:29;::::0;;::::1;::::0;109948:203;;::::1;::::0;::::1;::::0;;109967:31:::1;::::0;;::::1;::::0;109948:203;;110013:24;;109948:203;;::::1;::::0;110052:35:::1;::::0;;::::1;::::0;-1:-1:-1;;;;;109948:203:0::1;::::0;;;;110103:37;;::::1;::::0;109948:203:::1;;::::0;;;;110242:22;;::::1;::::0;109875:29;;109948:203;110238:324:::1;;;110328:10;::::0;110370:41;;110431:34:::1;::::0;::::1;::::0;110317:233:::1;::::0;-1:-1:-1;;;110317:233:0;;-1:-1:-1;;;;;110328:10:0;;::::1;::::0;110317:34:::1;::::0;:233:::1;::::0;110370:41;;110328:10:::1;::::0;;;110317:233:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;110281:269:0::1;:33;::::0;::::1;:269:::0;110238:324:::1;110583:24;::::0;;;:10:::1;:24;::::0;;;;;;;:60;;;;110627:16;;110583:41:::1;::::0;;::::1;::::0;:60:::1;::::0;:41;;:60;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;110583:60:0::1;::::0;;::::1;::::0;;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;110583:60:0::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;;::::1;::::0;;::::1;::::0;::::1;;-1:-1:-1::0;;;110583:60:0::1;-1:-1:-1::0;;;;;;110583:60:0;;;-1:-1:-1;;;;;110583:60:0;;::::1;::::0;;;;;;;::::1;::::0;;-1:-1:-1;;;;;109409:1242:0:o;128886:454::-;129009:14;;;;:10;:14;;;;;:45;;:52;128972:15;;129005:328;;129115:15;;;129128:1;129115:15;;;;;;;;;129083:29;;129115:15;;;;;;;;;-1:-1:-1;;129164:35:0;;129145:16;;;;-1:-1:-1;129164:35:0;;;129145:16;;-1:-1:-1;129164:35:0;;129145:16;;-1:-1:-1;;;129145:16:0;;;;;;;;129005:328;129276:14;;;;:10;:14;;;;;;;;;:45;;129269:52;;;;;;;;;;;;;;;;;129276:45;;129269:52;;129276:45;129269:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;129269:52:0;;128886:454;-1:-1:-1;;;;;;;128886:454:0:o;75681:223::-;75820:31;75837:4;75843:7;75820:16;:31::i;112417:1266::-;89649:1;90247:7;;:19;;90239:63;;;;-1:-1:-1;;;90239:63:0;;;;;;;:::i;:::-;89649:1;90380:7;:18;99687:24:::1;::::0;;;:10:::1;:24;::::0;;;;:33;:24;;112761:16;;99687:46:::1;::::0;::::1;-1:-1:-1::0;;;99687:33:0;;::::1;-1:-1:-1::0;;;;;99687:33:0::1;:46;;99665:106;;;;-1:-1:-1::0;;;99665:106:0::1;;;;;;;:::i;:::-;112799:65:::2;112824:11;112837:19;112858:5;;112799:24;:65::i;:::-;112795:382;;;112889:33;::::0;;;:20:::2;:33;::::0;;;;;;;112923:10:::2;112889:45:::0;;;;;;;;:87:::2;::::0;;::::2;::::0;:64:::2;::::0;112937:16;;112889:45:::2;:64;:::i;:::-;:87;;;;112881:120;;;;-1:-1:-1::0;;;112881:120:0::2;;;;;;;:::i;:::-;113016:33;::::0;;;:20:::2;:33;::::0;;;;;;;113050:10:::2;113016:45:::0;;;;;;;:65;;113065:16;;113016:33;:65:::2;::::0;113065:16;;113016:65:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;112795:382;;;113122:27;113137:11;113122:14;:27::i;:::-;113114:51;;;;-1:-1:-1::0;;;113114:51:0::2;;;;;;;:::i;:::-;113211:23;::::0;;;:10:::2;:23;::::0;;;;:41;-1:-1:-1;;;113211:41:0;::::2;-1:-1:-1::0;;;;;113211:41:0::2;:46:::0;;:128:::2;;-1:-1:-1::0;113298:23:0::2;::::0;;;:10:::2;:23;::::0;;;;:41;-1:-1:-1;;;113298:41:0;::::2;-1:-1:-1::0;;;;;113298:41:0::2;113278:61;::::0;::::2;;;113211:128;113189:197;;;;-1:-1:-1::0;;;113189:197:0::2;;;;;;;:::i;:::-;113399:14;113416:23:::0;;;:10:::2;:23;::::0;;;;:30:::2;;::::0;::::2;::::0;::::2;-1:-1:-1::0;;;;;113416:30:0::2;113457:149;113416:23:::0;113532:16;113563:11;113416:30;113457:34:::2;:149::i;:::-;113617:58;113631:11;113644:16;113662:12;113617:13;:58::i;:::-;-1:-1:-1::0;;89605:1:0;90559:7;:22;-1:-1:-1;;;;;;;;112417:1266:0:o;130557:272::-;-1:-1:-1;;;;;40417:25:0;;;130684:4;40417:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;130726:95;;;-1:-1:-1;130784:37:0;55528:4;130812:8;130784:7;:37::i;115446:1059::-;89649:1;90247:7;;:19;;90239:63;;;;-1:-1:-1;;;90239:63:0;;;;;;;:::i;:::-;89649:1;90380:7;:18;115608:46:::1;115642:11:::0;115608:33:::1;:46::i;:::-;:77;;;;115658:27;115673:11;115658:14;:27::i;:::-;115586:146;;;::::0;-1:-1:-1;;;115586:146:0;;28747:2:1;115586:146:0::1;::::0;::::1;28729:21:1::0;28786:2;28766:18;;;28759:30;-1:-1:-1;;;28805:18:1;;;28798:49;28864:18;;115586:146:0::1;28719:169:1::0;115586:146:0::1;115765:13;::::0;-1:-1:-1;;;;;115765:13:0::1;115782:10;115765:27;::::0;:92:::1;;-1:-1:-1::0;115813:23:0::1;::::0;;;:10:::1;:23;::::0;;;;:30:::1;;::::0;::::1;::::0;::::1;-1:-1:-1::0;;;;;115813:30:0::1;115847:10;115813:44;115765:92;115743:154;;;::::0;-1:-1:-1;;;115743:154:0;;32814:2:1;115743:154:0::1;::::0;::::1;32796:21:1::0;32853:2;32833:18;;;32826:30;-1:-1:-1;;;32872:18:1;;;32865:42;32924:18;;115743:154:0::1;32786:162:1::0;115743:154:0::1;115914:13;::::0;-1:-1:-1;;;;;115914:13:0::1;115931:10;115914:27;115910:529;;;115996:23;::::0;;;:10:::1;:23;::::0;;;;:42;::::1;-1:-1:-1::0;;;115996:42:0;;::::1;::::0;::::1;115984:54:::0;;::::1;;;115958:126;;;;-1:-1:-1::0;;;115958:126:0::1;;;;;;;:::i;:::-;116099:23;::::0;;;:10:::1;:23;::::0;;;;:54;;116145:8;;116099:23;:42:::1;::::0;:54:::1;::::0;116145:8;;-1:-1:-1;;;116099:54:0;::::1;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;115910:529;;;116175:23;::::0;;;:10:::1;:23;::::0;;;;:30:::1;;::::0;::::1;::::0;::::1;-1:-1:-1::0;;;;;116175:30:0::1;116209:10;116175:44;116171:268;;;116274:23;::::0;;;:10:::1;:23;::::0;;;;:40;::::1;::::0;;::::1;116262:52:::0;;::::1;;;116236:124;;;;-1:-1:-1::0;;;116236:124:0::1;;;;;;;:::i;:::-;116375:23;::::0;;;:10:::1;:23;::::0;;;;:52;;116419:8;;116375:23;:52:::1;::::0;116419:8;;116375:52:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;116171:268;116449:48;116463:11;116476:8;116486:10;116449:13;:48::i;:::-;-1:-1:-1::0;;89605:1:0;90559:7;:22;115446:1059::o;123282:243::-;55528:4;55974:30;55528:4;33332:10;55974;:30::i;:::-;123450:5:::1;123434:12;:21;;;;123426:30;;;::::0;::::1;;-1:-1:-1::0;123467:35:0::1;:50:::0;;-1:-1:-1;;123467:50:0::1;;::::0;;;::::1;::::0;;;::::1;::::0;;123282:243::o;56832:519::-;56913:22;56921:4;56927:7;56913;:22::i;:::-;56908:436;;57101:52;57140:7;-1:-1:-1;;;;;57101:52:0;57150:2;57101:30;:52::i;:::-;57226:49;57265:4;57272:2;57226:30;:49::i;:::-;57006:292;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;57006:292:0;;;;;;;;;;-1:-1:-1;;;56952:380:0;;;;;;;:::i;56908:436::-;56832:519;;:::o;37078:349::-;37202:4;-1:-1:-1;;;;;;37239:51:0;;-1:-1:-1;;;37239:51:0;;:127;;-1:-1:-1;;;;;;;37307:59:0;;-1:-1:-1;;;37307:59:0;37239:127;:180;;;-1:-1:-1;;;;;;;;;;3561:51:0;;;37383:36;3452:168;4375:190;4460:4;4484:36;4508:11;4484:23;:36::i;:::-;:73;;;-1:-1:-1;;;;;;;;4524:33:0;;;;;:20;:33;;;;;;;;;4375:190::o;74001:225::-;74086:4;-1:-1:-1;;;;;;74110:68:0;;-1:-1:-1;;;74110:68:0;;:108;;;74182:36;74206:11;74182:23;:36::i;43031:127::-;43096:4;43120:16;;;:7;:16;;;;;;-1:-1:-1;;;;;43120:16:0;:30;;;43031:127::o;47046:185::-;47121:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;47121:29:0;-1:-1:-1;;;;;47121:29:0;;;;;;;;:24;;47175:34;47121:24;47175:25;:34::i;:::-;-1:-1:-1;;;;;47166:57:0;;;;;;;;;;;47046:185;;:::o;36621:219::-;2201:13;;;;;;;;:30;;-1:-1:-1;2219:12:0;;;;2218:13;2201:30;2193:89;;;;-1:-1:-1;;;2193:89:0;;;;;;;:::i;:::-;2295:19;2318:13;;;;;;2317:14;2342:101;;;;2377:13;:20;;-1:-1:-1;;2412:19:0;;;;;2342:101;36720:26:::1;:24;:26::i;:::-;36757:25;:23;:25::i;:::-;36793:39;36817:5;36824:7;36793:23;:39::i;:::-;2473:14:::0;2469:68;;;2520:5;2504:21;;-1:-1:-1;;2504:21:0;;;36621:219;;;:::o;55066:177::-;2201:13;;;;;;;;:30;;-1:-1:-1;2219:12:0;;;;2218:13;2201:30;2193:89;;;;-1:-1:-1;;;2193:89:0;;;;;;;:::i;:::-;2295:19;2318:13;;;;;;2317:14;2342:101;;;;2377:13;:20;;-1:-1:-1;;2412:19:0;;;;;2342:101;55130:26:::1;:24;:26::i;:::-;55167:25;:23;:25::i;:::-;55203:32;:30;:32::i;76319:169::-:0;76407:31;76424:4;76430:7;76407:16;:31::i;43325:359::-;43418:4;43443:16;43451:7;43443;:16::i;:::-;43435:73;;;;-1:-1:-1;;;43435:73:0;;28334:2:1;43435:73:0;;;28316:21:1;28373:2;28353:18;;;28346:30;28412:34;28392:18;;;28385:62;-1:-1:-1;;;28463:18:1;;;28456:42;28515:19;;43435:73:0;28306:234:1;43435:73:0;43519:13;43535:34;43561:7;43535:25;:34::i;:::-;43519:50;;43599:5;-1:-1:-1;;;;;43588:16:0;:7;-1:-1:-1;;;;;43588:16:0;;:51;;;;43632:7;-1:-1:-1;;;;;43608:31:0;:20;43620:7;43608:11;:20::i;:::-;-1:-1:-1;;;;;43608:31:0;;43588:51;:87;;;;43643:32;43660:5;43667:7;43643:16;:32::i;:::-;43580:96;43325:359;-1:-1:-1;;;;43325:359:0:o;46339:589::-;46509:4;-1:-1:-1;;;;;46471:42:0;:34;46497:7;46471:25;:34::i;:::-;-1:-1:-1;;;;;46471:42:0;;46463:96;;;;-1:-1:-1;;;46463:96:0;;34236:2:1;46463:96:0;;;34218:21:1;34275:2;34255:18;;;34248:30;34314:34;34294:18;;;34287:62;-1:-1:-1;;;34365:18:1;;;34358:39;34414:19;;46463:96:0;34208:231:1;46463:96:0;-1:-1:-1;;;;;46578:16:0;;46570:65;;;;-1:-1:-1;;;46570:65:0;;26897:2:1;46570:65:0;;;26879:21:1;26936:2;26916:18;;;26909:30;26975:34;26955:18;;;26948:62;-1:-1:-1;;;27026:18:1;;;27019:34;27070:19;;46570:65:0;26869:226:1;46570:65:0;46752:29;46769:1;46773:7;46752:8;:29::i;:::-;-1:-1:-1;;;;;46794:15:0;;;;;;:9;:15;;;;;:20;;46813:1;;46794:15;:20;;46813:1;;46794:20;:::i;:::-;;;;-1:-1:-1;;;;;;;46825:13:0;;;;;;:9;:13;;;;;:18;;46842:1;;46825:13;:18;;46842:1;;46825:18;:::i;:::-;;;;-1:-1:-1;;46854:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;46854:21:0;-1:-1:-1;;;;;46854:21:0;;;;;;;;;46893:27;;46854:16;;46893:27;;;;-1:-1:-1;;;;;;;;;;;46893:27:0;;46339:589;;;:::o;57925:147::-;58008:18;58021:4;58008:12;:18::i;:::-;55974:30;55985:4;33332:10;55974;:30::i;:::-;58039:25:::1;58050:4;58056:7;58039:10;:25::i;68497:152::-:0;68567:4;68591:50;68596:3;-1:-1:-1;;;;;68616:23:0;;68591:4;:50::i;58973:218::-;-1:-1:-1;;;;;59069:23:0;;33332:10;59069:23;59061:83;;;;-1:-1:-1;;;59061:83:0;;38528:2:1;59061:83:0;;;38510:21:1;38567:2;38547:18;;;38540:30;38606:34;38586:18;;;38579:62;-1:-1:-1;;;38657:18:1;;;38650:45;38712:19;;59061:83:0;38500:237:1;59061:83:0;59157:26;59169:4;59175:7;59157:11;:26::i;68825:158::-;68898:4;68922:53;68930:3;-1:-1:-1;;;;;68950:23:0;;68922:7;:53::i;101438:268::-;101534:4;101601:17;101563:24;;;;:10;:24;;;;;:34;;;;;:55;;;;;;-1:-1:-1;;;101563:55:0;;;;;;;;;;:135;;;;-1:-1:-1;101656:24:0;;;;:10;:24;;;;;:41;;;101622:76;;-1:-1:-1;;;;;101656:41:0;102571:218;102691:4;102740:15;102720:17;-1:-1:-1;;;;;102720:35:0;;:61;;;-1:-1:-1;;;;;;;102759:22:0;;;102571:218::o;105677:1035::-;106036:17;100049:52;100083:17;100049:33;:52::i;:::-;100041:70;;;;-1:-1:-1;;;100041:70:0;;;;;;;:::i;:::-;106071:40:::1;106085:12;106099:11;106071:13;:40::i;:::-;106124:24;::::0;;;:10:::1;:24;::::0;;;;;;;:53;;::::1;::::0;:37:::1;::::0;;::::1;::::0;:53;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;106194:16:0;;106190:98:::1;;106227:24;::::0;;;:10:::1;:24;::::0;;;;:35:::1;;:49:::0;;;106190:98:::1;106300:24;::::0;;;:10:::1;:24;::::0;;;;:61;;::::1;106372:65:::0;;::::1;-1:-1:-1::0;;;106372:65:0::1;-1:-1:-1::0;;;;;;106372:65:0;;;106300:61;;::::1;106372:65:::0;::::1;::::0;;-1:-1:-1;;;;;106454:23:0;::::1;::::0;106450:119:::1;;106494:24;::::0;;;:10:::1;:24;::::0;;;;:63;;-1:-1:-1;;;;;106494:63:0::1;-1:-1:-1::0;;;;;;;;106494:63:0;::::1;;;::::0;;106450:119:::1;-1:-1:-1::0;;;;;106593:22:0;::::1;::::0;106589:116:::1;;106632:24;::::0;;;:10:::1;:24;::::0;;;;:41:::1;;:61:::0;;-1:-1:-1;;;;;;106632:61:0::1;-1:-1:-1::0;;;;;106632:61:0;::::1;;::::0;;106589:116:::1;105677:1035:::0;;;;;;;;;:::o;104046:696::-;104177:24;;;;:10;:24;;;;;:34;;;:58;;104214:21;-1:-1:-1;;104177:58:0;;;;;;104348:22;;;104304:66;;-1:-1:-1;;;;;;;;104304:66:0;-1:-1:-1;;;104348:22:0;;;;-1:-1:-1;;;;;104348:22:0;;;-1:-1:-1;;;104304:66:0;;;;;;;;;104444:35;;-1:-1:-1;;;104400:33:0;;;;;;;;104348:22;;;104444:35;;104400:33;;104444:35;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;104444:35:0;;;;;-1:-1:-1;;;;;104444:35:0;;;;;;104490:14;;:16;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;104583:24:0;;;;:10;:24;;;;;;;:31;;;;104524:210;;;;;;104583:24;;:31;;;;-1:-1:-1;;;;;104583:31:0;;104629:9;;104653:18;;104686:37;;;;;104524:210;:::i;4972:201::-;-1:-1:-1;;;;;;5056:25:0;;;;;5048:66;;;;-1:-1:-1;;;5048:66:0;;25498:2:1;5048:66:0;;;25480:21:1;25537:2;25517:18;;;25510:30;-1:-1:-1;;;25556:18:1;;;25549:58;25624:18;;5048:66:0;25470:178:1;5048:66:0;-1:-1:-1;;;;;;5125:33:0;;;;;:20;:33;;;;;:40;;-1:-1:-1;;5125:40:0;5161:4;5125:40;;;4972:201::o;69793:158::-;69867:7;69918:22;69922:3;69934:5;69918:3;:22::i;42403:315::-;42560:28;42570:4;42576:2;42580:7;42560:9;:28::i;:::-;42607:48;42630:4;42636:2;42640:7;42649:5;42607:22;:48::i;:::-;42599:111;;;;-1:-1:-1;;;42599:111:0;;;;;;;:::i;102009:407::-;102204:4;102234:47;102268:12;102234:33;:47::i;:::-;:68;;;;-1:-1:-1;102285:17:0;;;102234:68;:173;;;;;102306:101;102314:48;102320:10;102340:20;102332:29;;119757:35;;-1:-1:-1;;;;;;18529:2:1;18500:15;;;18496:45;119757:35:0;;;18484:58:1;18558:12;;;18551:28;;;119715:7:0;;18595:12:1;;119757:35:0;;;;;;;;;;;;119747:46;;;;;;119740:53;;119615:186;;;;;102314:48;102364:10;:24;102375:12;102364:24;;;;;;;;;;;:35;;;102401:5;;102306:101;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;102306:7:0;;-1:-1:-1;;;102306:101:0:i;:::-;102226:182;102009:407;-1:-1:-1;;;;;102009:407:0:o;118109:1059::-;118295:19;118317:24;;;:10;:24;;;;;:35;;;;;118380:30;;;;-1:-1:-1;;;;;118317:35:0;;;;-1:-1:-1;;;118380:30:0;;-1:-1:-1;;;;;118380:30:0;118317:35;118421:740;;118475:17;;118467:46;;;;-1:-1:-1;;;118467:46:0;;26212:2:1;118467:46:0;;;26194:21:1;26251:2;26231:18;;;26224:30;-1:-1:-1;;;26270:18:1;;;26263:46;26326:18;;118467:46:0;26184:166:1;118467:46:0;118567:18;118579:6;118567:18;;;;:::i;:::-;-1:-1:-1;;;;;118554:31:0;:9;:31;118528:106;;;;-1:-1:-1;;;118528:106:0;;;;;;;:::i;:::-;118649:64;118667:12;118681:11;118694:9;118705:7;118649:17;:64::i;:::-;118421:740;;;118754:9;:14;118746:41;;;;-1:-1:-1;;;118746:41:0;;37159:2:1;118746:41:0;;;37141:21:1;37198:2;37178:18;;;37171:30;-1:-1:-1;;;37217:18:1;;;37210:44;37271:18;;118746:41:0;37131:164:1;118746:41:0;118844:18;118856:6;118844:18;;;;:::i;:::-;-1:-1:-1;;;;;118828:34:0;:12;:34;118802:109;;;;-1:-1:-1;;;118802:109:0;;;;;;;:::i;:::-;118928:139;;-1:-1:-1;;;118928:139:0;;118979:10;118928:139;;;21479:34:1;119016:4:0;21529:18:1;;;21522:43;21581:18;;;21574:34;;;-1:-1:-1;;;;;118928:32:0;;;;;21414:18:1;;118928:139:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;119082:67;119100:12;119114:11;119127:12;119141:7;119082:17;:67::i;:::-;118109:1059;;;;;;:::o;116736:1121::-;116841:18;116862:24;;;:10;:24;;;;;:41;-1:-1:-1;;;;;;;;116862:41:0;;;;;-1:-1:-1;;;116930:33:0;;;;;116974:756;116993:9;116989:13;;:1;:13;;;116974:756;;;117041:1;117032:6;-1:-1:-1;;;;;117032:10:0;;117024:37;;;;-1:-1:-1;;;117024:37:0;;30341:2:1;117024:37:0;;;30323:21:1;30380:2;30360:18;;;30353:30;-1:-1:-1;;;30399:18:1;;;30392:44;30453:18;;117024:37:0;30313:164:1;117024:37:0;117090:36;117096:13;117111:14;;;;:10;:14;:::i;:::-;-1:-1:-1;;;;;117090:36:0;:5;:36::i;:::-;117178:12;117141:18;:34;117160:14;;;;:10;:14;:::i;:::-;-1:-1:-1;;;;;117141:34:0;;;;;;;;;;;;:49;;;;117207:18;117295:12;117330:15;117368:14;117405:6;117256:174;;;;;;;;;;20782:19:1;;;20826:2;20817:12;;20810:28;;;;20901:2;20872:15;-1:-1:-1;;;;;;20868:45:1;20863:2;20854:12;;20847:67;20978:3;20948:16;-1:-1:-1;;;;;;20944:47:1;20939:2;20930:12;;20923:69;21017:2;21008:12;;20772:254;117256:174:0;;;;;;;-1:-1:-1;;117256:174:0;;;;;;117228:217;;117256:174;117228:217;;;;117530:24;;;;:10;:24;;;;;:31;;;117228:217;;-1:-1:-1;117465:230:0;;117530:24;;:31;;;-1:-1:-1;;;;;117530:31:0;117580:13;117612:14;;;;:10;:14;:::i;:::-;117465:230;;;39544:25:1;;;-1:-1:-1;;;;;39643:15:1;;;39638:2;39623:18;;39616:43;39695:15;;;;39675:18;;;39668:43;-1:-1:-1;;;;;39747:32:1;39742:2;39727:18;;39720:60;-1:-1:-1;;;;;39817:31:1;;39767:3;39796:19;;39789:60;39596:3;39865:19;;39858:35;;;39531:3;39516:19;117465:230:0;;;;;;;117710:8;;;:::i;:::-;;;116974:756;117004:3;;;;;:::i;:::-;;;;116974:756;;;-1:-1:-1;117742:24:0;;;;:10;:24;;;;;:54;;;;;;:24;:41;;:54;;;;-1:-1:-1;;;117742:54:0;;-1:-1:-1;;;;;117742:54:0;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;117742:54:0;;;;;;;;;;;;;;;-1:-1:-1;117807:24:0;;;:10;:24;;;;;;:42;;-1:-1:-1;;;;;;;;117807:42:0;-1:-1:-1;;;117807:42:0;;;;;;;;;;;;;;-1:-1:-1;;;;116736:1121:0:o;33733:723::-;33789:13;34010:10;34006:53;;-1:-1:-1;;34037:10:0;;;;;;;;;;;;-1:-1:-1;;;34037:10:0;;;;;33733:723::o;34006:53::-;34084:5;34069:12;34125:78;34132:9;;34125:78;;34158:8;;;;:::i;:::-;;-1:-1:-1;34181:10:0;;-1:-1:-1;34189:2:0;34181:10;;:::i;:::-;;;34125:78;;;34213:19;34245:6;-1:-1:-1;;;;;34235:17:0;;;;;-1:-1:-1;;;34235:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34235:17:0;;34213:39;;34263:154;34270:10;;34263:154;;34297:11;34307:1;34297:11;;:::i;:::-;;-1:-1:-1;34366:10:0;34374:2;34366:5;:10;:::i;:::-;34353:24;;:2;:24;:::i;:::-;34340:39;;34323:6;34330;34323:14;;;;;;-1:-1:-1;;;34323:14:0;;;;;;;;;;;;:56;-1:-1:-1;;;;;34323:56:0;;;;;;;;-1:-1:-1;34394:11:0;34403:2;34394:11;;:::i;:::-;;;34263:154;;69322:117;69385:7;69412:19;69420:3;64806:18;;64723:109;103394:474;103527:4;103591:7;:14;103566;:21;:39;103544:96;;;;-1:-1:-1;;;103544:96:0;;38944:2:1;103544:96:0;;;38926:21:1;38983:1;38963:18;;;38956:29;-1:-1:-1;;;39001:18:1;;;38994:37;39048:18;;103544:96:0;38916:156:1;103544:96:0;103651:19;103686:9;103681:108;103701:7;:14;103697:1;:18;103681:108;;;103767:7;103775:1;103767:10;;;;;;-1:-1:-1;;;103767:10:0;;;;;;;;;;;;;;;103752:12;:25;;;;:::i;:::-;103737:40;-1:-1:-1;103717:3:0;;;;:::i;:::-;;;;103681:108;;;;103823:5;103807:12;:21;;;;103799:39;;;;-1:-1:-1;;;103799:39:0;;33568:2:1;103799:39:0;;;33550:21:1;33607:1;33587:18;;;33580:29;-1:-1:-1;;;33625:18:1;;;33618:35;33670:18;;103799:39:0;33540:154:1;103799:39:0;-1:-1:-1;103856:4:0;;103394:474;-1:-1:-1;;;103394:474:0:o;58317:149::-;58401:18;58414:4;58401:12;:18::i;:::-;55974:30;55985:4;33332:10;55974;:30::i;:::-;58432:26:::1;58444:4;58450:7;58432:11;:26::i;102939:211::-:0;103054:4;103121:21;103083:24;;;;:10;:24;;;;;:34;;;;;:59;;;;;;-1:-1:-1;;;103083:59:0;;;;;;;;;;;102939:211;-1:-1:-1;;102939:211:0:o;35034:451::-;35109:13;35135:19;35167:10;35171:6;35167:1;:10;:::i;:::-;:14;;35180:1;35167:14;:::i;:::-;-1:-1:-1;;;;;35157:25:0;;;;;-1:-1:-1;;;35157:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35157:25:0;;35135:47;;-1:-1:-1;;;35193:6:0;35200:1;35193:9;;;;;;-1:-1:-1;;;35193:9:0;;;;;;;;;;;;:15;-1:-1:-1;;;;;35193:15:0;;;;;;;;;-1:-1:-1;;;35219:6:0;35226:1;35219:9;;;;;;-1:-1:-1;;;35219:9:0;;;;;;;;;;;;:15;-1:-1:-1;;;;;35219:15:0;;;;;;;;-1:-1:-1;35250:9:0;35262:10;35266:6;35262:1;:10;:::i;:::-;:14;;35275:1;35262:14;:::i;:::-;35250:26;;35245:135;35282:1;35278;:5;35245:135;;;-1:-1:-1;;;35330:5:0;35338:3;35330:11;35317:25;;;;;-1:-1:-1;;;35317:25:0;;;;;;;;;;;;35305:6;35312:1;35305:9;;;;;;-1:-1:-1;;;35305:9:0;;;;;;;;;;;;:37;-1:-1:-1;;;;;35305:37:0;;;;;;;;-1:-1:-1;35367:1:0;35357:11;;;;;35285:3;;;:::i;:::-;;;35245:135;;;-1:-1:-1;35398:10:0;;35390:55;;;;-1:-1:-1;;;35390:55:0;;24381:2:1;35390:55:0;;;24363:21:1;;;24400:18;;;24393:30;24459:34;24439:18;;;24432:62;24511:18;;35390:55:0;24353:182:1;56096:215:0;56181:4;-1:-1:-1;;;;;;56205:58:0;;-1:-1:-1;;;56205:58:0;;:98;;;56267:36;56291:11;56267:23;:36::i;33181:65::-;2201:13;;;;;;;;:30;;-1:-1:-1;2219:12:0;;;;2218:13;2201:30;2193:89;;;;-1:-1:-1;;;2193:89:0;;;;;;;:::i;:::-;2295:19;2318:13;;;;;;2317:14;2342:101;;;;2377:13;:20;;-1:-1:-1;;2412:19:0;;;;;2469:68;;;;2520:5;2504:21;;-1:-1:-1;;2504:21:0;;;33181:65;:::o;36848:158::-;2201:13;;;;;;;;:30;;-1:-1:-1;2219:12:0;;;;2218:13;2201:30;2193:89;;;;-1:-1:-1;;;2193:89:0;;;;;;;:::i;:::-;2295:19;2318:13;;;;;;2317:14;2342:101;;;;2377:13;:20;;-1:-1:-1;;2412:19:0;;;;;2342:101;36957:13;;::::1;::::0;:5:::1;::::0;:13:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;36981:17:0;;::::1;::::0;:7:::1;::::0;:17:::1;::::0;::::1;::::0;::::1;:::i;:::-;;2473:14:::0;2469:68;;;2520:5;2504:21;;-1:-1:-1;;2504:21:0;;;36848:158;;;:::o;59774:112::-;59853:25;59864:4;59870:7;60277:229;60352:22;60360:4;60366:7;60352;:22::i;:::-;60347:152;;60391:12;;;;:6;:12;;;;;;;;-1:-1:-1;;;;;60391:29:0;;;;;;;;;:36;;-1:-1:-1;;60391:36:0;60423:4;60391:36;;;60474:12;33332:10;;33252:98;60474:12;-1:-1:-1;;;;;60447:40:0;60465:7;-1:-1:-1;;;;;60447:40:0;60459:4;60447:40;;;;;;;;;;60277:229;;:::o;62412:414::-;62475:4;64605:19;;;:12;;;:19;;;;;;62492:327;;-1:-1:-1;62535:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;62718:18;;62696:19;;;:12;;;:19;;;;;;:40;;;;62751:11;;62492:327;-1:-1:-1;62802:5:0;62795:12;;60514:230;60589:22;60597:4;60603:7;60589;:22::i;:::-;60585:152;;;60660:5;60628:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;60628:29:0;;;;;;;;;;:37;;-1:-1:-1;;60628:37:0;;;60685:40;33332:10;;60628:12;;60685:40;;60660:5;60685:40;60514:230;;:::o;63002:1420::-;63068:4;63207:19;;;:12;;;:19;;;;;;63243:15;;63239:1176;;63618:21;63642:14;63655:1;63642:10;:14;:::i;:::-;63691:18;;63618:38;;-1:-1:-1;63671:17:0;;63691:22;;63712:1;;63691:22;:::i;:::-;63671:42;;63747:13;63734:9;:26;63730:405;;63781:17;63801:3;:11;;63813:9;63801:22;;;;;;-1:-1:-1;;;63801:22:0;;;;;;;;;;;;;;;;;63781:42;;63955:9;63926:3;:11;;63938:13;63926:26;;;;;;-1:-1:-1;;;63926:26:0;;;;;;;;;;;;;;;;;;;;:38;;;;64040:23;;;:12;;;:23;;;;;:36;;;63730:405;64216:17;;:3;;:17;;;-1:-1:-1;;;64216:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;64311:3;:12;;:19;64324:5;64311:19;;;;;;;;;;;64304:26;;;64354:4;64347:11;;;;;;;63239:1176;64398:5;64391:12;;;;;104914:200;-1:-1:-1;;;;;105004:25:0;;;105000:107;;105046:24;;;;:10;:24;;;;;:35;;:49;;-1:-1:-1;;;;;105046:49:0;;-1:-1:-1;;;;;;105046:49:0;;;;;;104914:200;;:::o;65186:120::-;65253:7;65280:3;:11;;65292:5;65280:18;;;;;;-1:-1:-1;;;65280:18:0;;;;;;;;;;;;;;;;;65273:25;;65186:120;;;;:::o;47796:821::-;47951:4;-1:-1:-1;;;;;47972:13:0;;26484:20;26532:8;47968:642;;48008:83;;-1:-1:-1;;;48008:83:0;;-1:-1:-1;;;;;48008:47:0;;;;;:83;;33332:10;;48070:4;;48076:7;;48085:5;;48008:83;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48008:83:0;;;;;;;;-1:-1:-1;;48008:83:0;;;;;;;;;;;;:::i;:::-;;;48004:551;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48272:13:0;;48268:272;;48315:60;;-1:-1:-1;;;48315:60:0;;;;;;;:::i;48268:272::-;48490:6;48484:13;48475:6;48471:2;48467:15;48460:38;48004:551;-1:-1:-1;;;;;;48142:62:0;-1:-1:-1;;;48142:62:0;;-1:-1:-1;48135:69:0;;47968:642;-1:-1:-1;48594:4:0;48587:11;;120051:207;120183:4;120207:43;120226:5;120233:10;120245:4;120207:18;:43::i;125762:743::-;125929:38;125970:61;126008:12;125970:23;:61::i;:::-;125929:102;;126042:30;126075;126092:12;126075:16;:30::i;:::-;126042:63;;126116:16;126150:9;126145:237;126165:21;:28;126161:1;:32;126145:237;;;126215:11;126259:5;126240:14;126255:1;126240:17;;;;;;-1:-1:-1;;;126240:17:0;;;;;;;;;;;;;;;126230:27;;:7;:27;;;;:::i;:::-;126229:35;;;;:::i;:::-;126215:49;-1:-1:-1;126290:14:0;126215:49;126290:8;:14;:::i;:::-;126279:25;;126319:51;126327:21;126349:1;126327:24;;;;;;-1:-1:-1;;;126327:24:0;;;;;;;;;;;;;;;126353:11;126366:3;126319:7;:51::i;:::-;-1:-1:-1;126195:3:0;;;;:::i;:::-;;;;126145:237;;;-1:-1:-1;126417:1:0;126396:18;126406:8;126396:7;:18;:::i;:::-;:22;126392:106;;;126435:51;126443:7;126452:11;126466:18;126476:8;126466:7;:18;:::i;:::-;126435:7;:51::i;:::-;125762:743;;;;;;;:::o;45020:382::-;-1:-1:-1;;;;;45100:16:0;;45092:61;;;;-1:-1:-1;;;45092:61:0;;31434:2:1;45092:61:0;;;31416:21:1;;;31453:18;;;31446:30;31512:34;31492:18;;;31485:62;31564:18;;45092:61:0;31406:182:1;45092:61:0;45173:16;45181:7;45173;:16::i;:::-;45172:17;45164:58;;;;-1:-1:-1;;;45164:58:0;;25855:2:1;45164:58:0;;;25837:21:1;25894:2;25874:18;;;25867:30;-1:-1:-1;;;25913:18:1;;;25906:58;25981:18;;45164:58:0;25827:178:1;45164:58:0;-1:-1:-1;;;;;45293:13:0;;;;;;:9;:13;;;;;:18;;45310:1;;45293:13;:18;;45310:1;;45293:18;:::i;:::-;;;;-1:-1:-1;;45322:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;45322:21:0;-1:-1:-1;;;;;45322:21:0;;;;;;;;45361:33;;45322:16;;;-1:-1:-1;;;;;;;;;;;45361:33:0;45322:16;;45361:33;45020:382;;:::o;80429:190::-;80554:4;80607;80578:25;80591:5;80598:4;80578:12;:25::i;:::-;:33;;80429:190;-1:-1:-1;;;;80429:190:0:o;126765:727::-;-1:-1:-1;;;;;126898:25:0;;;126894:591;;126940:49;;-1:-1:-1;;;126940:49:0;;-1:-1:-1;;;;;22304:32:1;;;126940:49:0;;;22286:51:1;22353:18;;;22346:34;;;126940:28:0;;;;;22259:18:1;;126940:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;126894:591::-;127082:12;127108:10;-1:-1:-1;;;;;127100:24:0;127150:7;127181:5;127100:105;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;127081:124;;;127309:7;127304:170;;-1:-1:-1;;;;;127394:33:0;;;;;;:21;:33;;;;;;:64;;127451:7;;127394:64;:::i;:::-;-1:-1:-1;;;;;127337:33:0;;;;;;:21;:33;;;;;:121;126894:591;126765:727;;;:::o;81296:296::-;81379:7;81422:4;81379:7;81437:118;81461:5;:12;81457:1;:16;81437:118;;;81510:33;81520:12;81534:5;81540:1;81534:8;;;;;;-1:-1:-1;;;81534:8:0;;;;;;;;;;;;;;;81510:9;:33::i;:::-;81495:48;-1:-1:-1;81475:3:0;;;;:::i;:::-;;;;81437:118;;;-1:-1:-1;81572:12:0;81296:296;-1:-1:-1;;;81296:296:0:o;87503:149::-;87566:7;87597:1;87593;:5;:51;;87728:13;87822:15;;;87858:4;87851:15;;;87905:4;87889:21;;87593:51;;;87728:13;87822:15;;;87858:4;87851:15;;;87905:4;87889:21;;87601:20;87807:114;-1:-1:-1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:406:1;78:5;-1:-1:-1;;;;;101:30:1;;98:2;;;134:18;;:::i;:::-;172:57;217:2;196:15;;-1:-1:-1;;192:29:1;223:4;188:40;172:57;:::i;:::-;163:66;;252:6;245:5;238:21;292:3;283:6;278:3;274:16;271:25;268:2;;;309:1;306;299:12;268:2;358:6;353:3;346:4;339:5;335:16;322:43;412:1;405:4;396:6;389:5;385:18;381:29;374:40;88:332;;;;;:::o;425:768::-;479:5;532:3;525:4;517:6;513:17;509:27;499:2;;554:5;547;540:20;499:2;594:6;581:20;620:4;644:60;660:43;700:2;660:43;:::i;:::-;644:60;:::i;:::-;726:3;750:2;745:3;738:15;778:2;773:3;769:12;762:19;;813:2;805:6;801:15;865:3;860:2;854;851:1;847:10;839:6;835:23;831:32;828:41;825:2;;;886:5;879;872:20;825:2;912:5;926:238;940:2;937:1;934:9;926:238;;;1011:3;998:17;1028:31;1053:5;1028:31;:::i;:::-;1072:18;;1110:12;;;;1142;;;;958:1;951:9;926:238;;;-1:-1:-1;1182:5:1;;489:704;-1:-1:-1;;;;;;;489:704:1:o;1198:395::-;1261:8;1271:6;1325:3;1318:4;1310:6;1306:17;1302:27;1292:2;;1350:8;1340;1333:26;1292:2;-1:-1:-1;1380:20:1;;-1:-1:-1;;;;;1412:30:1;;1409:2;;;1462:8;1452;1445:26;1409:2;1506:4;1498:6;1494:17;1482:29;;1566:3;1559:4;1549:6;1546:1;1542:14;1534:6;1530:27;1526:38;1523:47;1520:2;;;1583:1;1580;1573:12;1520:2;1282:311;;;;;:::o;1598:697::-;1651:5;1704:3;1697:4;1689:6;1685:17;1681:27;1671:2;;1726:5;1719;1712:20;1671:2;1766:6;1753:20;1792:4;1816:60;1832:43;1872:2;1832:43;:::i;1816:60::-;1898:3;1922:2;1917:3;1910:15;1950:2;1945:3;1941:12;1934:19;;1985:2;1977:6;1973:15;2037:3;2032:2;2026;2023:1;2019:10;2011:6;2007:23;2003:32;2000:41;1997:2;;;2058:5;2051;2044:20;1997:2;2084:5;2098:168;2112:2;2109:1;2106:9;2098:168;;;2169:22;2187:3;2169:22;:::i;:::-;2157:35;;2212:12;;;;2244;;;;2130:1;2123:9;2098:168;;2300:128;2365:20;;2394:28;2365:20;2394:28;:::i;2433:229::-;2476:5;2529:3;2522:4;2514:6;2510:17;2506:27;2496:2;;2551:5;2544;2537:20;2496:2;2577:79;2652:3;2643:6;2630:20;2623:4;2615:6;2611:17;2577:79;:::i;2667:850::-;2723:5;2771:4;2759:9;2754:3;2750:19;2746:30;2743:2;;;2793:5;2786;2779:20;2743:2;2819:22;;:::i;:::-;2810:31;-1:-1:-1;2864:23:1;;-1:-1:-1;;;;;2936:14:1;;;2933:2;;;2963:1;2960;2953:12;2933:2;2990:56;3042:3;3033:6;3022:9;3018:22;2990:56;:::i;:::-;2983:5;2976:71;3100:2;3089:9;3085:18;3072:32;3056:48;;3129:2;3119:8;3116:16;3113:2;;;3145:1;3142;3135:12;3113:2;3181:59;3236:3;3225:8;3214:9;3210:24;3181:59;:::i;:::-;3176:2;3169:5;3165:14;3158:83;3294:2;3283:9;3279:18;3266:32;3250:48;;3323:2;3313:8;3310:16;3307:2;;;3339:1;3336;3329:12;3307:2;;3375:67;3438:3;3427:8;3416:9;3412:24;3375:67;:::i;:::-;3370:2;3363:5;3359:14;3352:91;;3475:35;3506:2;3495:9;3491:18;3475:35;:::i;:::-;3470:2;3463:5;3459:14;3452:59;2733:784;;;;:::o;3522:797::-;3587:5;3635:4;3623:9;3618:3;3614:19;3610:30;3607:2;;;3657:5;3650;3643:20;3607:2;3683:22;;:::i;:::-;3674:31;-1:-1:-1;3728:23:1;;-1:-1:-1;;;;;3800:14:1;;;3797:2;;;3827:1;3824;3817:12;3797:2;3854:57;3907:3;3898:6;3887:9;3883:22;3854:57;:::i;:::-;3847:5;3840:72;3965:2;3954:9;3950:18;3937:32;3921:48;;3994:2;3984:8;3981:16;3978:2;;;4010:1;4007;4000:12;3978:2;;4046:58;4100:3;4089:8;4078:9;4074:24;4046:58;:::i;:::-;4041:2;4034:5;4030:14;4023:82;;4137:37;4170:2;4159:9;4155:18;4137:37;:::i;:::-;4132:2;4125:5;4121:14;4114:61;4227:2;4216:9;4212:18;4199:32;4240:33;4265:7;4240:33;:::i;4324:163::-;4391:20;;4451:10;4440:22;;4430:33;;4420:2;;4477:1;4474;4467:12;4492:171;4559:20;;-1:-1:-1;;;;;4608:30:1;;4598:41;;4588:2;;4653:1;4650;4643:12;4668:257;4727:6;4780:2;4768:9;4759:7;4755:23;4751:32;4748:2;;;4801:6;4793;4786:22;4748:2;4845:9;4832:23;4864:31;4889:5;4864:31;:::i;4930:261::-;5000:6;5053:2;5041:9;5032:7;5028:23;5024:32;5021:2;;;5074:6;5066;5059:22;5021:2;5111:9;5105:16;5130:31;5155:5;5130:31;:::i;5466:398::-;5534:6;5542;5595:2;5583:9;5574:7;5570:23;5566:32;5563:2;;;5616:6;5608;5601:22;5563:2;5660:9;5647:23;5679:31;5704:5;5679:31;:::i;:::-;5729:5;-1:-1:-1;5786:2:1;5771:18;;5758:32;5799:33;5758:32;5799:33;:::i;:::-;5851:7;5841:17;;;5553:311;;;;;:::o;5869:466::-;5946:6;5954;5962;6015:2;6003:9;5994:7;5990:23;5986:32;5983:2;;;6036:6;6028;6021:22;5983:2;6080:9;6067:23;6099:31;6124:5;6099:31;:::i;:::-;6149:5;-1:-1:-1;6206:2:1;6191:18;;6178:32;6219:33;6178:32;6219:33;:::i;:::-;5973:362;;6271:7;;-1:-1:-1;;;6325:2:1;6310:18;;;;6297:32;;5973:362::o;6340:824::-;6435:6;6443;6451;6459;6512:3;6500:9;6491:7;6487:23;6483:33;6480:2;;;6534:6;6526;6519:22;6480:2;6578:9;6565:23;6597:31;6622:5;6597:31;:::i;:::-;6647:5;-1:-1:-1;6704:2:1;6689:18;;6676:32;6717:33;6676:32;6717:33;:::i;:::-;6769:7;-1:-1:-1;6823:2:1;6808:18;;6795:32;;-1:-1:-1;6878:2:1;6863:18;;6850:32;-1:-1:-1;;;;;6894:30:1;;6891:2;;;6942:6;6934;6927:22;6891:2;6970:22;;7023:4;7015:13;;7011:27;-1:-1:-1;7001:2:1;;7057:6;7049;7042:22;7001:2;7085:73;7150:7;7145:2;7132:16;7127:2;7123;7119:11;7085:73;:::i;:::-;7075:83;;;6470:694;;;;;;;:::o;7169:392::-;7234:6;7242;7295:2;7283:9;7274:7;7270:23;7266:32;7263:2;;;7316:6;7308;7301:22;7263:2;7360:9;7347:23;7379:31;7404:5;7379:31;:::i;:::-;7429:5;-1:-1:-1;7486:2:1;7471:18;;7458:32;7499:30;7458:32;7499:30;:::i;7566:878::-;7717:6;7725;7733;7786:2;7774:9;7765:7;7761:23;7757:32;7754:2;;;7807:6;7799;7792:22;7754:2;7851:9;7838:23;7870:31;7895:5;7870:31;:::i;:::-;7920:5;-1:-1:-1;7976:2:1;7961:18;;7948:32;-1:-1:-1;;;;;8029:14:1;;;8026:2;;;8061:6;8053;8046:22;8026:2;8089:22;;;;8145:3;8127:16;;;8123:26;8120:2;;;8167:6;8159;8152:22;8120:2;8195;;-1:-1:-1;8250:2:1;8235:18;;8222:32;;8266:16;;;8263:2;;;8300:6;8292;8285:22;8263:2;-1:-1:-1;8328:24:1;;8386:3;8368:16;;;8364:26;8361:2;;;8408:6;8400;8393:22;8361:2;8436;8426:12;;;7744:700;;;;;:::o;8449:325::-;8517:6;8525;8578:2;8566:9;8557:7;8553:23;8549:32;8546:2;;;8599:6;8591;8584:22;8546:2;8643:9;8630:23;8662:31;8687:5;8662:31;:::i;:::-;8712:5;8764:2;8749:18;;;;8736:32;;-1:-1:-1;;;8536:238:1:o;8779:255::-;8846:6;8899:2;8887:9;8878:7;8874:23;8870:32;8867:2;;;8920:6;8912;8905:22;8867:2;8957:9;8951:16;8976:28;8998:5;8976:28;:::i;9039:190::-;9098:6;9151:2;9139:9;9130:7;9126:23;9122:32;9119:2;;;9172:6;9164;9157:22;9119:2;-1:-1:-1;9200:23:1;;9109:120;-1:-1:-1;9109:120:1:o;9234:325::-;9302:6;9310;9363:2;9351:9;9342:7;9338:23;9334:32;9331:2;;;9384:6;9376;9369:22;9331:2;9425:9;9412:23;9402:33;;9485:2;9474:9;9470:18;9457:32;9498:31;9523:5;9498:31;:::i;9564:258::-;9632:6;9640;9693:2;9681:9;9672:7;9668:23;9664:32;9661:2;;;9714:6;9706;9699:22;9661:2;-1:-1:-1;;9742:23:1;;;9812:2;9797:18;;;9784:32;;-1:-1:-1;9651:171:1:o;9827:255::-;9885:6;9938:2;9926:9;9917:7;9913:23;9909:32;9906:2;;;9959:6;9951;9944:22;9906:2;10003:9;9990:23;10022:30;10046:5;10022:30;:::i;10087:259::-;10156:6;10209:2;10197:9;10188:7;10184:23;10180:32;10177:2;;;10230:6;10222;10215:22;10177:2;10267:9;10261:16;10286:30;10310:5;10286:30;:::i;10351:874::-;10482:6;10490;10498;10506;10550:9;10541:7;10537:23;10580:3;10576:2;10572:12;10569:2;;;10602:6;10594;10587:22;10569:2;10634:23;;-1:-1:-1;;;;;10706:14:1;;;10703:2;;;10738:6;10730;10723:22;10703:2;10766:50;10808:7;10799:6;10788:9;10784:22;10766:50;:::i;:::-;10756:60;;10869:2;10858:9;10854:18;10841:32;10825:48;;10898:2;10888:8;10885:16;10882:2;;;10919:6;10911;10904:22;10882:2;;10947:52;10991:7;10980:8;10969:9;10965:24;10947:52;:::i;:::-;10937:62;-1:-1:-1;;11033:2:1;-1:-1:-1;;11015:16:1;;11011:25;11008:2;;;11054:6;11046;11039:22;11008:2;;11097;11086:9;11082:18;11072:28;;11150:3;11139:9;11135:19;11122:33;11164:31;11189:5;11164:31;:::i;:::-;10517:708;;;;-1:-1:-1;10517:708:1;;-1:-1:-1;;10517:708:1:o;11230:306::-;11289:6;11342:2;11330:9;11321:7;11317:23;11313:32;11310:2;;;11363:6;11355;11348:22;11310:2;11394:23;;-1:-1:-1;;;;;11446:31:1;;11436:42;;11426:2;;11497:6;11489;11482:22;12329:410;12407:6;12415;12468:2;12456:9;12447:7;12443:23;12439:32;12436:2;;;12489:6;12481;12474:22;12436:2;12517:23;;;-1:-1:-1;12591:2:1;12576:18;;12563:32;-1:-1:-1;;;;;12607:30:1;;12604:2;;;12655:6;12647;12640:22;12604:2;12683:50;12725:7;12716:6;12705:9;12701:22;12683:50;:::i;:::-;12673:60;;;12426:313;;;;;:::o;12744:437::-;12839:6;12847;12900:2;12888:9;12879:7;12875:23;12871:32;12868:2;;;12921:6;12913;12906:22;12868:2;12949:23;;;-1:-1:-1;13023:2:1;13008:18;;12995:32;-1:-1:-1;;;;;13039:30:1;;13036:2;;;13087:6;13079;13072:22;13036:2;13115:60;13167:7;13158:6;13147:9;13143:22;13115:60;:::i;13186:262::-;13253:6;13261;13314:2;13302:9;13293:7;13289:23;13285:32;13282:2;;;13335:6;13327;13320:22;13282:2;13376:9;13363:23;13353:33;;13405:37;13438:2;13427:9;13423:18;13405:37;:::i;:::-;13395:47;;13272:176;;;;;:::o;13453:739::-;13573:6;13581;13589;13597;13605;13613;13666:3;13654:9;13645:7;13641:23;13637:33;13634:2;;;13688:6;13680;13673:22;13634:2;13729:9;13716:23;13706:33;;13758:37;13791:2;13780:9;13776:18;13758:37;:::i;:::-;13748:47;;13814:37;13847:2;13836:9;13832:18;13814:37;:::i;:::-;13804:47;-1:-1:-1;13898:2:1;13883:18;;13870:32;;-1:-1:-1;13953:3:1;13938:19;;13925:33;-1:-1:-1;;;;;13970:30:1;;13967:2;;;14018:6;14010;14003:22;13967:2;14062:70;14124:7;14115:6;14104:9;14100:22;14062:70;:::i;:::-;13624:568;;;;-1:-1:-1;13624:568:1;;-1:-1:-1;13624:568:1;;14151:8;;13624:568;-1:-1:-1;;;13624:568:1:o;14197:875::-;14326:6;14334;14342;14350;14358;14366;14374;14427:3;14415:9;14406:7;14402:23;14398:33;14395:2;;;14449:6;14441;14434:22;14395:2;14490:9;14477:23;14467:33;;14519:37;14552:2;14541:9;14537:18;14519:37;:::i;:::-;14509:47;;14575:37;14608:2;14597:9;14593:18;14575:37;:::i;:::-;14565:47;-1:-1:-1;14659:2:1;14644:18;;14631:32;;-1:-1:-1;14714:3:1;14699:19;;14686:33;-1:-1:-1;;;;;14731:30:1;;14728:2;;;14779:6;14771;14764:22;14728:2;14823:70;14885:7;14876:6;14865:9;14861:22;14823:70;:::i;:::-;14912:8;;-1:-1:-1;14797:96:1;-1:-1:-1;;14997:3:1;14982:19;;14969:33;15011:31;14969:33;15011:31;:::i;:::-;15061:5;15051:15;;;14385:687;;;;;;;;;;:::o;15077:334::-;15152:6;15160;15168;15221:2;15209:9;15200:7;15196:23;15192:32;15189:2;;;15242:6;15234;15227:22;15189:2;15283:9;15270:23;15260:33;;15312:37;15345:2;15334:9;15330:18;15312:37;:::i;:::-;15302:47;;15368:37;15401:2;15390:9;15386:18;15368:37;:::i;:::-;15358:47;;15179:232;;;;;:::o;15416:194::-;15474:6;15527:2;15515:9;15506:7;15502:23;15498:32;15495:2;;;15548:6;15540;15533:22;15495:2;15576:28;15594:9;15576:28;:::i;15615:194::-;15673:6;15726:2;15714:9;15705:7;15701:23;15697:32;15694:2;;;15747:6;15739;15732:22;15694:2;15775:28;15793:9;15775:28;:::i;15814:104::-;-1:-1:-1;;;;;15880:31:1;15868:44;;15858:60::o;15923:463::-;15976:3;16014:5;16008:12;16041:6;16036:3;16029:19;16067:4;16096:2;16091:3;16087:12;16080:19;;16133:2;16126:5;16122:14;16154:3;16166:195;16180:6;16177:1;16174:13;16166:195;;;16245:13;;-1:-1:-1;;;;;16241:39:1;16229:52;;16301:12;;;;16336:15;;;;16277:1;16195:9;16166:195;;;-1:-1:-1;16377:3:1;;15984:402;-1:-1:-1;;;;;15984:402:1:o;16391:453::-;16443:3;16481:5;16475:12;16508:6;16503:3;16496:19;16534:4;16563:2;16558:3;16554:12;16547:19;;16600:2;16593:5;16589:14;16621:3;16633:186;16647:6;16644:1;16641:13;16633:186;;;16712:13;;16727:10;16708:30;16696:43;;16759:12;;;;16794:15;;;;16669:1;16662:9;16633:186;;16945:257;16986:3;17024:5;17018:12;17051:6;17046:3;17039:19;17067:63;17123:6;17116:4;17111:3;17107:14;17100:4;17093:5;17089:16;17067:63;:::i;:::-;17184:2;17163:15;-1:-1:-1;;17159:29:1;17150:39;;;;17191:4;17146:50;;16994:208;-1:-1:-1;;16994:208:1:o;17207:237::-;17288:1;17281:5;17278:12;17268:2;;17333:10;17328:3;17324:20;17321:1;17314:31;17368:4;17365:1;17358:15;17396:4;17393:1;17386:15;17268:2;17420:18;;17258:186::o;17449:558::-;17496:3;17540:5;17534:12;17567:4;17562:3;17555:17;17593:58;17645:4;17640:3;17636:14;17622:12;17593:58;:::i;:::-;17581:70;;17699:4;17692:5;17688:16;17682:23;17747:3;17741:4;17737:14;17730:4;17725:3;17721:14;17714:38;17775:49;17819:4;17803:14;17775:49;:::i;:::-;17877:4;17866:16;;;17860:23;-1:-1:-1;;;;;17856:49:1;17840:14;;;17833:73;17959:4;17948:16;;;17942:23;17967:10;17938:40;17922:14;;;;17915:64;;;;-1:-1:-1;17761:63:1;;17504:503;-1:-1:-1;;17504:503:1:o;18012:104::-;-1:-1:-1;;;;;18078:31:1;18066:44;;18056:60::o;18618:931::-;19100:3;19138:6;19132:13;19154:53;19200:6;19195:3;19188:4;19180:6;19176:17;19154:53;:::i;:::-;19238:6;19233:3;19229:16;19216:29;;-1:-1:-1;;;19290:2:1;19283:5;19276:17;19324:6;19318:13;19340:65;19396:8;19392:1;19385:5;19381:13;19374:4;19366:6;19362:17;19340:65;:::i;:::-;19468:1;19424:20;;19460:10;;;19453:22;-1:-1:-1;;;19499:1:1;19491:10;;19484:32;19540:2;19532:11;;19108:441;-1:-1:-1;;;;19108:441:1:o;19764:786::-;-1:-1:-1;;;20170:3:1;20163:38;20145:3;20230:6;20224:13;20246:62;20301:6;20296:2;20291:3;20287:12;20280:4;20272:6;20268:17;20246:62;:::i;:::-;-1:-1:-1;;;20367:2:1;20327:16;;;20359:11;;;20352:40;20417:13;;20439:63;20417:13;20488:2;20480:11;;20473:4;20461:17;;20439:63;:::i;:::-;20522:17;20541:2;20518:26;;20153:397;-1:-1:-1;;;;20153:397:1:o;21619:488::-;-1:-1:-1;;;;;21888:15:1;;;21870:34;;21940:15;;21935:2;21920:18;;21913:43;21987:2;21972:18;;21965:34;;;22035:3;22030:2;22015:18;;22008:31;;;21813:4;;22056:45;;22081:19;;22073:6;22056:45;:::i;:::-;22048:53;21822:285;-1:-1:-1;;;;;;21822:285:1:o;22391:261::-;22570:2;22559:9;22552:21;22533:4;22590:56;22642:2;22631:9;22627:18;22619:6;22590:56;:::i;22657:656::-;22975:3;22964:9;22957:22;22938:4;23002:57;23054:3;23043:9;23039:19;23031:6;23002:57;:::i;:::-;23107:9;23099:6;23095:22;23090:2;23079:9;23075:18;23068:50;23135:43;23171:6;23163;23135:43;:::i;:::-;23226:10;23214:23;;;;23209:2;23194:18;;23187:51;-1:-1:-1;;;;;;;23274:32:1;;;;23269:2;23254:18;;;23247:60;23127:51;22947:366;-1:-1:-1;;22947:366:1:o;23318:258::-;23495:2;23484:9;23477:21;23458:4;23515:55;23566:2;23555:9;23551:18;23543:6;23515:55;:::i;23955:219::-;24104:2;24093:9;24086:21;24067:4;24124:44;24164:2;24153:9;24149:18;24141:6;24124:44;:::i;24540:332::-;24742:2;24724:21;;;24781:1;24761:18;;;24754:29;-1:-1:-1;;;24814:2:1;24799:18;;24792:39;24863:2;24848:18;;24714:158::o;24877:414::-;25079:2;25061:21;;;25118:2;25098:18;;;25091:30;25157:34;25152:2;25137:18;;25130:62;-1:-1:-1;;;25223:2:1;25208:18;;25201:48;25281:3;25266:19;;25051:240::o;26355:335::-;26557:2;26539:21;;;26596:2;26576:18;;;26569:30;-1:-1:-1;;;26630:2:1;26615:18;;26608:41;26681:2;26666:18;;26529:161::o;27790:337::-;27992:2;27974:21;;;28031:2;28011:18;;;28004:30;-1:-1:-1;;;28065:2:1;28050:18;;28043:43;28118:2;28103:18;;27964:163::o;30817:410::-;31019:2;31001:21;;;31058:2;31038:18;;;31031:30;31097:34;31092:2;31077:18;;31070:62;-1:-1:-1;;;31163:2:1;31148:18;;31141:44;31217:3;31202:19;;30991:236::o;32264:343::-;32466:2;32448:21;;;32505:2;32485:18;;;32478:30;-1:-1:-1;;;32539:2:1;32524:18;;32517:49;32598:2;32583:18;;32438:169::o;34444:329::-;34646:2;34628:21;;;34685:1;34665:18;;;34658:29;-1:-1:-1;;;34718:2:1;34703:18;;34696:36;34764:2;34749:18;;34618:155::o;35851:413::-;36053:2;36035:21;;;36092:2;36072:18;;;36065:30;36131:34;36126:2;36111:18;;36104:62;-1:-1:-1;;;36197:2:1;36182:18;;36175:47;36254:3;36239:19;;36025:239::o;36269:344::-;36471:2;36453:21;;;36510:2;36490:18;;;36483:30;-1:-1:-1;;;36544:2:1;36529:18;;36522:50;36604:2;36589:18;;36443:170::o;36618:334::-;36820:2;36802:21;;;36859:2;36839:18;;;36832:30;-1:-1:-1;;;36893:2:1;36878:18;;36871:40;36943:2;36928:18;;36792:160::o;37633:355::-;37835:2;37817:21;;;37874:2;37854:18;;;37847:30;37913:33;37908:2;37893:18;;37886:61;37979:2;37964:18;;37807:181::o;37993:328::-;38195:2;38177:21;;;38234:1;38214:18;;;38207:29;-1:-1:-1;;;38267:2:1;38252:18;;38245:35;38312:2;38297:18;;38167:154::o;39904:1633::-;40162:25;;;-1:-1:-1;;;;;40244:32:1;;40206:2;40224:18;;;40217:60;;;;-1:-1:-1;;;;;40313:31:1;;40333:2;40293:18;;40286:59;40264:3;40376:2;40361:18;;40354:31;;;40143:4;;40206:2;40408:45;;40433:19;;40425:6;40408:45;:::i;:::-;40490:22;;;40484:3;40469:19;;40462:51;40563:13;;40533:4;;40622:1;40642:18;;;;40695;;;;40722:2;;40776:4;40768:6;40764:17;40754:27;;40722:2;40829;40821:6;40818:14;40798:18;40795:38;40792:2;;;-1:-1:-1;;;40856:34:1;;40913:4;40910:1;40903:15;40944:4;40863;40931:18;40792:2;45155:19;;;45207:4;45198:14;;40968:73;-1:-1:-1;41057:18:1;41084:100;;;;41198:1;41193:318;;;;41050:461;;41084:100;-1:-1:-1;;41117:24:1;;41105:37;;41162:12;;;;-1:-1:-1;41084:100:1;;41193:318;44972:4;44991:17;;;45041:4;45025:21;;41288:4;41305:165;41319:6;41316:1;41313:13;41305:165;;;41397:14;;41384:11;;;41377:35;41440:16;;;;41334:10;;41305:165;;;41490:11;;;-1:-1:-1;;41050:461:1;-1:-1:-1;41528:3:1;;40152:1385;-1:-1:-1;;;;;;;;;;;;;40152:1385:1:o;41542:290::-;41719:6;41708:9;41701:25;41762:2;41757;41746:9;41742:18;41735:30;41682:4;41782:44;41822:2;41811:9;41807:18;41799:6;41782:44;:::i;42034:1416::-;42603:10;42591:23;;;42573:42;;18186:22;;42665:2;42650:18;;18174:35;-1:-1:-1;;;;;18285:30:1;;42719:2;42704:18;;18273:43;-1:-1:-1;;;;;18285:30:1;;42773:2;42758:18;;18273:43;-1:-1:-1;;;;;18285:30:1;;42827:3;42812:19;;18273:43;42841:47;42883:3;42872:9;42868:19;42860:6;42841:47;:::i;:::-;42897;42939:3;42928:9;42924:19;42916:6;42897:47;:::i;:::-;16919:13;;16912:21;42992:3;42977:19;;16900:34;43006:47;43048:3;43037:9;43033:19;43025:6;43006:47;:::i;:::-;43062;43104:3;43093:9;43089:19;43081:6;43062:47;:::i;:::-;43146:3;43140;43129:9;43125:19;43118:32;42554:4;43173:46;43214:3;43203:9;43199:19;43190:7;43173:46;:::i;:::-;43256:7;43250:3;43239:9;43235:19;43228:36;43273:55;43323:3;43312:9;43308:19;43299:7;43273:55;:::i;:::-;43377:9;43369:6;43365:22;43359:3;43348:9;43344:19;43337:51;43405:39;43437:6;43428:7;43405:39;:::i;:::-;43397:47;;;42563:887;;;;;;;;;;;;;;;;;:::o;43660:534::-;43738:4;43744:6;43804:11;43791:25;43898:2;43894:7;43883:8;43867:14;43863:29;43859:43;43839:18;43835:68;43825:2;;43920:4;43914;43907:18;43825:2;43950:33;;44002:20;;;-1:-1:-1;;;;;;44034:30:1;;44031:2;;;44080:4;44074;44067:18;44031:2;44116:4;44104:17;;-1:-1:-1;44147:14:1;44143:27;;;44133:38;;44130:2;;;44184:1;44181;44174:12;44199:253;44271:2;44265:9;44313:4;44301:17;;-1:-1:-1;;;;;44333:34:1;;44369:22;;;44330:62;44327:2;;;44395:18;;:::i;:::-;44431:2;44424:22;44245:207;:::o;44457:275::-;44528:2;44522:9;44593:2;44574:13;;-1:-1:-1;;44570:27:1;44558:40;;-1:-1:-1;;;;;44613:34:1;;44649:22;;;44610:62;44607:2;;;44675:18;;:::i;:::-;44711:2;44704:22;44502:230;;-1:-1:-1;44502:230:1:o;44737:183::-;44797:4;-1:-1:-1;;;;;44819:30:1;;44816:2;;;44852:18;;:::i;:::-;-1:-1:-1;44897:1:1;44893:14;44909:4;44889:25;;44806:114::o;45223:238::-;45263:3;-1:-1:-1;;;;;45330:10:1;;;45360;;;45390:12;;;45382:21;;45379:2;;;45406:18;;:::i;:::-;45442:13;;45271:190;-1:-1:-1;;;;45271:190:1:o;45466:128::-;45506:3;45537:1;45533:6;45530:1;45527:13;45524:2;;;45543:18;;:::i;:::-;-1:-1:-1;45579:9:1;;45514:80::o;45599:228::-;45638:3;45666:10;45703:2;45700:1;45696:10;45733:2;45730:1;45726:10;45764:3;45760:2;45756:12;45751:3;45748:21;45745:2;;;45772:18;;:::i;45832:236::-;45871:3;-1:-1:-1;;;;;45937:10:1;;;45967;;;45997:12;;;45989:21;;45986:2;;;46013:18;;:::i;46073:120::-;46113:1;46139;46129:2;;46144:18;;:::i;:::-;-1:-1:-1;46178:9:1;;46119:74::o;46198:272::-;46238:7;-1:-1:-1;;;;;46309:10:1;;;46339;;;46372:11;;46365:19;46394:12;;;46386:21;;46361:47;46358:2;;;46411:18;;:::i;:::-;46451:13;;46250:220;-1:-1:-1;;;;46250:220:1:o;46475:168::-;46515:7;46581:1;46577;46573:6;46569:14;46566:1;46563:21;46558:1;46551:9;46544:17;46540:45;46537:2;;;46588:18;;:::i;:::-;-1:-1:-1;46628:9:1;;46527:116::o;46648:125::-;46688:4;46716:1;46713;46710:8;46707:2;;;46721:18;;:::i;:::-;-1:-1:-1;46758:9:1;;46697:76::o;46778:221::-;46817:4;46846:10;46906;;;;46876;;46928:12;;;46925:2;;;46943:18;;:::i;:::-;46980:13;;46826:173;-1:-1:-1;;;46826:173:1:o;47004:199::-;47110:9;47147:50;47182:14;47175:5;47147:50;:::i;47208:258::-;47280:1;47290:113;47304:6;47301:1;47298:13;47290:113;;;47380:11;;;47374:18;47361:11;;;47354:39;47326:2;47319:10;47290:113;;;47421:6;47418:1;47415:13;47412:2;;;-1:-1:-1;;47456:1:1;47438:16;;47431:27;47261:205::o;47471:136::-;47510:3;47538:5;47528:2;;47547:18;;:::i;:::-;-1:-1:-1;;;47583:18:1;;47518:89::o;47612:193::-;47650:3;-1:-1:-1;;;;;47683:30:1;;;47722:2;;47743:18;;:::i;:::-;-1:-1:-1;;47779:20:1;;47658:147;-1:-1:-1;;47658:147:1:o;47810:380::-;47889:1;47885:12;;;;47932;;;47953:2;;48007:4;47999:6;47995:17;47985:27;;47953:2;48060;48052:6;48049:14;48029:18;48026:38;48023:2;;;48106:10;48101:3;48097:20;48094:1;48087:31;48141:4;48138:1;48131:15;48169:4;48166:1;48159:15;48023:2;;47865:325;;;:::o;48195:197::-;48233:3;48261:6;48302:2;48295:5;48291:14;48329:2;48320:7;48317:15;48314:2;;;48335:18;;:::i;:::-;48384:1;48371:15;;48241:151;-1:-1:-1;;;48241:151:1:o;48397:135::-;48436:3;-1:-1:-1;;48457:17:1;;48454:2;;;48477:18;;:::i;:::-;-1:-1:-1;48524:1:1;48513:13;;48444:88::o;48537:112::-;48569:1;48595;48585:2;;48600:18;;:::i;:::-;-1:-1:-1;48634:9:1;;48575:74::o;48654:127::-;48715:10;48710:3;48706:20;48703:1;48696:31;48746:4;48743:1;48736:15;48770:4;48767:1;48760:15;48786:127;48847:10;48842:3;48838:20;48835:1;48828:31;48878:4;48875:1;48868:15;48902:4;48899:1;48892:15;48918:127;48979:10;48974:3;48970:20;48967:1;48960:31;49010:4;49007:1;49000:15;49034:4;49031:1;49024:15;49050:131;-1:-1:-1;;;;;49125:31:1;;49115:42;;49105:2;;49171:1;49168;49161:12;49186:118;49272:5;49265:13;49258:21;49251:5;49248:32;49238:2;;49294:1;49291;49284:12;49309:131;-1:-1:-1;;;;;;49383:32:1;;49373:43;;49363:2;;49430:1;49427;49420:12
Swarm Source
ipfs://c1dc08b2a8d4ca269fdc070089575e43de6f4c2b0b0f431aa0758c58bdca4707
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
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.