Token ETH Atlantic Straddle 2
Overview ERC-721
Total Supply:
357 ETH-ATLANTIC-STRADDLE-2
Holders:
273 addresses
Contract:
Balance
1 ETH-ATLANTIC-STRADDLE-2
[ Download CSV Export ]
[ Download CSV Export ]
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
AtlanticStraddle
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity)
/** *Submitted for verification at Arbiscan.io on 2022-08-22 */ // File @openzeppelin/contracts/utils/[email protected] /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } } /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @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`. * * 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; /** * @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 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 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 the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @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); } /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @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 `IERC721Receiver.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 IERC721Metadata is IERC721 { /** * @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 Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 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 Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall( target, data, "Address: low-level delegate call failed" ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(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 /// @solidity memory-safe-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 Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @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 Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } /** * @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 ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } /** * @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 ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings 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. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require( owner != address(0), "ERC721: address zero is not a valid owner" ); 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: invalid token ID"); 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) { _requireMinted(tokenId); 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 overridden 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 = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_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: caller is not token 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: caller is not token 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) { address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == 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); _afterTokenTransfer(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 = ERC721.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); _afterTokenTransfer(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( ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner" ); 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); _afterTokenTransfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @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 IERC721Receiver(to).onERC721Received( _msgSender(), from, tokenId, data ) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert( "ERC721: transfer to non ERC721Receiver implementer" ); } else { /// @solidity memory-safe-assembly 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 {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} } /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); } /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require( index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds" ); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require( index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds" ); return _allTokens[index]; } /** * @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` cannot be the zero address. * - `to` cannot be the zero address. * * 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 override { super._beforeTokenTransfer(from, to, tokenId); if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } } /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`. // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`. // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a // good first aproximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1; uint256 x = a; if (x >> 128 > 0) { x >>= 128; result <<= 64; } if (x >> 64 > 0) { x >>= 64; result <<= 32; } if (x >> 32 > 0) { x >>= 32; result <<= 16; } if (x >> 16 > 0) { x >>= 16; result <<= 8; } if (x >> 8 > 0) { x >>= 8; result <<= 4; } if (x >> 4 > 0) { x >>= 4; result <<= 2; } if (x >> 2 > 0) { result <<= 1; } // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { uint256 result = sqrt(a); if (rounding == Rounding.Up && result * result < a) { result += 1; } return result; } } /** * @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); } /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transfer.selector, to, value) ); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value) ); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn( token, abi.encodeWithSelector(token.approve.selector, spender, value) ); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require( oldAllowance >= value, "SafeERC20: decreased allowance below zero" ); uint256 newAllowance = oldAllowance - value; _callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require( nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed" ); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall( data, "SafeERC20: low-level call failed" ); if (returndata.length > 0) { // Return data is optional require( abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed" ); } } } /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @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 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 AccessControl is Context, IAccessControl, ERC165 { 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); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @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 virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(uint160(account), 20), " is missing role ", Strings.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 virtual 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. * * May emit a {RoleGranted} event. */ 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. * * May emit a {RoleRevoked} event. */ 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 revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ 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. * * May emit a {RoleGranted} event. * * [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}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ 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); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } } /** * @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 Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } } /// @title ContractWhitelist /// @author witherblock /// @notice A helper contract that lets you add a list of whitelisted contracts that should be able to interact with restricited functions abstract contract ContractWhitelist { /// @dev contract => whitelisted or not mapping(address => bool) public whitelistedContracts; /*==== SETTERS ====*/ /// @dev add to the contract whitelist /// @param _contract the address of the contract to add to the contract whitelist function _addToContractWhitelist(address _contract) internal { require(isContract(_contract), "Address must be a contract"); require( !whitelistedContracts[_contract], "Contract already whitelisted" ); whitelistedContracts[_contract] = true; emit AddToContractWhitelist(_contract); } /// @dev remove from the contract whitelist /// @param _contract the address of the contract to remove from the contract whitelist function _removeFromContractWhitelist(address _contract) internal { require(whitelistedContracts[_contract], "Contract not whitelisted"); whitelistedContracts[_contract] = false; emit RemoveFromContractWhitelist(_contract); } // modifier is eligible sender modifier function _isEligibleSender() internal view { // the below condition checks whether the caller is a contract or not if (msg.sender != tx.origin) require( whitelistedContracts[msg.sender], "Contract must be whitelisted" ); } /*==== VIEWS ====*/ /// @dev checks for contract or eoa addresses /// @param addr the address to check /// @return bool whether the passed address is a contract address function isContract(address addr) public view returns (bool) { uint256 size; assembly { size := extcodesize(addr) } return size > 0; } /*==== EVENTS ====*/ event AddToContractWhitelist(address indexed _contract); event RemoveFromContractWhitelist(address indexed _contract); } interface IAssetSwapper { function swapAsset( address from, address to, uint256 amount, uint256 minAmountOut, uint256 swapperId ) external returns (uint256); } interface IOptionPricing { function getOptionPrice( bool isPut, uint256 expiry, uint256 strike, uint256 lastPrice, uint256 baseIv ) external view returns (uint256); } interface IPriceOracle { function getCollateralPrice() external view returns (uint256); function getUnderlyingPrice() external view returns (uint256); } interface IVolatilityOracle { function getVolatility(uint256) external view returns (uint256); } interface IPositionMinter is IERC721Enumerable { function mint(address to) external returns (uint256 tokenId); function burnToken(uint256 tokenId) external; } // File contracts/AtlanticStraddle.sol //SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.7; // Libraries // Contracts // Interfaces // Atlantic straddles // ============== // - Accept stable deposits // - Deposits can only happen for next epoch // - Stables are always sold as ATM puts // - Tokenize deposit as NFT // - 3 day epochs, deposits auto-rollover unless deactivated // - Withdrawal considers performance of pool since deposit // - On purchase of Atlantic straddle, use 50% of AP collateral to purchase underlying asset // - At expiry, settle by selling purchased underlying asset to return AP and AC collateral contract AtlanticStraddle is ReentrancyGuard, ERC721, ERC721Enumerable, AccessControl, Pausable, ContractWhitelist { using SafeERC20 for IERC20; using Counters for Counters.Counter; /// @dev Token ID counter for write positions Counters.Counter private _tokenIdCounter; // Current epoch. 0-indexed uint256 public currentEpoch; // Managar Role bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE"); // Contract addresses Addresses public addresses; // Total deposits for epoch mapping(uint256 => EpochData) public epochData; // Data for premium and funding collections for an epoch mapping(uint256 => EpochCollectionsData) public epochCollectionsData; // Is vault ready for the epoch i.e can purchases begin mapping(uint256 => bool) public isVaultReady; // Toggled to true after an epoch has been marked pre-expired mapping(uint256 => bool) public isEpochPreExpired; // Toggled to true after an epoch has been marked expired mapping(uint256 => bool) public isEpochExpired; // Write positions mapping(uint256 => WritePosition) public writePositions; // Straddle positions mapping(uint256 => StraddlePosition) public straddlePositions; // Percentage precision uint256 public constant PERCENT_PRECISION = 1e6; // usdc decimals uint256 public constant USDC_DECIMALS = 1e6; // Min purchase 0.01 to prevent spam uint256 public constant MIN_PURCHASE_AMOUNT = 1e16; // seconds a year uint256 internal constant SECONDS_A_YEAR = 365 days; // Purchase fee percent uint256 public purchaseFeePercent = 1e5; // Delegation fee uint256 public MAX_DELEGATION_FEE = 10 * USDC_DECIMALS; // Settlement fee percent uint256 public settlementFeePercent = 1e5; // AP funding percent uint256 public apFundingPercent = 16 * PERCENT_PRECISION; // Fee percent charged to owner, default to 0.1% uint256 public settleDelegationFeePercent = PERCENT_PRECISION / 10; // Purchase time limit variable to prevent last min buyouts uint256 public blackoutPeriodBeforeExpiry = 6 hours; // PnL slippage percent uint256 public pnlSlippagePercent = 2 * PERCENT_PRECISION; uint256 internal constant AMOUNT_PRICE_TO_USDC_DECIMALS = (1e18 * 1e8) / 1e6; struct Addresses { // Stablecoin token (1e6 precision) address usd; // Underlying token address underlying; // Asset Swapper address assetSwapper; // Price Oracle address priceOracle; // Volatility Oracle address volatilityOracle; // Option Pricing address optionPricing; // Fee Distributor address feeDistributor; } struct EpochData { // Start time uint256 startTime; // Expiry time uint256 expiry; // Total USD deposits uint256 usdDeposits; // Active USD deposits (used for writing) uint256 activeUsdDeposits; // Settlement Price uint256 settlementPrice; // Percentage of total settlement executed uint256 settlementPercentage; // Amount of underlying assets purchased uint256 underlyingPurchased; } struct EpochCollectionsData { // Total premiums collected for USD deposits uint256 usdPremiums; // Total funding collected for USD deposits uint256 usdFunding; // Total amount of straddles sold uint256 totalSold; // Number of "live" straddles per epoch uint256 straddleCounter; // Final usd balance before withdraw uint256 finalUsdBalanceBeforeWithdaw; } struct WritePosition { // Epoch # uint256 epoch; // USD deposits uint256 usdDeposit; // Whether deposit should be rolled over to the next epoch bool rollover; } struct StraddlePosition { // Epoch # uint256 epoch; // Amount uint256 amount; // AP Strike uint256 apStrike; // Underlying purchased for this straddle uint256 underlyingPurchased; } event Bootstrap(uint256 epoch); event Deposit( uint256 epoch, uint256 amount, bool rollover, address user, address sender, uint256 tokenId ); event Purchase(address user, uint256 straddleId, uint256 cost); event Settle( address indexed sender, address indexed owner, uint256 id, uint256 pnl ); event Withdraw(address indexed sender, uint256 id, uint256 pnl); event ToggleRollover(uint256 id, bool rollover); event EpochExpired(address caller); event EpochPreExpired(address caller); event SetAddresses(Addresses addresses); event SetBlackoutPeriod(uint256 period); event SetApFunding(uint256 apFunding); event SetPnlSlippagePercent(uint256 pnlSlippagePercent); event SetFeePercents( uint256 purchaseFeePercent, uint256 settlementFeePercent, uint256 settleDelegationFeePercent ); /*==== CONSTRUCTOR ====*/ constructor( string memory _name, string memory _symbol, Addresses memory _addresses ) ERC721(_name, _symbol) { addresses = _addresses; IERC20(addresses.usd).safeIncreaseAllowance( addresses.assetSwapper, type(uint256).max ); IERC20(addresses.underlying).safeIncreaseAllowance( addresses.assetSwapper, type(uint256).max ); _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); _setupRole(MANAGER_ROLE, msg.sender); } /*==== USER METHODS ====*/ /// @dev Deposit for next epoch /// @param amount Amount to deposit /// @param shouldRollover Should the deposit be rolled over /// @param user User address /// @return tokenId Write position token ID function deposit( uint256 amount, bool shouldRollover, address user ) external whenNotPaused nonReentrant returns (uint256 tokenId) { _isEligibleSender(); require(amount > 0, "Cannot deposit 0 amount"); uint256 nextEpoch = currentEpoch + 1; epochData[nextEpoch].usdDeposits += amount; epochCollectionsData[nextEpoch].finalUsdBalanceBeforeWithdaw += amount; tokenId = _mintPositionToken(user); writePositions[tokenId] = WritePosition({ epoch: nextEpoch, usdDeposit: amount, rollover: shouldRollover }); IERC20(addresses.usd).safeTransferFrom( msg.sender, address(this), amount ); emit Deposit( nextEpoch, amount, shouldRollover, user, msg.sender, tokenId ); } /// @dev Rolls over a deposit to the next epoch. Anyone can call this for write positions with `rollover` enabled /// Call this prior to bootstrapping to a new epoch or it will roll over to epoch n + 2 /// @param id Write position token ID /// @return tokenId Rolled over write position token ID function rollover(uint256 id) public whenNotPaused nonReentrant returns (uint256 tokenId) { _isEligibleSender(); WritePosition memory writePos = writePositions[id]; require(writePos.rollover, "Rollover not authorized"); require(writePos.epoch != 0, "Invalid write position"); require(isEpochExpired[writePos.epoch], "Epoch has not expired"); uint256 depositPlusPnl = calculateWritePositionPnl(id); address user = ownerOf(id); _burn(id); require(depositPlusPnl != 0, "Write position pnl is 0"); emit Withdraw(user, id, depositPlusPnl); uint256 nextEpoch = currentEpoch + 1; epochData[nextEpoch].usdDeposits += depositPlusPnl; epochCollectionsData[nextEpoch] .finalUsdBalanceBeforeWithdaw += depositPlusPnl; tokenId = _mintPositionToken(user); writePositions[tokenId] = WritePosition({ epoch: nextEpoch, usdDeposit: depositPlusPnl, rollover: true }); emit Deposit(nextEpoch, depositPlusPnl, true, user, user, tokenId); } /// @dev Rollover for multiple ids /// @param ids Write position token IDs /// @return tokenIds Rolled over write position token IDs function multirollover(uint256[] memory ids) external returns (uint256[] memory tokenIds) { tokenIds = new uint256[](ids.length); for (uint256 i = 0; i < ids.length; i++) { tokenIds[i] = rollover(ids[i]); } } /// @dev Toggle rollover for a write position /// @param id Write position token ID function toggleRollover(uint256 id) external whenNotPaused nonReentrant { _isEligibleSender(); require(ownerOf(id) == msg.sender, "Invalid owner"); require(writePositions[id].epoch != 0, "Invalid position"); writePositions[id].rollover = !writePositions[id].rollover; emit ToggleRollover(id, writePositions[id].rollover); } /// @dev Withdraw write positions after strikes are settled /// @param id ID of write position /// @return writePositionPnl of write position function withdraw(uint256 id) external whenNotPaused nonReentrant returns (uint256 writePositionPnl) { _isEligibleSender(); require(ownerOf(id) == msg.sender, "Invalid owner"); WritePosition memory writePos = writePositions[id]; require(writePos.epoch != 0, "Invalid write position"); require(isEpochExpired[writePos.epoch], "Settlements not done"); writePositionPnl = calculateWritePositionPnl(id); _burn(id); require(writePositionPnl != 0, "Write position pnl is 0"); IERC20(addresses.usd).safeTransfer(msg.sender, writePositionPnl); emit Withdraw(msg.sender, id, writePositionPnl); } /// @dev Purchase a straddle /// @param amount Approx. amount of straddles to purchase (10 ** 18) /// @param swapperId Swapper ID of the swap method to use /// @param user Address to purchase straddles for /// @return tokenId Straddle position token ID function purchase( uint256 amount, uint256 swapperId, address user ) external whenNotPaused nonReentrant returns (uint256 tokenId) { _isEligibleSender(); require(currentEpoch > 0, "Invalid epoch"); require(amount > MIN_PURCHASE_AMOUNT, "Invalid amount"); require( block.timestamp < epochData[currentEpoch].expiry - blackoutPeriodBeforeExpiry, "Cannot purchase during blackout period" ); uint256 currentPrice = getUnderlyingPrice(); uint256 timeToExpiry = epochData[currentEpoch].expiry - block.timestamp; require( epochData[currentEpoch].usdDeposits - (epochData[currentEpoch].activeUsdDeposits / AMOUNT_PRICE_TO_USDC_DECIMALS) >= (currentPrice * amount) / AMOUNT_PRICE_TO_USDC_DECIMALS, "Not enough AP liquidity available" ); // Swap half of AP to underlying uint256 underlyingPurchased = _swapToUnderlying( ((currentPrice * amount) / 2) / AMOUNT_PRICE_TO_USDC_DECIMALS, swapperId ); epochCollectionsData[currentEpoch].finalUsdBalanceBeforeWithdaw -= ((currentPrice * amount) / 2) / AMOUNT_PRICE_TO_USDC_DECIMALS; uint256 swapPrice = (currentPrice * amount) / (underlyingPurchased * 2); epochData[currentEpoch].underlyingPurchased += underlyingPurchased; // Deposits epochData[currentEpoch].activeUsdDeposits += swapPrice * (underlyingPurchased * 2); uint256 apPremium = calculatePremium( true, swapPrice, underlyingPurchased * 2, epochData[currentEpoch].expiry ); uint256 apFunding = calculateApFunding( swapPrice, underlyingPurchased * 2, timeToExpiry ); // Collections epochCollectionsData[currentEpoch].usdPremiums += apPremium; epochCollectionsData[currentEpoch].usdFunding += apFunding; epochCollectionsData[currentEpoch].totalSold += underlyingPurchased * 2; epochCollectionsData[currentEpoch].straddleCounter += 1; // Mint straddle position token tokenId = _mintPositionToken(user); straddlePositions[tokenId] = StraddlePosition({ epoch: currentEpoch, amount: underlyingPurchased * 2, apStrike: swapPrice, underlyingPurchased: underlyingPurchased }); uint256 protocolFee = (apPremium * purchaseFeePercent) / (PERCENT_PRECISION * AMOUNT_PRICE_TO_USDC_DECIMALS * 100); IERC20(addresses.usd).safeTransferFrom( msg.sender, address(this), (apPremium + apFunding) / AMOUNT_PRICE_TO_USDC_DECIMALS + protocolFee ); IERC20(addresses.usd).safeTransfer( addresses.feeDistributor, protocolFee ); epochCollectionsData[currentEpoch] .finalUsdBalanceBeforeWithdaw += ((apPremium + apFunding) / AMOUNT_PRICE_TO_USDC_DECIMALS); emit Purchase(user, tokenId, apPremium + apFunding); } /// @dev Settles a purchased option /// @param id ID of straddle position /// @return pnl of straddle function settle(uint256 id) public whenNotPaused nonReentrant returns (uint256) { _isEligibleSender(); StraddlePosition memory sp = straddlePositions[id]; require(sp.epoch != 0, "Invalid straddle position"); require(isEpochPreExpired[sp.epoch], "Epoch has not pre-expired"); uint256 buyerPnl = calculateStraddlePositionPnl(id); address owner = ownerOf(id); _burn(id); require(buyerPnl != 0, "buyerPnl cannot be 0"); uint256 protocolFee = (buyerPnl * settlementFeePercent) / (PERCENT_PRECISION * 100); uint256 delegationFee; // If owner did not settle, collect settlement fees if (owner != msg.sender) { delegationFee = (buyerPnl * settleDelegationFeePercent) / (PERCENT_PRECISION * 100); delegationFee = Math.min(delegationFee, MAX_DELEGATION_FEE); } buyerPnl -= (protocolFee + delegationFee); epochCollectionsData[sp.epoch].straddleCounter -= 1; epochCollectionsData[sp.epoch] .finalUsdBalanceBeforeWithdaw -= (buyerPnl + protocolFee + delegationFee); IERC20(addresses.usd).safeTransfer( addresses.feeDistributor, protocolFee ); IERC20(addresses.usd).safeTransfer(owner, buyerPnl); IERC20(addresses.usd).safeTransfer(msg.sender, delegationFee); emit Settle(msg.sender, owner, id, buyerPnl); return buyerPnl; } /// @dev Settle for multiple ids /// @param ids Straddle position token IDs /// @return pnls pnls function multisettle(uint256[] memory ids) external returns (uint256[] memory pnls) { pnls = new uint256[](ids.length); for (uint256 i = 0; i < ids.length; i++) { pnls[i] = settle(ids[i]); } } /*==== INTERNAL METHODS ====*/ /// @dev Internal function to mint a write position token /// @param to the address to mint the position to function _mintPositionToken(address to) private returns (uint256 tokenId) { tokenId = _tokenIdCounter.current(); _tokenIdCounter.increment(); _safeMint(to, tokenId); } /// @dev Internal function to swap USD to underlying tokens /// @param amount Amount of USD to swap /// @param swapperId Swapper ID function _swapToUnderlying(uint256 amount, uint256 swapperId) internal returns (uint256 underlyingPurchased) { underlyingPurchased = IAssetSwapper(addresses.assetSwapper).swapAsset( addresses.usd, addresses.underlying, amount, 0, swapperId ); } /// @dev Internal function to swap underlying tokens to USD /// @param amount Amount of underlying tokens to swap /// @param swapperId Swapper ID function _swapFromUnderlying(uint256 amount, uint256 swapperId) internal returns (uint256 usdObtained) { usdObtained = IAssetSwapper(addresses.assetSwapper).swapAsset( addresses.underlying, addresses.usd, amount, 0, swapperId ); } /*==== VIEWS ====*/ /// @notice Returns the price of the underlying in USD in 1e8 precision function getUnderlyingPrice() public view returns (uint256) { return IPriceOracle(addresses.priceOracle).getUnderlyingPrice(); } /// @notice Returns the volatility from the volatility oracle /// @param _strike Strike of the option function getVolatility(uint256 _strike) public view returns (uint256) { return IVolatilityOracle(addresses.volatilityOracle).getVolatility( _strike ); } /// @notice Calculate premium for an option /// @param _isPut Is put option /// @param _strike Strike price of the option /// @param _amount Amount of options (1e18 precision) /// @param _expiry Expiry of the option /// @return premium in USD function calculatePremium( bool _isPut, uint256 _strike, uint256 _amount, uint256 _expiry ) public view returns (uint256 premium) { premium = (IOptionPricing(addresses.optionPricing).getOptionPrice( _isPut, _expiry, _strike, getUnderlyingPrice(), getVolatility(_strike) ) * _amount); } /// @notice Calculate premium for an option /// @param _price Price of the asset /// @param _amount Amount of options (1e18 precision) /// @param _timeToExpiry Time to expiry function calculateApFunding( uint256 _price, uint256 _amount, uint256 _timeToExpiry ) public view returns (uint256 funding) { funding = (((_price * apFundingPercent * _timeToExpiry * _amount) / (SECONDS_A_YEAR * PERCENT_PRECISION)) / 100) / 2; } /// @notice Calculates the writer position pnl /// @param id the id of the write position /// @return writePositionPnl function calculateWritePositionPnl(uint256 id) public view returns (uint256 writePositionPnl) { WritePosition memory writePos = writePositions[id]; require(writePos.epoch != 0, "Invalid write position"); writePositionPnl = (writePos.usdDeposit * epochCollectionsData[writePos.epoch] .finalUsdBalanceBeforeWithdaw) / epochData[writePos.epoch].usdDeposits; } /// @param id ID of straddle position /// @return buyerPnl positive pnl of buyer function calculateStraddlePositionPnl(uint256 id) public view returns (uint256 buyerPnl) { StraddlePosition memory sp = straddlePositions[id]; require(sp.epoch != 0, "Invalid straddle position"); uint256 settlementPrice = epochData[sp.epoch].settlementPrice; uint256 strikePrice = sp.apStrike; // straddle pnl = max(K - S, 0) + 0.5 * (S - K) // if K > S, get (K - S) - 0.5 * (K - S) if (strikePrice > settlementPrice) { buyerPnl = (strikePrice - settlementPrice) * sp.amount; buyerPnl -= (strikePrice - settlementPrice) * sp.underlyingPurchased; } else { // else get 0 + 0.5 * (S - K) buyerPnl += (settlementPrice - strikePrice) * sp.underlyingPurchased; } buyerPnl /= AMOUNT_PRICE_TO_USDC_DECIMALS; buyerPnl -= (buyerPnl * pnlSlippagePercent) / (100 * PERCENT_PRECISION); } /// @notice Returns the tokenIds owned by a wallet (writePositions) /// @param owner wallet owner function writePositionsOfOwner(address owner) public view returns (uint256[] memory tokenIds) { uint256 ownerTokenCount = balanceOf(owner); tokenIds = new uint256[](ownerTokenCount); for (uint256 i; i < ownerTokenCount; i++) { uint256 tokenId = tokenOfOwnerByIndex(owner, i); if (writePositions[tokenId].epoch != 0) { tokenIds[i] = tokenId; } } } /// @notice Returns the tokenIds owned by a wallet (straddlePositions) /// @param owner wallet owner function straddlePositionsOfOwner(address owner) public view returns (uint256[] memory tokenIds) { uint256 ownerTokenCount = balanceOf(owner); tokenIds = new uint256[](ownerTokenCount); for (uint256 i; i < ownerTokenCount; i++) { uint256 tokenId = tokenOfOwnerByIndex(owner, i); if (straddlePositions[tokenId].epoch != 0) { tokenIds[i] = tokenId; } } } /*==== MANAGER METHODS ====*/ /// @dev Bootstrap and start the next epoch for purchases /// @param expiry Expiry function bootstrap(uint256 expiry) external whenNotPaused onlyRole(MANAGER_ROLE) returns (bool) { uint256 nextEpoch = currentEpoch + 1; require( block.timestamp < expiry, "Expiry cannot be before current time" ); require( currentEpoch == 0 || !isVaultReady[nextEpoch], "Cannot bootstrap when vault is ready" ); if (currentEpoch > 0) { require( isEpochExpired[currentEpoch], "Cannot bootstrap before the current epoch was expired & settled" ); } // Set expiry in epoch data epochData[nextEpoch].startTime = block.timestamp; epochData[nextEpoch].expiry = expiry; // Mark vault as ready for epoch isVaultReady[nextEpoch] = true; // Increase the current epoch currentEpoch = nextEpoch; emit Bootstrap(nextEpoch); return true; } /// @dev Swap a certain percentage of total purchased underlying /// @param percentage percentage of underlying to swap in 1e6 /// @param swapperId Swapper ID of the swap method to use with AssetSwapper function preExpireEpoch(uint256 percentage, uint256 swapperId) external whenNotPaused onlyRole(MANAGER_ROLE) returns (bool) { EpochData memory data = epochData[currentEpoch]; require(percentage > 0, "Percentage cannot be 0"); require( block.timestamp >= data.expiry, "Time is not past epoch expiry" ); require( !isEpochPreExpired[currentEpoch], "Epoch was already pre-expired" ); require(!isEpochExpired[currentEpoch], "Epoch was already expired"); require( data.settlementPercentage + percentage <= (100 * PERCENT_PRECISION), "You cannot swap more than 100%" ); // Swap all purchased underlying at current price uint256 underlyingToSwap = (data.underlyingPurchased * percentage) / (100 * PERCENT_PRECISION); uint256 normalizedSettlementPrice; if (underlyingToSwap > 0) { uint256 usdObtained = _swapFromUnderlying( underlyingToSwap, swapperId ); epochCollectionsData[currentEpoch] .finalUsdBalanceBeforeWithdaw += usdObtained; uint256 settlementPrice = (usdObtained * AMOUNT_PRICE_TO_USDC_DECIMALS) / underlyingToSwap; normalizedSettlementPrice = ((data.settlementPrice * data.settlementPercentage) + (settlementPrice * percentage)) / (data.settlementPercentage + percentage); epochData[currentEpoch].settlementPercentage += percentage; } else { normalizedSettlementPrice = getUnderlyingPrice(); epochData[currentEpoch].settlementPercentage = 100 * PERCENT_PRECISION; } if (epochData[currentEpoch].settlementPrice == 0) { epochData[currentEpoch].settlementPrice = normalizedSettlementPrice; } else { epochData[currentEpoch].settlementPrice = Math.min( epochData[currentEpoch].settlementPrice, normalizedSettlementPrice ); } if ( epochData[currentEpoch].settlementPercentage > (99 * PERCENT_PRECISION) ) { isEpochPreExpired[currentEpoch] = true; } emit EpochPreExpired(msg.sender); return true; } /// @dev Expire epoch and set the settlement price function expireEpoch() external whenNotPaused onlyRole(MANAGER_ROLE) returns (bool expired) { require( block.timestamp >= epochData[currentEpoch].expiry, "Time is not past epoch expiry" ); require(isEpochPreExpired[currentEpoch], "Epoch has not pre-expired"); require(!isEpochExpired[currentEpoch], "Epoch was already expired"); if (epochCollectionsData[currentEpoch].straddleCounter == 0) { isEpochExpired[currentEpoch] = true; expired = true; } else { revert("All settlements have not been processed"); } emit EpochExpired(msg.sender); } /*==== ADMIN METHODS ====*/ /// @notice Sets the addresses used in the contract /// @dev Can only be called by admin /// @param _addresses Addresses function setAddresses(Addresses memory _addresses) external onlyRole(DEFAULT_ADMIN_ROLE) { addresses = _addresses; emit SetAddresses(_addresses); } /// @notice Change blackout period before expiry /// @dev Can only be called by governance function setBlackoutPeriodBeforeExpiry(uint256 period) external onlyRole(DEFAULT_ADMIN_ROLE) returns (bool) { require(period > 1 hours, "Blackout period must be more than 1 hour"); blackoutPeriodBeforeExpiry = period; emit SetBlackoutPeriod(period); return true; } /// @notice Sets the apFunding /// @dev Can only be called by admin /// @param _apFundingPercent funding percentage number between 1% and 100% function setApFunding(uint256 _apFundingPercent) external onlyRole(DEFAULT_ADMIN_ROLE) { require(_apFundingPercent > 0, "Funding rate must be greater than 0"); apFundingPercent = _apFundingPercent; emit SetApFunding(_apFundingPercent); } /// @notice Sets the pnlSlippagePercent /// @dev Can only be called by admin /// @param _pnlSlippagePercent The pnl slippage percent function setPnlSlippagePercent(uint256 _pnlSlippagePercent) external onlyRole(DEFAULT_ADMIN_ROLE) { require(_pnlSlippagePercent > 0, "Funding rate must be greater than 0"); pnlSlippagePercent = _pnlSlippagePercent; emit SetPnlSlippagePercent(_pnlSlippagePercent); } /// @notice Sets the purchase/settlement fee percent /// @dev Can only be called by admin /// @param _purchaseFeePercent Purchase fee percent /// @param _settlementFeePercent Settlement fee percent /// @param _settleDelegationFeePercent Settle delegation fee percent function setFeePercents( uint256 _purchaseFeePercent, uint256 _settlementFeePercent, uint256 _settleDelegationFeePercent ) external onlyRole(DEFAULT_ADMIN_ROLE) { require( _purchaseFeePercent > 0 && _settlementFeePercent > 0 && _settleDelegationFeePercent > 0, "Percents must be greater than 0" ); purchaseFeePercent = _purchaseFeePercent; settlementFeePercent = _settlementFeePercent; settleDelegationFeePercent = _settleDelegationFeePercent; emit SetFeePercents( _purchaseFeePercent, _settlementFeePercent, _settleDelegationFeePercent ); } /// @notice Pauses the vault for emergency cases /// @dev Can only be called by admin function pause() external onlyRole(DEFAULT_ADMIN_ROLE) { _pause(); } /// @notice Unpauses the vault /// @dev Can only be called by admin function unpause() external onlyRole(DEFAULT_ADMIN_ROLE) { _unpause(); } /// @notice Add a contract to the whitelist /// @dev Can only be called by the owner /// @param _contract Address of the contract that needs to be added to the whitelist function addToContractWhitelist(address _contract) external onlyRole(DEFAULT_ADMIN_ROLE) { _addToContractWhitelist(_contract); } /// @notice Remove a contract to the whitelist /// @dev Can only be called by the owner /// @param _contract Address of the contract that needs to be removed from the whitelist function removeFromContractWhitelist(address _contract) external onlyRole(DEFAULT_ADMIN_ROLE) { _removeFromContractWhitelist(_contract); } /// @notice Transfers all funds to msg.sender /// @dev Can only be called by admin /// @param tokens The list of erc20 tokens to withdraw /// @param transferNative Whether should transfer the native currency function emergencyWithdraw(address[] calldata tokens, bool transferNative) external onlyRole(DEFAULT_ADMIN_ROLE) whenPaused { if (transferNative) { payable(msg.sender).transfer(address(this).balance); } for (uint256 i = 0; i < tokens.length; i++) { IERC20 token = IERC20(tokens[i]); token.safeTransfer(msg.sender, token.balanceOf(address(this))); } } // The following functions are overrides required by Solidity. function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal override(ERC721, ERC721Enumerable) { super._beforeTokenTransfer(from, to, tokenId); } function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable, AccessControl) returns (bool) { return super.supportsInterface(interfaceId); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"components":[{"internalType":"address","name":"usd","type":"address"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"address","name":"assetSwapper","type":"address"},{"internalType":"address","name":"priceOracle","type":"address"},{"internalType":"address","name":"volatilityOracle","type":"address"},{"internalType":"address","name":"optionPricing","type":"address"},{"internalType":"address","name":"feeDistributor","type":"address"}],"internalType":"struct AtlanticStraddle.Addresses","name":"_addresses","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_contract","type":"address"}],"name":"AddToContractWhitelist","type":"event"},{"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":"epoch","type":"uint256"}],"name":"Bootstrap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"rollover","type":"bool"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"EpochExpired","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"EpochPreExpired","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"straddleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"cost","type":"uint256"}],"name":"Purchase","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_contract","type":"address"}],"name":"RemoveFromContractWhitelist","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":[{"components":[{"internalType":"address","name":"usd","type":"address"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"address","name":"assetSwapper","type":"address"},{"internalType":"address","name":"priceOracle","type":"address"},{"internalType":"address","name":"volatilityOracle","type":"address"},{"internalType":"address","name":"optionPricing","type":"address"},{"internalType":"address","name":"feeDistributor","type":"address"}],"indexed":false,"internalType":"struct AtlanticStraddle.Addresses","name":"addresses","type":"tuple"}],"name":"SetAddresses","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"apFunding","type":"uint256"}],"name":"SetApFunding","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"period","type":"uint256"}],"name":"SetBlackoutPeriod","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"purchaseFeePercent","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"settlementFeePercent","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"settleDelegationFeePercent","type":"uint256"}],"name":"SetFeePercents","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"pnlSlippagePercent","type":"uint256"}],"name":"SetPnlSlippagePercent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"pnl","type":"uint256"}],"name":"Settle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bool","name":"rollover","type":"bool"}],"name":"ToggleRollover","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"pnl","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_DELEGATION_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_PURCHASE_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERCENT_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDC_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"}],"name":"addToContractWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"addresses","outputs":[{"internalType":"address","name":"usd","type":"address"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"address","name":"assetSwapper","type":"address"},{"internalType":"address","name":"priceOracle","type":"address"},{"internalType":"address","name":"volatilityOracle","type":"address"},{"internalType":"address","name":"optionPricing","type":"address"},{"internalType":"address","name":"feeDistributor","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"apFundingPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blackoutPeriodBeforeExpiry","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"expiry","type":"uint256"}],"name":"bootstrap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_timeToExpiry","type":"uint256"}],"name":"calculateApFunding","outputs":[{"internalType":"uint256","name":"funding","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_isPut","type":"bool"},{"internalType":"uint256","name":"_strike","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_expiry","type":"uint256"}],"name":"calculatePremium","outputs":[{"internalType":"uint256","name":"premium","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"calculateStraddlePositionPnl","outputs":[{"internalType":"uint256","name":"buyerPnl","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"calculateWritePositionPnl","outputs":[{"internalType":"uint256","name":"writePositionPnl","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"shouldRollover","type":"bool"},{"internalType":"address","name":"user","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"bool","name":"transferNative","type":"bool"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"epochCollectionsData","outputs":[{"internalType":"uint256","name":"usdPremiums","type":"uint256"},{"internalType":"uint256","name":"usdFunding","type":"uint256"},{"internalType":"uint256","name":"totalSold","type":"uint256"},{"internalType":"uint256","name":"straddleCounter","type":"uint256"},{"internalType":"uint256","name":"finalUsdBalanceBeforeWithdaw","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"epochData","outputs":[{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"usdDeposits","type":"uint256"},{"internalType":"uint256","name":"activeUsdDeposits","type":"uint256"},{"internalType":"uint256","name":"settlementPrice","type":"uint256"},{"internalType":"uint256","name":"settlementPercentage","type":"uint256"},{"internalType":"uint256","name":"underlyingPurchased","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"expireEpoch","outputs":[{"internalType":"bool","name":"expired","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","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":[],"name":"getUnderlyingPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_strike","type":"uint256"}],"name":"getVolatility","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":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isContract","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isEpochExpired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isEpochPreExpired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isVaultReady","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"multirollover","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"multisettle","outputs":[{"internalType":"uint256[]","name":"pnls","type":"uint256[]"}],"stateMutability":"nonpayable","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":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pnlSlippagePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"uint256","name":"swapperId","type":"uint256"}],"name":"preExpireEpoch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"swapperId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"purchase","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"purchaseFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"}],"name":"removeFromContractWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","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":"uint256","name":"id","type":"uint256"}],"name":"rollover","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"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":[{"components":[{"internalType":"address","name":"usd","type":"address"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"address","name":"assetSwapper","type":"address"},{"internalType":"address","name":"priceOracle","type":"address"},{"internalType":"address","name":"volatilityOracle","type":"address"},{"internalType":"address","name":"optionPricing","type":"address"},{"internalType":"address","name":"feeDistributor","type":"address"}],"internalType":"struct AtlanticStraddle.Addresses","name":"_addresses","type":"tuple"}],"name":"setAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_apFundingPercent","type":"uint256"}],"name":"setApFunding","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":"uint256","name":"period","type":"uint256"}],"name":"setBlackoutPeriodBeforeExpiry","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_purchaseFeePercent","type":"uint256"},{"internalType":"uint256","name":"_settlementFeePercent","type":"uint256"},{"internalType":"uint256","name":"_settleDelegationFeePercent","type":"uint256"}],"name":"setFeePercents","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pnlSlippagePercent","type":"uint256"}],"name":"setPnlSlippagePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"settle","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"settleDelegationFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"settlementFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"straddlePositions","outputs":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"apStrike","type":"uint256"},{"internalType":"uint256","name":"underlyingPurchased","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"straddlePositionsOfOwner","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"stateMutability":"view","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":"id","type":"uint256"}],"name":"toggleRollover","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelistedContracts","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"writePositionPnl","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"writePositions","outputs":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"uint256","name":"usdDeposit","type":"uint256"},{"internalType":"bool","name":"rollover","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"writePositionsOfOwner","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6080604052620186a0601e556200001b620f4240600a620006db565b601f55620186a060205562000035620f42406010620006db565b60215562000048600a620f4240620006fd565b60225561546060235562000061620f42406002620006db565b6024553480156200007157600080fd5b506040516200617e3803806200617e83398101604081905262000094916200083e565b60016000819055835184918491620000b2919060208501906200061f565b508051620000c89060029060208401906200061f565b5050600c805460ff19169055508051601080546001600160a01b03199081166001600160a01b03938416908117909255602080850151601180548416918616919091179055604085015160128054841691861691821790556060860151601380548516918716919091179055608086015160148054851691871691909117905560a086015160158054851691871691909117905560c0860151601680549094169516949094179091556200018a929060001990620001f9811b620036c817901c565b601254601154620001b7916001600160a01b039182169116600019620001f9602090811b620036c817901c565b620001c4600033620002ef565b620001f07f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b0833620002ef565b50505062000a3a565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e9060440160206040518083038186803b1580156200024657600080fd5b505afa1580156200025b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000281919062000951565b6200028d91906200096b565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b17909152919250620002e991869190620002ff16565b50505050565b620002fb8282620003e6565b5050565b60006200035b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166200048a60201b620037bc179092919060201c565b805190915015620003e157808060200190518101906200037c919062000986565b620003e15760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b505050565b6000828152600b602090815260408083206001600160a01b038516845290915290205460ff16620002fb576000828152600b602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620004463390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60606200049b8484600085620004a5565b90505b9392505050565b606082471015620005085760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401620003d8565b6001600160a01b0385163b620005615760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401620003d8565b600080866001600160a01b031685876040516200057f9190620009aa565b60006040518083038185875af1925050503d8060008114620005be576040519150601f19603f3d011682016040523d82523d6000602084013e620005c3565b606091505b509092509050620005d6828286620005e1565b979650505050505050565b60608315620005f25750816200049e565b825115620006035782518084602001fd5b8160405162461bcd60e51b8152600401620003d89190620009c8565b8280546200062d90620009fd565b90600052602060002090601f0160209004810192826200065157600085556200069c565b82601f106200066c57805160ff19168380011785556200069c565b828001600101855582156200069c579182015b828111156200069c5782518255916020019190600101906200067f565b50620006aa929150620006ae565b5090565b5b80821115620006aa5760008155600101620006af565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615620006f857620006f8620006c5565b500290565b6000826200071b57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b03811182821017156200075b576200075b62000720565b60405290565b60005b838110156200077e57818101518382015260200162000764565b83811115620002e95750506000910152565b600082601f830112620007a257600080fd5b81516001600160401b0380821115620007bf57620007bf62000720565b604051601f8301601f19908116603f01168101908282118183101715620007ea57620007ea62000720565b816040528381528660208588010111156200080457600080fd5b6200081784602083016020890162000761565b9695505050505050565b80516001600160a01b03811681146200083957600080fd5b919050565b60008060008385036101208112156200085657600080fd5b84516001600160401b03808211156200086e57600080fd5b6200087c8883890162000790565b955060208701519150808211156200089357600080fd5b50620008a28782880162000790565b93505060e0603f1982011215620008b857600080fd5b50620008c362000736565b620008d16040860162000821565b8152620008e16060860162000821565b6020820152620008f46080860162000821565b60408201526200090760a0860162000821565b60608201526200091a60c0860162000821565b60808201526200092d60e0860162000821565b60a082015262000941610100860162000821565b60c0820152809150509250925092565b6000602082840312156200096457600080fd5b5051919050565b60008219821115620009815762000981620006c5565b500190565b6000602082840312156200099957600080fd5b815180151581146200049e57600080fd5b60008251620009be81846020870162000761565b9190910192915050565b6020815260008251806020840152620009e981604085016020870162000761565b601f01601f19169190910160400192915050565b600181811c9082168062000a1257607f821691505b6020821081141562000a3457634e487b7160e01b600052602260045260246000fd5b50919050565b6157348062000a4a6000396000f3fe608060405234801561001057600080fd5b506004361061043e5760003560e01c80637927113011610236578063c1419def1161013b578063de8b007a116100c3578063ef2bb7e211610087578063ef2bb7e214610b28578063f55b5b1014610b3b578063f9bb30e214610b4e578063fcec046814610b61578063ffe8e3721461096657600080fd5b8063de8b007a14610a62578063e985e9c514610a75578063ea3bd5df14610ab1578063ec87621c14610ac4578063ee0d82c114610ad957600080fd5b8063cddd38931161010a578063cddd3893146109a9578063cf4b6805146109b2578063d547741f146109c5578063d706f3f0146109d8578063da0321cd146109e157600080fd5b8063c1419def14610966578063c189c19b14610970578063c3d9ed3914610983578063c87b56dd1461099657600080fd5b806395d89b41116101be578063a22cb4651161018d578063a22cb46514610911578063acc3a00614610924578063b375d49214610937578063b88d4fde1461094a578063bbdce1681461095d57600080fd5b806395d89b4114610889578063998e59ae146108915780639ce990ea146108f6578063a217fddf1461090957600080fd5b80638df82800116102055780638df82800146107e257806390bb5855146107f557806391d148541461084a578063931efa961461085d57806393c82c751461086657600080fd5b806379271130146107a15780637c4b52cb146107b457806380ed71e4146107c75780638456cb59146107da57600080fd5b80633dbb196d1161034757806354545bfb116102cf5780636db29f6d116102935780636db29f6d146106ea5780636e821b2e146106f257806370a082311461077257806375153f3e14610785578063766718081461079857600080fd5b806354545bfb146106985780635c975abb146106a65780636352211e146106b15780636ae78edf146106c45780636c1085a1146106d757600080fd5b806342842e0e1161031657806342842e0e14610634578063468f02d2146106475780634a2a60701461064f5780634f6ccce7146106725780635387b84c1461068557600080fd5b80633dbb196d146105d65780633ec21260146105f65780633f4ba83a146106095780633f83b8a51461061157600080fd5b80632e1a7d4d116103ca57806333f4bb991161039957806333f4bb991461057157806336568abe1461057a5780633686a39e1461058d578063391feebb146105a05780633b8f56a0146105c357600080fd5b80632e1a7d4d146105255780632f2ff15d146105385780632f745c591461054b57806333277bca1461055e57600080fd5b8063162790551161041157806316279055146104c057806318160ddd146104d457806323b872dd146104e6578063248a9ca3146104f957806326325a781461051c57600080fd5b806301ffc9a71461044357806306fdde031461046b578063081812fc14610480578063095ea7b3146104ab575b600080fd5b610456610451366004614d21565b610b6a565b60405190151581526020015b60405180910390f35b610473610b7b565b6040516104629190614d96565b61049361048e366004614da9565b610c0d565b6040516001600160a01b039091168152602001610462565b6104be6104b9366004614dd9565b610c34565b005b6104566104ce366004614e03565b3b151590565b6009545b604051908152602001610462565b6104be6104f4366004614e1e565b610d4f565b6104d8610507366004614da9565b6000908152600b602052604090206001015490565b6104d860205481565b6104d8610533366004614da9565b610d80565b6104be610546366004614e5a565b610f72565b6104d8610559366004614dd9565b610f97565b6104be61056c366004614e86565b61102d565b6104d860225481565b6104be610588366004614e5a565b6110f4565b61045661059b366004614da9565b611172565b6104566105ae366004614e03565b600d6020526000908152604090205460ff1681565b6104566105d1366004614eb2565b611378565b6105e96105e4366004614f1b565b6117eb565b6040516104629190614fc1565b6105e9610604366004614e03565b611890565b6104be61194c565b61045661061f366004614da9565b60196020526000908152604090205460ff1681565b6104be610642366004614e1e565b611962565b6104d861197d565b61045661065d366004614da9565b601a6020526000908152604090205460ff1681565b6104d8610680366004614da9565b6119ff565b6104d8610693366004614da9565b611a92565b6104d8662386f26fc1000081565b600c5460ff16610456565b6104936106bf366004614da9565b611bf5565b6104d86106d2366004615013565b611c55565b6104be6106e5366004614da9565b611d12565b610456611e53565b61073d610700366004614da9565b6017602052600090815260409020805460018201546002830154600384015460048501546005860154600690960154949593949293919290919087565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e001610462565b6104d8610780366004614e03565b612062565b6104d8610793366004614da9565b6120e8565b6104d8600f5481565b6105e96107af366004614e03565b612185565b6104be6107c236600461504e565b61223a565b6104d86107d53660046150d4565b612360565b6104be612529565b6104d86107f0366004614da9565b61253c565b61082a610803366004614da9565b601d6020526000908152604090208054600182015460028301546003909301549192909184565b604080519485526020850193909352918301526060820152608001610462565b610456610858366004614e5a565b612852565b6104d860245481565b610456610874366004614da9565b601b6020526000908152604090205460ff1681565b61047361287d565b6108ce61089f366004614da9565b601860205260009081526040902080546001820154600283015460038401546004909401549293919290919085565b604080519586526020860194909452928401919091526060830152608082015260a001610462565b6104d8610904366004614e86565b61288c565b6104d8600081565b6104be61091f366004615112565b6128ed565b6104be610932366004614e03565b6128f8565b6104be610945366004615149565b61290c565b6104be6109583660046151f9565b612a4c565b6104d860215481565b6104d8620f424081565b6104d861097e366004614da9565b612a84565b6104be610991366004614e03565b612b01565b6104736109a4366004614da9565b612b15565b6104d860235481565b6104566109c0366004614da9565b612b88565b6104be6109d3366004614e5a565b612c37565b6104d8601f5481565b601054601154601254601354601454601554601654610a19966001600160a01b03908116968116958116948116938116928116911687565b604080516001600160a01b039889168152968816602088015294871694860194909452918516606085015284166080840152831660a083015290911660c082015260e001610462565b6105e9610a70366004614f1b565b612c5c565b610456610a833660046152b9565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b6104d8610abf3660046152e3565b612d01565b6104d86000805160206156df83398151915281565b610b0b610ae7366004614da9565b601c6020526000908152604090208054600182015460029092015490919060ff1683565b604080519384526020840192909252151590820152606001610462565b6104d8610b36366004614da9565b6132fe565b6104be610b49366004614da9565b613608565b6104be610b5c366004614da9565b613668565b6104d8601e5481565b6000610b75826137cb565b92915050565b606060018054610b8a9061530f565b80601f0160208091040260200160405190810160405280929190818152602001828054610bb69061530f565b8015610c035780601f10610bd857610100808354040283529160200191610c03565b820191906000526020600020905b815481529060010190602001808311610be657829003601f168201915b5050505050905090565b6000610c18826137f0565b506000908152600560205260409020546001600160a01b031690565b6000610c3f82611bf5565b9050806001600160a01b0316836001600160a01b03161415610cb25760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b0382161480610cce5750610cce8133610a83565b610d405760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610ca9565b610d4a838361384f565b505050565b610d5933826138bd565b610d755760405162461bcd60e51b8152600401610ca990615344565b610d4a83838361393b565b6000610d8a613ae2565b60026000541415610dad5760405162461bcd60e51b8152600401610ca990615392565b6002600055610dba613b2a565b33610dc483611bf5565b6001600160a01b031614610e0a5760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b21037bbb732b960991b6044820152606401610ca9565b6000828152601c60209081526040918290208251606081018452815480825260018301549382019390935260029091015460ff16151592810192909252610e635760405162461bcd60e51b8152600401610ca9906153c9565b80516000908152601b602052604090205460ff16610eba5760405162461bcd60e51b8152602060048201526014602482015273536574746c656d656e7473206e6f7420646f6e6560601b6044820152606401610ca9565b610ec3836120e8565b9150610ece83613b90565b81610f155760405162461bcd60e51b81526020600482015260176024820152760577269746520706f736974696f6e20706e6c206973203604c1b6044820152606401610ca9565b601054610f2c906001600160a01b03163384613c37565b604080518481526020810184905233917ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568910160405180910390a2506001600055919050565b6000828152600b6020526040902060010154610f8d81613c67565b610d4a8383613c71565b6000610fa283612062565b82106110045760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610ca9565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b600061103881613c67565b6000841180156110485750600083115b80156110545750600082115b6110a05760405162461bcd60e51b815260206004820152601f60248201527f50657263656e7473206d7573742062652067726561746572207468616e2030006044820152606401610ca9565b601e849055602083815560228390556040805186815291820185905281018390527f55098e58cb45f2010b003083b66e4a51d1e887ad51259c626dc46dcdd0019bd99060600160405180910390a150505050565b6001600160a01b03811633146111645760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610ca9565b61116e8282613cf7565b5050565b600061117c613ae2565b6000805160206156df83398151915261119481613c67565b6000600f5460016111a5919061540f565b90508342106112025760405162461bcd60e51b8152602060048201526024808201527f4578706972792063616e6e6f74206265206265666f72652063757272656e742060448201526374696d6560e01b6064820152608401610ca9565b600f541580611220575060008181526019602052604090205460ff16155b6112785760405162461bcd60e51b8152602060048201526024808201527f43616e6e6f7420626f6f747374726170207768656e207661756c7420697320726044820152636561647960e01b6064820152608401610ca9565b600f541561130757600f546000908152601b602052604090205460ff166113075760405162461bcd60e51b815260206004820152603f60248201527f43616e6e6f7420626f6f747374726170206265666f726520746865206375727260448201527f656e742065706f6368207761732065787069726564202620736574746c6564006064820152608401610ca9565b600081815260176020908152604080832042815560019081018890556019835292819020805460ff1916909317909255600f83905590518281527fb5ca1ca1b7b47549eb8af476f3ef702fc63bcd8b8c01dc163b009bb818f97997910160405180910390a160019250505b50919050565b6000611382613ae2565b6000805160206156df83398151915261139a81613c67565b600f54600090815260176020908152604091829020825160e081018452815481526001820154928101929092526002810154928201929092526003820154606082015260048201546080820152600582015460a082015260069091015460c0820152846114425760405162461bcd60e51b8152602060048201526016602482015275050657263656e746167652063616e6e6f7420626520360541b6044820152606401610ca9565b80602001514210156114965760405162461bcd60e51b815260206004820152601d60248201527f54696d65206973206e6f7420706173742065706f6368206578706972790000006044820152606401610ca9565b600f546000908152601a602052604090205460ff16156114f85760405162461bcd60e51b815260206004820152601d60248201527f45706f63682077617320616c7265616479207072652d657870697265640000006044820152606401610ca9565b600f546000908152601b602052604090205460ff16156115565760405162461bcd60e51b8152602060048201526019602482015278115c1bd8da081dd85cc8185b1c9958591e48195e1c1a5c9959603a1b6044820152606401610ca9565b611564620f42406064615427565b858260a00151611574919061540f565b11156115c25760405162461bcd60e51b815260206004820152601e60248201527f596f752063616e6e6f742073776170206d6f7265207468616e203130302500006044820152606401610ca9565b60006115d2620f42406064615427565b868360c001516115e29190615427565b6115ec919061545c565b9050600081156116cd5760006116028388613d5e565b90508060186000600f548152602001908152602001600020600401600082825461162c919061540f565b90915550600090508361164868056bc75e2d6310000084615427565b611652919061545c565b9050888560a00151611664919061540f565b61166e8a83615427565b8660a0015187608001516116829190615427565b61168c919061540f565b611696919061545c565b92508860176000600f54815260200190815260200160002060050160008282546116c0919061540f565b909155506116fb92505050565b6116d561197d565b90506116e5620f42406064615427565b600f546000908152601760205260409020600501555b600f5460009081526017602052604090206004015461173057600f546000908152601760205260409020600401819055611765565b600f5460009081526017602052604090206004015461174f9082613e05565b600f546000908152601760205260409020600401555b611773620f42406063615427565b600f5460009081526017602052604090206005015411156117ab57600f546000908152601a60205260409020805460ff191660011790555b6040513381527fe299059e3adc918e4f4ab456527f6220987ed7fce29c2bc9a416f9336822bdd29060200160405180910390a15060019695505050505050565b6060815167ffffffffffffffff81111561180757611807614ed4565b604051908082528060200260200182016040528015611830578160200160208202803683370190505b50905060005b82518110156113725761186183828151811061185457611854615470565b602002602001015161253c565b82828151811061187357611873615470565b60209081029190910101528061188881615486565b915050611836565b6060600061189d83612062565b90508067ffffffffffffffff8111156118b8576118b8614ed4565b6040519080825280602002602001820160405280156118e1578160200160208202803683370190505b50915060005b818110156119455760006118fb8583610f97565b6000818152601d602052604090205490915015611932578084838151811061192557611925615470565b6020026020010181815250505b508061193d81615486565b9150506118e7565b5050919050565b600061195781613c67565b61195f613e1b565b50565b610d4a83838360405180602001604052806000815250612a4c565b60135460408051632347816960e11b815290516000926001600160a01b03169163468f02d2916004808301926020929190829003018186803b1580156119c257600080fd5b505afa1580156119d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119fa91906154a1565b905090565b6000611a0a60095490565b8210611a6d5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610ca9565b60098281548110611a8057611a80615470565b90600052602060002001549050919050565b6000818152601d602090815260408083208151608081018352815480825260018301549482019490945260028201549281019290925260030154606082015290611b1a5760405162461bcd60e51b815260206004820152601960248201527824b73b30b634b21039ba3930b2323632903837b9b4ba34b7b760391b6044820152606401610ca9565b805160009081526017602052604090819020600401549082015181811115611b82576020830151611b4b83836154ba565b611b559190615427565b6060840151909450611b6783836154ba565b611b719190615427565b611b7b90856154ba565b9350611ba8565b6060830151611b9182846154ba565b611b9b9190615427565b611ba5908561540f565b93505b611bbb68056bc75e2d631000008561545c565b9350611bcb620f42406064615427565b602454611bd89086615427565b611be2919061545c565b611bec90856154ba565b95945050505050565b6000818152600360205260408120546001600160a01b031680610b755760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610ca9565b60155460009083906001600160a01b0316635b7b6d88878588611c7661197d565b611c7f8b612a84565b6040516001600160e01b031960e088901b1681529415156004860152602485019390935260448401919091526064830152608482015260a40160206040518083038186803b158015611cd057600080fd5b505afa158015611ce4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d0891906154a1565b611bec9190615427565b611d1a613ae2565b60026000541415611d3d5760405162461bcd60e51b8152600401610ca990615392565b6002600055611d4a613b2a565b33611d5482611bf5565b6001600160a01b031614611d9a5760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b21037bbb732b960991b6044820152606401610ca9565b6000818152601c6020526040902054611de85760405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b2103837b9b4ba34b7b760811b6044820152606401610ca9565b6000818152601c6020908152604091829020600201805460ff8082161560ff199092168217909255835185815291161515918101919091527fb5e95d468eadd79446f495b23ddf06bb55ff5717a821eb2cc57154a31cd5ee22910160405180910390a1506001600055565b6000611e5d613ae2565b6000805160206156df833981519152611e7581613c67565b600f54600090815260176020526040902060010154421015611ed95760405162461bcd60e51b815260206004820152601d60248201527f54696d65206973206e6f7420706173742065706f6368206578706972790000006044820152606401610ca9565b600f546000908152601a602052604090205460ff16611f365760405162461bcd60e51b8152602060048201526019602482015278115c1bd8da081a185cc81b9bdd081c1c994b595e1c1a5c9959603a1b6044820152606401610ca9565b600f546000908152601b602052604090205460ff1615611f945760405162461bcd60e51b8152602060048201526019602482015278115c1bd8da081dd85cc8185b1c9958591e48195e1c1a5c9959603a1b6044820152606401610ca9565b600f54600090815260186020526040902060030154611fd357600f546000908152601b60205260409020805460ff19166001908117909155915061202b565b60405162461bcd60e51b815260206004820152602760248201527f416c6c20736574746c656d656e74732068617665206e6f74206265656e2070726044820152661bd8d95cdcd95960ca1b6064820152608401610ca9565b6040513381527f6a4de20bb9fa8fea199f1022f29eff6be1752c446674d16913f2afc2b3c5a8a59060200160405180910390a15090565b60006001600160a01b0382166120cc5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610ca9565b506001600160a01b031660009081526004602052604090205490565b6000818152601c602090815260408083208151606081018352815480825260018301549482019490945260029091015460ff16151591810191909152906121415760405162461bcd60e51b8152600401610ca9906153c9565b80516000908152601760209081526040808320600201548451845260188352922060040154908301516121749190615427565b61217e919061545c565b9392505050565b6060600061219283612062565b90508067ffffffffffffffff8111156121ad576121ad614ed4565b6040519080825280602002602001820160405280156121d6578160200160208202803683370190505b50915060005b818110156119455760006121f08583610f97565b6000818152601c602052604090205490915015612227578084838151811061221a5761221a615470565b6020026020010181815250505b508061223281615486565b9150506121dc565b600061224581613c67565b61224d613e6d565b81156122815760405133904780156108fc02916000818181858888f1935050505015801561227f573d6000803e3d6000fd5b505b60005b838110156123595760008585838181106122a0576122a0615470565b90506020020160208101906122b59190614e03565b6040516370a0823160e01b81523060048201529091506123469033906001600160a01b038416906370a082319060240160206040518083038186803b1580156122fd57600080fd5b505afa158015612311573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233591906154a1565b6001600160a01b0384169190613c37565b508061235181615486565b915050612284565b5050505050565b600061236a613ae2565b6002600054141561238d5760405162461bcd60e51b8152600401610ca990615392565b600260005561239a613b2a565b600084116123ea5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74206465706f736974203020616d6f756e740000000000000000006044820152606401610ca9565b6000600f5460016123fb919061540f565b905084601760008381526020019081526020016000206002016000828254612423919061540f565b90915550506000818152601860205260408120600401805487929061244990849061540f565b90915550612458905083613eb6565b6040805160608101825283815260208082018981528815158385019081526000868152601c909352939091209151825551600182015590516002909101805460ff19169115159190911790556010549092506124bf906001600160a01b0316333088613ee0565b6040805182815260208101879052851515818301526001600160a01b038516606082015233608082015260a0810184905290517f14c0e56f4125d5707194bbf1beff49bb39b170a0f49574bcf25d8616f4df1cf69181900360c00190a15060016000559392505050565b600061253481613c67565b61195f613f18565b6000612546613ae2565b600260005414156125695760405162461bcd60e51b8152600401610ca990615392565b6002600055612576613b2a565b6000828152601d6020908152604091829020825160808101845281548082526001830154938201939093526002820154938101939093526003015460608301526125fe5760405162461bcd60e51b815260206004820152601960248201527824b73b30b634b21039ba3930b2323632903837b9b4ba34b7b760391b6044820152606401610ca9565b80516000908152601a602052604090205460ff1661265a5760405162461bcd60e51b8152602060048201526019602482015278115c1bd8da081a185cc81b9bdd081c1c994b595e1c1a5c9959603a1b6044820152606401610ca9565b600061266584611a92565b9050600061267285611bf5565b905061267d85613b90565b816126c15760405162461bcd60e51b815260206004820152601460248201527306275796572506e6c2063616e6e6f7420626520360641b6044820152606401610ca9565b60006126d1620f42406064615427565b6020546126de9085615427565b6126e8919061545c565b905060006001600160a01b03831633146127325761270a620f42406064615427565b6022546127179086615427565b612721919061545c565b905061272f81601f54613e05565b90505b61273c818361540f565b61274690856154ba565b85516000908152601860205260408120600301805492965060019290919061276f9084906154ba565b90915550819050612780838661540f565b61278a919061540f565b8551600090815260186020526040812060040180549091906127ad9084906154ba565b90915550506016546010546127cf916001600160a01b03918216911684613c37565b6010546127e6906001600160a01b03168486613c37565b6010546127fd906001600160a01b03163383613c37565b60408051888152602081018690526001600160a01b0385169133917fddd2b8bfe59e2aa6d76b0600fa7f6e161b9ece46b47a20197e2755899e7e8837910160405180910390a350506001600055509392505050565b6000918252600b602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060028054610b8a9061530f565b6000600260646128a3620f42406301e13380615427565b8585602154896128b39190615427565b6128bd9190615427565b6128c79190615427565b6128d1919061545c565b6128db919061545c565b6128e5919061545c565b949350505050565b61116e338383613f55565b600061290381613c67565b61116e82614024565b600061291781613c67565b8151601080546001600160a01b039283166001600160a01b0319918216179091556020840151601180549184169183169190911790556040808501516012805491851691841691909117905560608501516013805491851691841691909117905560808501516014805491851691841691909117905560a08501516015805491851691841691909117905560c08501516016805491909416921691909117909155517f488865203db2c6efd677f2757b6433d6fd6f452390e796b6719252b8588fcdf990612a4090849081516001600160a01b03908116825260208084015182169083015260408084015182169083015260608084015182169083015260808084015182169083015260a08381015182169083015260c092830151169181019190915260e00190565b60405180910390a15050565b612a5633836138bd565b612a725760405162461bcd60e51b8152600401610ca990615344565b612a7e84848484614127565b50505050565b60145460405163c189c19b60e01b8152600481018390526000916001600160a01b03169063c189c19b9060240160206040518083038186803b158015612ac957600080fd5b505afa158015612add573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b7591906154a1565b6000612b0c81613c67565b61116e8261415a565b6060612b20826137f0565b6000612b3760408051602081019091526000815290565b90506000815111612b57576040518060200160405280600081525061217e565b80612b618461420b565b604051602001612b729291906154d1565b6040516020818303038152906040529392505050565b600080612b9481613c67565b610e108311612bf65760405162461bcd60e51b815260206004820152602860248201527f426c61636b6f757420706572696f64206d757374206265206d6f726520746861604482015267371018903437bab960c11b6064820152608401610ca9565b60238390556040518381527f32e6db6aab294383bb2b48c5adfb1100050e096a4ce0eed5b7568604fc09f10b9060200160405180910390a150600192915050565b6000828152600b6020526040902060010154612c5281613c67565b610d4a8383613cf7565b6060815167ffffffffffffffff811115612c7857612c78614ed4565b604051908082528060200260200182016040528015612ca1578160200160208202803683370190505b50905060005b825181101561137257612cd2838281518110612cc557612cc5615470565b60200260200101516132fe565b828281518110612ce457612ce4615470565b602090810291909101015280612cf981615486565b915050612ca7565b6000612d0b613ae2565b60026000541415612d2e5760405162461bcd60e51b8152600401610ca990615392565b6002600055612d3b613b2a565b6000600f5411612d7d5760405162461bcd60e51b815260206004820152600d60248201526c092dcecc2d8d2c840cae0dec6d609b1b6044820152606401610ca9565b662386f26fc100008411612dc45760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606401610ca9565b602354600f54600090815260176020526040902060010154612de691906154ba565b4210612e435760405162461bcd60e51b815260206004820152602660248201527f43616e6e6f7420707572636861736520647572696e6720626c61636b6f7574206044820152651c195c9a5bd960d21b6064820152608401610ca9565b6000612e4d61197d565b600f5460009081526017602052604081206001015491925090612e719042906154ba565b905068056bc75e2d63100000612e878784615427565b612e91919061545c565b600f54600090815260176020526040902060030154612eba9068056bc75e2d631000009061545c565b600f54600090815260176020526040902060020154612ed991906154ba565b1015612f315760405162461bcd60e51b815260206004820152602160248201527f4e6f7420656e6f756768204150206c697175696469747920617661696c61626c6044820152606560f81b6064820152608401610ca9565b6000612f6668056bc75e2d631000006002612f4c8a87615427565b612f56919061545c565b612f60919061545c565b87614309565b905068056bc75e2d631000006002612f7e8986615427565b612f88919061545c565b612f92919061545c565b600f5460009081526018602052604081206004018054909190612fb69084906154ba565b9091555060009050612fc9826002615427565b612fd38986615427565b612fdd919061545c565b90508160176000600f5481526020019081526020016000206006016000828254613007919061540f565b909155506130189050826002615427565b6130229082615427565b600f546000908152601760205260408120600301805490919061304690849061540f565b909155506000905061307960018361305f866002615427565b600f54600090815260176020526040902060010154611c55565b905060006130928361308c866002615427565b8761288c565b600f546000908152601860205260408120805492935084929091906130b890849061540f565b9091555050600f54600090815260186020526040812060010180548392906130e190849061540f565b909155506130f29050846002615427565b600f546000908152601860205260408120600201805490919061311690849061540f565b9091555050600f54600090815260186020526040812060030180546001929061314090849061540f565b9091555061314f905088613eb6565b96506040518060800160405280600f5481526020018560026131719190615427565b81526020808201869052604091820187905260008a8152601d8252828120845181559184015160018301559183015160028201556060909201516003909201919091556131ca68056bc75e2d63100000620f4240615427565b6131d5906064615427565b601e546131e29085615427565b6131ec919061545c565b905061323033308368056bc75e2d63100000613208878961540f565b613212919061545c565b61321c919061540f565b6010546001600160a01b0316929190613ee0565b60165460105461324d916001600160a01b03918216911683613c37565b68056bc75e2d63100000613261838561540f565b61326b919061545c565b600f546000908152601860205260408120600401805490919061328f90849061540f565b909155507f12cb4648cf3058b17ceeb33e579f8b0bc269fe0843f3900b8e24b6c54871703c905089896132c2858761540f565b604080516001600160a01b03909416845260208401929092529082015260600160405180910390a1505060016000555093979650505050505050565b6000613308613ae2565b6002600054141561332b5760405162461bcd60e51b8152600401610ca990615392565b6002600055613338613b2a565b6000828152601c60209081526040918290208251606081018452815481526001820154928101929092526002015460ff161515918101829052906133be5760405162461bcd60e51b815260206004820152601760248201527f526f6c6c6f766572206e6f7420617574686f72697a65640000000000000000006044820152606401610ca9565b80516133dc5760405162461bcd60e51b8152600401610ca9906153c9565b80516000908152601b602052604090205460ff166134345760405162461bcd60e51b8152602060048201526015602482015274115c1bd8da081a185cc81b9bdd08195e1c1a5c9959605a1b6044820152606401610ca9565b600061343f846120e8565b9050600061344c85611bf5565b905061345785613b90565b8161349e5760405162461bcd60e51b81526020600482015260176024820152760577269746520706f736974696f6e20706e6c206973203604c1b6044820152606401610ca9565b60408051868152602081018490526001600160a01b038316917ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568910160405180910390a26000600f5460016134f3919061540f565b90508260176000838152602001908152602001600020600201600082825461351b919061540f565b90915550506000818152601860205260408120600401805485929061354190849061540f565b90915550613550905082613eb6565b6040805160608082018352848252602080830188815260018486018181526000888152601c85528790209551865591518582015590516002909401805460ff1916941515949094179093558351868152908101889052928301919091526001600160a01b038516908201819052608082015260a081018290529095507f14c0e56f4125d5707194bbf1beff49bb39b170a0f49574bcf25d8616f4df1cf69060c00160405180910390a150506001600055509092915050565b600061361381613c67565b600082116136335760405162461bcd60e51b8152600401610ca990615500565b60248290556040518281527fe4d44cc62a77ab305c1c324248b29e91f621d65b1c231ee984dd6800b2ff7b4690602001612a40565b600061367381613c67565b600082116136935760405162461bcd60e51b8152600401610ca990615500565b60218290556040518281527fc5c758ec4001ae2dfceeb8a99ff59eacf17b62ca95bae713257b9dd494b9a84090602001612a40565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e9060440160206040518083038186803b15801561371457600080fd5b505afa158015613728573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061374c91906154a1565b613756919061540f565b6040516001600160a01b038516602482015260448101829052909150612a7e90859063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614362565b60606128e58484600085614434565b60006001600160e01b03198216637965db0b60e01b1480610b755750610b7582614565565b6000818152600360205260409020546001600160a01b031661195f5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610ca9565b600081815260056020526040902080546001600160a01b0319166001600160a01b038416908117909155819061388482611bf5565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806138c983611bf5565b9050806001600160a01b0316846001600160a01b0316148061391057506001600160a01b0380821660009081526006602090815260408083209388168352929052205460ff165b806128e55750836001600160a01b031661392984610c0d565b6001600160a01b031614949350505050565b826001600160a01b031661394e82611bf5565b6001600160a01b0316146139b25760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610ca9565b6001600160a01b038216613a145760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610ca9565b613a1f83838361458a565b613a2a60008261384f565b6001600160a01b0383166000908152600460205260408120805460019290613a539084906154ba565b90915550506001600160a01b0382166000908152600460205260408120805460019290613a8190849061540f565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600c5460ff1615613b285760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610ca9565b565b333214613b2857336000908152600d602052604090205460ff16613b285760405162461bcd60e51b815260206004820152601c60248201527f436f6e7472616374206d7573742062652077686974656c6973746564000000006044820152606401610ca9565b6000613b9b82611bf5565b9050613ba98160008461458a565b613bb460008361384f565b6001600160a01b0381166000908152600460205260408120805460019290613bdd9084906154ba565b909155505060008281526003602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6040516001600160a01b038316602482015260448101829052610d4a90849063a9059cbb60e01b90606401613785565b61195f8133614595565b613c7b8282612852565b61116e576000828152600b602090815260408083206001600160a01b03851684529091529020805460ff19166001179055613cb33390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b613d018282612852565b1561116e576000828152600b602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60125460115460105460405163b91ac49560e01b81526001600160a01b0392831660048201529082166024820152604481018590526000606482018190526084820185905292919091169063b91ac4959060a4015b602060405180830381600087803b158015613dcd57600080fd5b505af1158015613de1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217e91906154a1565b6000818310613e14578161217e565b5090919050565b613e23613e6d565b600c805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600c5460ff16613b285760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610ca9565b6000613ec1600e5490565b9050613ed1600e80546001019055565b613edb82826145f9565b919050565b6040516001600160a01b0380851660248301528316604482015260648101829052612a7e9085906323b872dd60e01b90608401613785565b613f20613ae2565b600c805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613e503390565b816001600160a01b0316836001600160a01b03161415613fb75760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610ca9565b6001600160a01b03838116600081815260066020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b803b6140725760405162461bcd60e51b815260206004820152601a60248201527f41646472657373206d757374206265206120636f6e74726163740000000000006044820152606401610ca9565b6001600160a01b0381166000908152600d602052604090205460ff16156140db5760405162461bcd60e51b815260206004820152601c60248201527f436f6e747261637420616c72656164792077686974656c6973746564000000006044820152606401610ca9565b6001600160a01b0381166000818152600d6020526040808220805460ff19166001179055517ffbd3cde7ff522a917e485c8ed2a6e87590887ab399f5ac312307903f498543079190a250565b61413284848461393b565b61413e84848484614613565b612a7e5760405162461bcd60e51b8152600401610ca990615543565b6001600160a01b0381166000908152600d602052604090205460ff166141c25760405162461bcd60e51b815260206004820152601860248201527f436f6e7472616374206e6f742077686974656c697374656400000000000000006044820152606401610ca9565b6001600160a01b0381166000818152600d6020526040808220805460ff19169055517f8e81447740597754af5db3e176253a36f7981a9549f48ace3f0cb233913f9d859190a250565b60608161422f5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115614259578061424381615486565b91506142529050600a8361545c565b9150614233565b60008167ffffffffffffffff81111561427457614274614ed4565b6040519080825280601f01601f19166020018201604052801561429e576020820181803683370190505b5090505b84156128e5576142b36001836154ba565b91506142c0600a86615595565b6142cb90603061540f565b60f81b8183815181106142e0576142e0615470565b60200101906001600160f81b031916908160001a905350614302600a8661545c565b94506142a2565b60125460105460115460405163b91ac49560e01b81526001600160a01b0392831660048201529082166024820152604481018590526000606482018190526084820185905292919091169063b91ac4959060a401613db3565b60006143b7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166137bc9092919063ffffffff16565b805190915015610d4a57808060200190518101906143d591906155a9565b610d4a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610ca9565b6060824710156144955760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610ca9565b6001600160a01b0385163b6144ec5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ca9565b600080866001600160a01b0316858760405161450891906155c6565b60006040518083038185875af1925050503d8060008114614545576040519150601f19603f3d011682016040523d82523d6000602084013e61454a565b606091505b509150915061455a82828661471d565b979650505050505050565b60006001600160e01b0319821663780e9d6360e01b1480610b755750610b7582614756565b610d4a8383836147a6565b61459f8282612852565b61116e576145b7816001600160a01b0316601461485e565b6145c283602061485e565b6040516020016145d39291906155e2565b60408051601f198184030181529082905262461bcd60e51b8252610ca991600401614d96565b61116e8282604051806020016040528060008152506149fa565b60006001600160a01b0384163b1561471557604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614657903390899088908890600401615657565b602060405180830381600087803b15801561467157600080fd5b505af19250505080156146a1575060408051601f3d908101601f1916820190925261469e91810190615694565b60015b6146fb573d8080156146cf576040519150601f19603f3d011682016040523d82523d6000602084013e6146d4565b606091505b5080516146f35760405162461bcd60e51b8152600401610ca990615543565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506128e5565b5060016128e5565b6060831561472c57508161217e565b82511561473c5782518084602001fd5b8160405162461bcd60e51b8152600401610ca99190614d96565b60006001600160e01b031982166380ac58cd60e01b148061478757506001600160e01b03198216635b5e139f60e01b145b80610b7557506301ffc9a760e01b6001600160e01b0319831614610b75565b6001600160a01b038316614801576147fc81600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b614824565b816001600160a01b0316836001600160a01b031614614824576148248382614a2d565b6001600160a01b03821661483b57610d4a81614aca565b826001600160a01b0316826001600160a01b031614610d4a57610d4a8282614b79565b6060600061486d836002615427565b61487890600261540f565b67ffffffffffffffff81111561489057614890614ed4565b6040519080825280601f01601f1916602001820160405280156148ba576020820181803683370190505b509050600360fc1b816000815181106148d5576148d5615470565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061490457614904615470565b60200101906001600160f81b031916908160001a9053506000614928846002615427565b61493390600161540f565b90505b60018111156149ab576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061496757614967615470565b1a60f81b82828151811061497d5761497d615470565b60200101906001600160f81b031916908160001a90535060049490941c936149a4816156b1565b9050614936565b50831561217e5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610ca9565b614a048383614bbd565b614a116000848484614613565b610d4a5760405162461bcd60e51b8152600401610ca990615543565b60006001614a3a84612062565b614a4491906154ba565b600083815260086020526040902054909150808214614a97576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b600954600090614adc906001906154ba565b6000838152600a602052604081205460098054939450909284908110614b0457614b04615470565b906000526020600020015490508060098381548110614b2557614b25615470565b6000918252602080832090910192909255828152600a90915260408082208490558582528120556009805480614b5d57614b5d6156c8565b6001900381819060005260206000200160009055905550505050565b6000614b8483612062565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b6001600160a01b038216614c135760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610ca9565b6000818152600360205260409020546001600160a01b031615614c785760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610ca9565b614c846000838361458a565b6001600160a01b0382166000908152600460205260408120805460019290614cad90849061540f565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160e01b03198116811461195f57600080fd5b600060208284031215614d3357600080fd5b813561217e81614d0b565b60005b83811015614d59578181015183820152602001614d41565b83811115612a7e5750506000910152565b60008151808452614d82816020860160208601614d3e565b601f01601f19169290920160200192915050565b60208152600061217e6020830184614d6a565b600060208284031215614dbb57600080fd5b5035919050565b80356001600160a01b0381168114613edb57600080fd5b60008060408385031215614dec57600080fd5b614df583614dc2565b946020939093013593505050565b600060208284031215614e1557600080fd5b61217e82614dc2565b600080600060608486031215614e3357600080fd5b614e3c84614dc2565b9250614e4a60208501614dc2565b9150604084013590509250925092565b60008060408385031215614e6d57600080fd5b82359150614e7d60208401614dc2565b90509250929050565b600080600060608486031215614e9b57600080fd5b505081359360208301359350604090920135919050565b60008060408385031215614ec557600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614f1357614f13614ed4565b604052919050565b60006020808385031215614f2e57600080fd5b823567ffffffffffffffff80821115614f4657600080fd5b818501915085601f830112614f5a57600080fd5b813581811115614f6c57614f6c614ed4565b8060051b9150614f7d848301614eea565b8181529183018401918481019088841115614f9757600080fd5b938501935b83851015614fb557843582529385019390850190614f9c565b98975050505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614ff957835183529284019291840191600101614fdd565b50909695505050505050565b801515811461195f57600080fd5b6000806000806080858703121561502957600080fd5b843561503481615005565b966020860135965060408601359560600135945092505050565b60008060006040848603121561506357600080fd5b833567ffffffffffffffff8082111561507b57600080fd5b818601915086601f83011261508f57600080fd5b81358181111561509e57600080fd5b8760208260051b85010111156150b357600080fd5b602092830195509350508401356150c981615005565b809150509250925092565b6000806000606084860312156150e957600080fd5b8335925060208401356150fb81615005565b915061510960408501614dc2565b90509250925092565b6000806040838503121561512557600080fd5b61512e83614dc2565b9150602083013561513e81615005565b809150509250929050565b600060e0828403121561515b57600080fd5b60405160e0810181811067ffffffffffffffff8211171561517e5761517e614ed4565b60405261518a83614dc2565b815261519860208401614dc2565b60208201526151a960408401614dc2565b60408201526151ba60608401614dc2565b60608201526151cb60808401614dc2565b60808201526151dc60a08401614dc2565b60a08201526151ed60c08401614dc2565b60c08201529392505050565b6000806000806080858703121561520f57600080fd5b61521885614dc2565b93506020615227818701614dc2565b935060408601359250606086013567ffffffffffffffff8082111561524b57600080fd5b818801915088601f83011261525f57600080fd5b81358181111561527157615271614ed4565b615283601f8201601f19168501614eea565b9150808252898482850101111561529957600080fd5b808484018584013760008482840101525080935050505092959194509250565b600080604083850312156152cc57600080fd5b6152d583614dc2565b9150614e7d60208401614dc2565b6000806000606084860312156152f857600080fd5b833592506020840135915061510960408501614dc2565b600181811c9082168061532357607f821691505b6020821081141561137257634e487b7160e01b600052602260045260246000fd5b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526016908201527524b73b30b634b2103bb934ba32903837b9b4ba34b7b760511b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60008219821115615422576154226153f9565b500190565b6000816000190483118215151615615441576154416153f9565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261546b5761546b615446565b500490565b634e487b7160e01b600052603260045260246000fd5b600060001982141561549a5761549a6153f9565b5060010190565b6000602082840312156154b357600080fd5b5051919050565b6000828210156154cc576154cc6153f9565b500390565b600083516154e3818460208801614d3e565b8351908301906154f7818360208801614d3e565b01949350505050565b60208082526023908201527f46756e64696e672072617465206d75737420626520677265617465722074686160408201526206e20360ec1b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6000826155a4576155a4615446565b500690565b6000602082840312156155bb57600080fd5b815161217e81615005565b600082516155d8818460208701614d3e565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161561a816017850160208801614d3e565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161564b816028840160208801614d3e565b01602801949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061568a90830184614d6a565b9695505050505050565b6000602082840312156156a657600080fd5b815161217e81614d0b565b6000816156c0576156c06153f9565b506000190190565b634e487b7160e01b600052603160045260246000fdfe241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08a26469706673582212207d03e8cdca424291abcf53fa0968b1e199002c42cb6fc739a64dc8a98b5900ec64736f6c6343000809003300000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000ff970a61a04b1ca14834a43f5de4533ebddb5cc800000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab1000000000000000000000000b854384baf57716df2231af260fcc9a548d2726c00000000000000000000000019e6ee4c2cbe7bcc4cd1ef0bcf7e764fece23cc60000000000000000000000007745370dfcc3780dd7675995b529d4e24960c0150000000000000000000000002b99e3d67dad973c1b9747da742b7e26c8bdd67b00000000000000000000000055594cce8cc0014ea08c49fd820d731308f204c100000000000000000000000000000000000000000000000000000000000000174554482041746c616e746963205374726164646c65203200000000000000000000000000000000000000000000000000000000000000000000000000000000174554482d41544c414e5449432d5354524144444c452d32000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061043e5760003560e01c80637927113011610236578063c1419def1161013b578063de8b007a116100c3578063ef2bb7e211610087578063ef2bb7e214610b28578063f55b5b1014610b3b578063f9bb30e214610b4e578063fcec046814610b61578063ffe8e3721461096657600080fd5b8063de8b007a14610a62578063e985e9c514610a75578063ea3bd5df14610ab1578063ec87621c14610ac4578063ee0d82c114610ad957600080fd5b8063cddd38931161010a578063cddd3893146109a9578063cf4b6805146109b2578063d547741f146109c5578063d706f3f0146109d8578063da0321cd146109e157600080fd5b8063c1419def14610966578063c189c19b14610970578063c3d9ed3914610983578063c87b56dd1461099657600080fd5b806395d89b41116101be578063a22cb4651161018d578063a22cb46514610911578063acc3a00614610924578063b375d49214610937578063b88d4fde1461094a578063bbdce1681461095d57600080fd5b806395d89b4114610889578063998e59ae146108915780639ce990ea146108f6578063a217fddf1461090957600080fd5b80638df82800116102055780638df82800146107e257806390bb5855146107f557806391d148541461084a578063931efa961461085d57806393c82c751461086657600080fd5b806379271130146107a15780637c4b52cb146107b457806380ed71e4146107c75780638456cb59146107da57600080fd5b80633dbb196d1161034757806354545bfb116102cf5780636db29f6d116102935780636db29f6d146106ea5780636e821b2e146106f257806370a082311461077257806375153f3e14610785578063766718081461079857600080fd5b806354545bfb146106985780635c975abb146106a65780636352211e146106b15780636ae78edf146106c45780636c1085a1146106d757600080fd5b806342842e0e1161031657806342842e0e14610634578063468f02d2146106475780634a2a60701461064f5780634f6ccce7146106725780635387b84c1461068557600080fd5b80633dbb196d146105d65780633ec21260146105f65780633f4ba83a146106095780633f83b8a51461061157600080fd5b80632e1a7d4d116103ca57806333f4bb991161039957806333f4bb991461057157806336568abe1461057a5780633686a39e1461058d578063391feebb146105a05780633b8f56a0146105c357600080fd5b80632e1a7d4d146105255780632f2ff15d146105385780632f745c591461054b57806333277bca1461055e57600080fd5b8063162790551161041157806316279055146104c057806318160ddd146104d457806323b872dd146104e6578063248a9ca3146104f957806326325a781461051c57600080fd5b806301ffc9a71461044357806306fdde031461046b578063081812fc14610480578063095ea7b3146104ab575b600080fd5b610456610451366004614d21565b610b6a565b60405190151581526020015b60405180910390f35b610473610b7b565b6040516104629190614d96565b61049361048e366004614da9565b610c0d565b6040516001600160a01b039091168152602001610462565b6104be6104b9366004614dd9565b610c34565b005b6104566104ce366004614e03565b3b151590565b6009545b604051908152602001610462565b6104be6104f4366004614e1e565b610d4f565b6104d8610507366004614da9565b6000908152600b602052604090206001015490565b6104d860205481565b6104d8610533366004614da9565b610d80565b6104be610546366004614e5a565b610f72565b6104d8610559366004614dd9565b610f97565b6104be61056c366004614e86565b61102d565b6104d860225481565b6104be610588366004614e5a565b6110f4565b61045661059b366004614da9565b611172565b6104566105ae366004614e03565b600d6020526000908152604090205460ff1681565b6104566105d1366004614eb2565b611378565b6105e96105e4366004614f1b565b6117eb565b6040516104629190614fc1565b6105e9610604366004614e03565b611890565b6104be61194c565b61045661061f366004614da9565b60196020526000908152604090205460ff1681565b6104be610642366004614e1e565b611962565b6104d861197d565b61045661065d366004614da9565b601a6020526000908152604090205460ff1681565b6104d8610680366004614da9565b6119ff565b6104d8610693366004614da9565b611a92565b6104d8662386f26fc1000081565b600c5460ff16610456565b6104936106bf366004614da9565b611bf5565b6104d86106d2366004615013565b611c55565b6104be6106e5366004614da9565b611d12565b610456611e53565b61073d610700366004614da9565b6017602052600090815260409020805460018201546002830154600384015460048501546005860154600690960154949593949293919290919087565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e001610462565b6104d8610780366004614e03565b612062565b6104d8610793366004614da9565b6120e8565b6104d8600f5481565b6105e96107af366004614e03565b612185565b6104be6107c236600461504e565b61223a565b6104d86107d53660046150d4565b612360565b6104be612529565b6104d86107f0366004614da9565b61253c565b61082a610803366004614da9565b601d6020526000908152604090208054600182015460028301546003909301549192909184565b604080519485526020850193909352918301526060820152608001610462565b610456610858366004614e5a565b612852565b6104d860245481565b610456610874366004614da9565b601b6020526000908152604090205460ff1681565b61047361287d565b6108ce61089f366004614da9565b601860205260009081526040902080546001820154600283015460038401546004909401549293919290919085565b604080519586526020860194909452928401919091526060830152608082015260a001610462565b6104d8610904366004614e86565b61288c565b6104d8600081565b6104be61091f366004615112565b6128ed565b6104be610932366004614e03565b6128f8565b6104be610945366004615149565b61290c565b6104be6109583660046151f9565b612a4c565b6104d860215481565b6104d8620f424081565b6104d861097e366004614da9565b612a84565b6104be610991366004614e03565b612b01565b6104736109a4366004614da9565b612b15565b6104d860235481565b6104566109c0366004614da9565b612b88565b6104be6109d3366004614e5a565b612c37565b6104d8601f5481565b601054601154601254601354601454601554601654610a19966001600160a01b03908116968116958116948116938116928116911687565b604080516001600160a01b039889168152968816602088015294871694860194909452918516606085015284166080840152831660a083015290911660c082015260e001610462565b6105e9610a70366004614f1b565b612c5c565b610456610a833660046152b9565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b6104d8610abf3660046152e3565b612d01565b6104d86000805160206156df83398151915281565b610b0b610ae7366004614da9565b601c6020526000908152604090208054600182015460029092015490919060ff1683565b604080519384526020840192909252151590820152606001610462565b6104d8610b36366004614da9565b6132fe565b6104be610b49366004614da9565b613608565b6104be610b5c366004614da9565b613668565b6104d8601e5481565b6000610b75826137cb565b92915050565b606060018054610b8a9061530f565b80601f0160208091040260200160405190810160405280929190818152602001828054610bb69061530f565b8015610c035780601f10610bd857610100808354040283529160200191610c03565b820191906000526020600020905b815481529060010190602001808311610be657829003601f168201915b5050505050905090565b6000610c18826137f0565b506000908152600560205260409020546001600160a01b031690565b6000610c3f82611bf5565b9050806001600160a01b0316836001600160a01b03161415610cb25760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b0382161480610cce5750610cce8133610a83565b610d405760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610ca9565b610d4a838361384f565b505050565b610d5933826138bd565b610d755760405162461bcd60e51b8152600401610ca990615344565b610d4a83838361393b565b6000610d8a613ae2565b60026000541415610dad5760405162461bcd60e51b8152600401610ca990615392565b6002600055610dba613b2a565b33610dc483611bf5565b6001600160a01b031614610e0a5760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b21037bbb732b960991b6044820152606401610ca9565b6000828152601c60209081526040918290208251606081018452815480825260018301549382019390935260029091015460ff16151592810192909252610e635760405162461bcd60e51b8152600401610ca9906153c9565b80516000908152601b602052604090205460ff16610eba5760405162461bcd60e51b8152602060048201526014602482015273536574746c656d656e7473206e6f7420646f6e6560601b6044820152606401610ca9565b610ec3836120e8565b9150610ece83613b90565b81610f155760405162461bcd60e51b81526020600482015260176024820152760577269746520706f736974696f6e20706e6c206973203604c1b6044820152606401610ca9565b601054610f2c906001600160a01b03163384613c37565b604080518481526020810184905233917ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568910160405180910390a2506001600055919050565b6000828152600b6020526040902060010154610f8d81613c67565b610d4a8383613c71565b6000610fa283612062565b82106110045760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610ca9565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b600061103881613c67565b6000841180156110485750600083115b80156110545750600082115b6110a05760405162461bcd60e51b815260206004820152601f60248201527f50657263656e7473206d7573742062652067726561746572207468616e2030006044820152606401610ca9565b601e849055602083815560228390556040805186815291820185905281018390527f55098e58cb45f2010b003083b66e4a51d1e887ad51259c626dc46dcdd0019bd99060600160405180910390a150505050565b6001600160a01b03811633146111645760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610ca9565b61116e8282613cf7565b5050565b600061117c613ae2565b6000805160206156df83398151915261119481613c67565b6000600f5460016111a5919061540f565b90508342106112025760405162461bcd60e51b8152602060048201526024808201527f4578706972792063616e6e6f74206265206265666f72652063757272656e742060448201526374696d6560e01b6064820152608401610ca9565b600f541580611220575060008181526019602052604090205460ff16155b6112785760405162461bcd60e51b8152602060048201526024808201527f43616e6e6f7420626f6f747374726170207768656e207661756c7420697320726044820152636561647960e01b6064820152608401610ca9565b600f541561130757600f546000908152601b602052604090205460ff166113075760405162461bcd60e51b815260206004820152603f60248201527f43616e6e6f7420626f6f747374726170206265666f726520746865206375727260448201527f656e742065706f6368207761732065787069726564202620736574746c6564006064820152608401610ca9565b600081815260176020908152604080832042815560019081018890556019835292819020805460ff1916909317909255600f83905590518281527fb5ca1ca1b7b47549eb8af476f3ef702fc63bcd8b8c01dc163b009bb818f97997910160405180910390a160019250505b50919050565b6000611382613ae2565b6000805160206156df83398151915261139a81613c67565b600f54600090815260176020908152604091829020825160e081018452815481526001820154928101929092526002810154928201929092526003820154606082015260048201546080820152600582015460a082015260069091015460c0820152846114425760405162461bcd60e51b8152602060048201526016602482015275050657263656e746167652063616e6e6f7420626520360541b6044820152606401610ca9565b80602001514210156114965760405162461bcd60e51b815260206004820152601d60248201527f54696d65206973206e6f7420706173742065706f6368206578706972790000006044820152606401610ca9565b600f546000908152601a602052604090205460ff16156114f85760405162461bcd60e51b815260206004820152601d60248201527f45706f63682077617320616c7265616479207072652d657870697265640000006044820152606401610ca9565b600f546000908152601b602052604090205460ff16156115565760405162461bcd60e51b8152602060048201526019602482015278115c1bd8da081dd85cc8185b1c9958591e48195e1c1a5c9959603a1b6044820152606401610ca9565b611564620f42406064615427565b858260a00151611574919061540f565b11156115c25760405162461bcd60e51b815260206004820152601e60248201527f596f752063616e6e6f742073776170206d6f7265207468616e203130302500006044820152606401610ca9565b60006115d2620f42406064615427565b868360c001516115e29190615427565b6115ec919061545c565b9050600081156116cd5760006116028388613d5e565b90508060186000600f548152602001908152602001600020600401600082825461162c919061540f565b90915550600090508361164868056bc75e2d6310000084615427565b611652919061545c565b9050888560a00151611664919061540f565b61166e8a83615427565b8660a0015187608001516116829190615427565b61168c919061540f565b611696919061545c565b92508860176000600f54815260200190815260200160002060050160008282546116c0919061540f565b909155506116fb92505050565b6116d561197d565b90506116e5620f42406064615427565b600f546000908152601760205260409020600501555b600f5460009081526017602052604090206004015461173057600f546000908152601760205260409020600401819055611765565b600f5460009081526017602052604090206004015461174f9082613e05565b600f546000908152601760205260409020600401555b611773620f42406063615427565b600f5460009081526017602052604090206005015411156117ab57600f546000908152601a60205260409020805460ff191660011790555b6040513381527fe299059e3adc918e4f4ab456527f6220987ed7fce29c2bc9a416f9336822bdd29060200160405180910390a15060019695505050505050565b6060815167ffffffffffffffff81111561180757611807614ed4565b604051908082528060200260200182016040528015611830578160200160208202803683370190505b50905060005b82518110156113725761186183828151811061185457611854615470565b602002602001015161253c565b82828151811061187357611873615470565b60209081029190910101528061188881615486565b915050611836565b6060600061189d83612062565b90508067ffffffffffffffff8111156118b8576118b8614ed4565b6040519080825280602002602001820160405280156118e1578160200160208202803683370190505b50915060005b818110156119455760006118fb8583610f97565b6000818152601d602052604090205490915015611932578084838151811061192557611925615470565b6020026020010181815250505b508061193d81615486565b9150506118e7565b5050919050565b600061195781613c67565b61195f613e1b565b50565b610d4a83838360405180602001604052806000815250612a4c565b60135460408051632347816960e11b815290516000926001600160a01b03169163468f02d2916004808301926020929190829003018186803b1580156119c257600080fd5b505afa1580156119d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119fa91906154a1565b905090565b6000611a0a60095490565b8210611a6d5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610ca9565b60098281548110611a8057611a80615470565b90600052602060002001549050919050565b6000818152601d602090815260408083208151608081018352815480825260018301549482019490945260028201549281019290925260030154606082015290611b1a5760405162461bcd60e51b815260206004820152601960248201527824b73b30b634b21039ba3930b2323632903837b9b4ba34b7b760391b6044820152606401610ca9565b805160009081526017602052604090819020600401549082015181811115611b82576020830151611b4b83836154ba565b611b559190615427565b6060840151909450611b6783836154ba565b611b719190615427565b611b7b90856154ba565b9350611ba8565b6060830151611b9182846154ba565b611b9b9190615427565b611ba5908561540f565b93505b611bbb68056bc75e2d631000008561545c565b9350611bcb620f42406064615427565b602454611bd89086615427565b611be2919061545c565b611bec90856154ba565b95945050505050565b6000818152600360205260408120546001600160a01b031680610b755760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610ca9565b60155460009083906001600160a01b0316635b7b6d88878588611c7661197d565b611c7f8b612a84565b6040516001600160e01b031960e088901b1681529415156004860152602485019390935260448401919091526064830152608482015260a40160206040518083038186803b158015611cd057600080fd5b505afa158015611ce4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d0891906154a1565b611bec9190615427565b611d1a613ae2565b60026000541415611d3d5760405162461bcd60e51b8152600401610ca990615392565b6002600055611d4a613b2a565b33611d5482611bf5565b6001600160a01b031614611d9a5760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b21037bbb732b960991b6044820152606401610ca9565b6000818152601c6020526040902054611de85760405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b2103837b9b4ba34b7b760811b6044820152606401610ca9565b6000818152601c6020908152604091829020600201805460ff8082161560ff199092168217909255835185815291161515918101919091527fb5e95d468eadd79446f495b23ddf06bb55ff5717a821eb2cc57154a31cd5ee22910160405180910390a1506001600055565b6000611e5d613ae2565b6000805160206156df833981519152611e7581613c67565b600f54600090815260176020526040902060010154421015611ed95760405162461bcd60e51b815260206004820152601d60248201527f54696d65206973206e6f7420706173742065706f6368206578706972790000006044820152606401610ca9565b600f546000908152601a602052604090205460ff16611f365760405162461bcd60e51b8152602060048201526019602482015278115c1bd8da081a185cc81b9bdd081c1c994b595e1c1a5c9959603a1b6044820152606401610ca9565b600f546000908152601b602052604090205460ff1615611f945760405162461bcd60e51b8152602060048201526019602482015278115c1bd8da081dd85cc8185b1c9958591e48195e1c1a5c9959603a1b6044820152606401610ca9565b600f54600090815260186020526040902060030154611fd357600f546000908152601b60205260409020805460ff19166001908117909155915061202b565b60405162461bcd60e51b815260206004820152602760248201527f416c6c20736574746c656d656e74732068617665206e6f74206265656e2070726044820152661bd8d95cdcd95960ca1b6064820152608401610ca9565b6040513381527f6a4de20bb9fa8fea199f1022f29eff6be1752c446674d16913f2afc2b3c5a8a59060200160405180910390a15090565b60006001600160a01b0382166120cc5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610ca9565b506001600160a01b031660009081526004602052604090205490565b6000818152601c602090815260408083208151606081018352815480825260018301549482019490945260029091015460ff16151591810191909152906121415760405162461bcd60e51b8152600401610ca9906153c9565b80516000908152601760209081526040808320600201548451845260188352922060040154908301516121749190615427565b61217e919061545c565b9392505050565b6060600061219283612062565b90508067ffffffffffffffff8111156121ad576121ad614ed4565b6040519080825280602002602001820160405280156121d6578160200160208202803683370190505b50915060005b818110156119455760006121f08583610f97565b6000818152601c602052604090205490915015612227578084838151811061221a5761221a615470565b6020026020010181815250505b508061223281615486565b9150506121dc565b600061224581613c67565b61224d613e6d565b81156122815760405133904780156108fc02916000818181858888f1935050505015801561227f573d6000803e3d6000fd5b505b60005b838110156123595760008585838181106122a0576122a0615470565b90506020020160208101906122b59190614e03565b6040516370a0823160e01b81523060048201529091506123469033906001600160a01b038416906370a082319060240160206040518083038186803b1580156122fd57600080fd5b505afa158015612311573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233591906154a1565b6001600160a01b0384169190613c37565b508061235181615486565b915050612284565b5050505050565b600061236a613ae2565b6002600054141561238d5760405162461bcd60e51b8152600401610ca990615392565b600260005561239a613b2a565b600084116123ea5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74206465706f736974203020616d6f756e740000000000000000006044820152606401610ca9565b6000600f5460016123fb919061540f565b905084601760008381526020019081526020016000206002016000828254612423919061540f565b90915550506000818152601860205260408120600401805487929061244990849061540f565b90915550612458905083613eb6565b6040805160608101825283815260208082018981528815158385019081526000868152601c909352939091209151825551600182015590516002909101805460ff19169115159190911790556010549092506124bf906001600160a01b0316333088613ee0565b6040805182815260208101879052851515818301526001600160a01b038516606082015233608082015260a0810184905290517f14c0e56f4125d5707194bbf1beff49bb39b170a0f49574bcf25d8616f4df1cf69181900360c00190a15060016000559392505050565b600061253481613c67565b61195f613f18565b6000612546613ae2565b600260005414156125695760405162461bcd60e51b8152600401610ca990615392565b6002600055612576613b2a565b6000828152601d6020908152604091829020825160808101845281548082526001830154938201939093526002820154938101939093526003015460608301526125fe5760405162461bcd60e51b815260206004820152601960248201527824b73b30b634b21039ba3930b2323632903837b9b4ba34b7b760391b6044820152606401610ca9565b80516000908152601a602052604090205460ff1661265a5760405162461bcd60e51b8152602060048201526019602482015278115c1bd8da081a185cc81b9bdd081c1c994b595e1c1a5c9959603a1b6044820152606401610ca9565b600061266584611a92565b9050600061267285611bf5565b905061267d85613b90565b816126c15760405162461bcd60e51b815260206004820152601460248201527306275796572506e6c2063616e6e6f7420626520360641b6044820152606401610ca9565b60006126d1620f42406064615427565b6020546126de9085615427565b6126e8919061545c565b905060006001600160a01b03831633146127325761270a620f42406064615427565b6022546127179086615427565b612721919061545c565b905061272f81601f54613e05565b90505b61273c818361540f565b61274690856154ba565b85516000908152601860205260408120600301805492965060019290919061276f9084906154ba565b90915550819050612780838661540f565b61278a919061540f565b8551600090815260186020526040812060040180549091906127ad9084906154ba565b90915550506016546010546127cf916001600160a01b03918216911684613c37565b6010546127e6906001600160a01b03168486613c37565b6010546127fd906001600160a01b03163383613c37565b60408051888152602081018690526001600160a01b0385169133917fddd2b8bfe59e2aa6d76b0600fa7f6e161b9ece46b47a20197e2755899e7e8837910160405180910390a350506001600055509392505050565b6000918252600b602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060028054610b8a9061530f565b6000600260646128a3620f42406301e13380615427565b8585602154896128b39190615427565b6128bd9190615427565b6128c79190615427565b6128d1919061545c565b6128db919061545c565b6128e5919061545c565b949350505050565b61116e338383613f55565b600061290381613c67565b61116e82614024565b600061291781613c67565b8151601080546001600160a01b039283166001600160a01b0319918216179091556020840151601180549184169183169190911790556040808501516012805491851691841691909117905560608501516013805491851691841691909117905560808501516014805491851691841691909117905560a08501516015805491851691841691909117905560c08501516016805491909416921691909117909155517f488865203db2c6efd677f2757b6433d6fd6f452390e796b6719252b8588fcdf990612a4090849081516001600160a01b03908116825260208084015182169083015260408084015182169083015260608084015182169083015260808084015182169083015260a08381015182169083015260c092830151169181019190915260e00190565b60405180910390a15050565b612a5633836138bd565b612a725760405162461bcd60e51b8152600401610ca990615344565b612a7e84848484614127565b50505050565b60145460405163c189c19b60e01b8152600481018390526000916001600160a01b03169063c189c19b9060240160206040518083038186803b158015612ac957600080fd5b505afa158015612add573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b7591906154a1565b6000612b0c81613c67565b61116e8261415a565b6060612b20826137f0565b6000612b3760408051602081019091526000815290565b90506000815111612b57576040518060200160405280600081525061217e565b80612b618461420b565b604051602001612b729291906154d1565b6040516020818303038152906040529392505050565b600080612b9481613c67565b610e108311612bf65760405162461bcd60e51b815260206004820152602860248201527f426c61636b6f757420706572696f64206d757374206265206d6f726520746861604482015267371018903437bab960c11b6064820152608401610ca9565b60238390556040518381527f32e6db6aab294383bb2b48c5adfb1100050e096a4ce0eed5b7568604fc09f10b9060200160405180910390a150600192915050565b6000828152600b6020526040902060010154612c5281613c67565b610d4a8383613cf7565b6060815167ffffffffffffffff811115612c7857612c78614ed4565b604051908082528060200260200182016040528015612ca1578160200160208202803683370190505b50905060005b825181101561137257612cd2838281518110612cc557612cc5615470565b60200260200101516132fe565b828281518110612ce457612ce4615470565b602090810291909101015280612cf981615486565b915050612ca7565b6000612d0b613ae2565b60026000541415612d2e5760405162461bcd60e51b8152600401610ca990615392565b6002600055612d3b613b2a565b6000600f5411612d7d5760405162461bcd60e51b815260206004820152600d60248201526c092dcecc2d8d2c840cae0dec6d609b1b6044820152606401610ca9565b662386f26fc100008411612dc45760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606401610ca9565b602354600f54600090815260176020526040902060010154612de691906154ba565b4210612e435760405162461bcd60e51b815260206004820152602660248201527f43616e6e6f7420707572636861736520647572696e6720626c61636b6f7574206044820152651c195c9a5bd960d21b6064820152608401610ca9565b6000612e4d61197d565b600f5460009081526017602052604081206001015491925090612e719042906154ba565b905068056bc75e2d63100000612e878784615427565b612e91919061545c565b600f54600090815260176020526040902060030154612eba9068056bc75e2d631000009061545c565b600f54600090815260176020526040902060020154612ed991906154ba565b1015612f315760405162461bcd60e51b815260206004820152602160248201527f4e6f7420656e6f756768204150206c697175696469747920617661696c61626c6044820152606560f81b6064820152608401610ca9565b6000612f6668056bc75e2d631000006002612f4c8a87615427565b612f56919061545c565b612f60919061545c565b87614309565b905068056bc75e2d631000006002612f7e8986615427565b612f88919061545c565b612f92919061545c565b600f5460009081526018602052604081206004018054909190612fb69084906154ba565b9091555060009050612fc9826002615427565b612fd38986615427565b612fdd919061545c565b90508160176000600f5481526020019081526020016000206006016000828254613007919061540f565b909155506130189050826002615427565b6130229082615427565b600f546000908152601760205260408120600301805490919061304690849061540f565b909155506000905061307960018361305f866002615427565b600f54600090815260176020526040902060010154611c55565b905060006130928361308c866002615427565b8761288c565b600f546000908152601860205260408120805492935084929091906130b890849061540f565b9091555050600f54600090815260186020526040812060010180548392906130e190849061540f565b909155506130f29050846002615427565b600f546000908152601860205260408120600201805490919061311690849061540f565b9091555050600f54600090815260186020526040812060030180546001929061314090849061540f565b9091555061314f905088613eb6565b96506040518060800160405280600f5481526020018560026131719190615427565b81526020808201869052604091820187905260008a8152601d8252828120845181559184015160018301559183015160028201556060909201516003909201919091556131ca68056bc75e2d63100000620f4240615427565b6131d5906064615427565b601e546131e29085615427565b6131ec919061545c565b905061323033308368056bc75e2d63100000613208878961540f565b613212919061545c565b61321c919061540f565b6010546001600160a01b0316929190613ee0565b60165460105461324d916001600160a01b03918216911683613c37565b68056bc75e2d63100000613261838561540f565b61326b919061545c565b600f546000908152601860205260408120600401805490919061328f90849061540f565b909155507f12cb4648cf3058b17ceeb33e579f8b0bc269fe0843f3900b8e24b6c54871703c905089896132c2858761540f565b604080516001600160a01b03909416845260208401929092529082015260600160405180910390a1505060016000555093979650505050505050565b6000613308613ae2565b6002600054141561332b5760405162461bcd60e51b8152600401610ca990615392565b6002600055613338613b2a565b6000828152601c60209081526040918290208251606081018452815481526001820154928101929092526002015460ff161515918101829052906133be5760405162461bcd60e51b815260206004820152601760248201527f526f6c6c6f766572206e6f7420617574686f72697a65640000000000000000006044820152606401610ca9565b80516133dc5760405162461bcd60e51b8152600401610ca9906153c9565b80516000908152601b602052604090205460ff166134345760405162461bcd60e51b8152602060048201526015602482015274115c1bd8da081a185cc81b9bdd08195e1c1a5c9959605a1b6044820152606401610ca9565b600061343f846120e8565b9050600061344c85611bf5565b905061345785613b90565b8161349e5760405162461bcd60e51b81526020600482015260176024820152760577269746520706f736974696f6e20706e6c206973203604c1b6044820152606401610ca9565b60408051868152602081018490526001600160a01b038316917ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568910160405180910390a26000600f5460016134f3919061540f565b90508260176000838152602001908152602001600020600201600082825461351b919061540f565b90915550506000818152601860205260408120600401805485929061354190849061540f565b90915550613550905082613eb6565b6040805160608082018352848252602080830188815260018486018181526000888152601c85528790209551865591518582015590516002909401805460ff1916941515949094179093558351868152908101889052928301919091526001600160a01b038516908201819052608082015260a081018290529095507f14c0e56f4125d5707194bbf1beff49bb39b170a0f49574bcf25d8616f4df1cf69060c00160405180910390a150506001600055509092915050565b600061361381613c67565b600082116136335760405162461bcd60e51b8152600401610ca990615500565b60248290556040518281527fe4d44cc62a77ab305c1c324248b29e91f621d65b1c231ee984dd6800b2ff7b4690602001612a40565b600061367381613c67565b600082116136935760405162461bcd60e51b8152600401610ca990615500565b60218290556040518281527fc5c758ec4001ae2dfceeb8a99ff59eacf17b62ca95bae713257b9dd494b9a84090602001612a40565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e9060440160206040518083038186803b15801561371457600080fd5b505afa158015613728573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061374c91906154a1565b613756919061540f565b6040516001600160a01b038516602482015260448101829052909150612a7e90859063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614362565b60606128e58484600085614434565b60006001600160e01b03198216637965db0b60e01b1480610b755750610b7582614565565b6000818152600360205260409020546001600160a01b031661195f5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610ca9565b600081815260056020526040902080546001600160a01b0319166001600160a01b038416908117909155819061388482611bf5565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806138c983611bf5565b9050806001600160a01b0316846001600160a01b0316148061391057506001600160a01b0380821660009081526006602090815260408083209388168352929052205460ff165b806128e55750836001600160a01b031661392984610c0d565b6001600160a01b031614949350505050565b826001600160a01b031661394e82611bf5565b6001600160a01b0316146139b25760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610ca9565b6001600160a01b038216613a145760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610ca9565b613a1f83838361458a565b613a2a60008261384f565b6001600160a01b0383166000908152600460205260408120805460019290613a539084906154ba565b90915550506001600160a01b0382166000908152600460205260408120805460019290613a8190849061540f565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600c5460ff1615613b285760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610ca9565b565b333214613b2857336000908152600d602052604090205460ff16613b285760405162461bcd60e51b815260206004820152601c60248201527f436f6e7472616374206d7573742062652077686974656c6973746564000000006044820152606401610ca9565b6000613b9b82611bf5565b9050613ba98160008461458a565b613bb460008361384f565b6001600160a01b0381166000908152600460205260408120805460019290613bdd9084906154ba565b909155505060008281526003602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6040516001600160a01b038316602482015260448101829052610d4a90849063a9059cbb60e01b90606401613785565b61195f8133614595565b613c7b8282612852565b61116e576000828152600b602090815260408083206001600160a01b03851684529091529020805460ff19166001179055613cb33390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b613d018282612852565b1561116e576000828152600b602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60125460115460105460405163b91ac49560e01b81526001600160a01b0392831660048201529082166024820152604481018590526000606482018190526084820185905292919091169063b91ac4959060a4015b602060405180830381600087803b158015613dcd57600080fd5b505af1158015613de1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217e91906154a1565b6000818310613e14578161217e565b5090919050565b613e23613e6d565b600c805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600c5460ff16613b285760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610ca9565b6000613ec1600e5490565b9050613ed1600e80546001019055565b613edb82826145f9565b919050565b6040516001600160a01b0380851660248301528316604482015260648101829052612a7e9085906323b872dd60e01b90608401613785565b613f20613ae2565b600c805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613e503390565b816001600160a01b0316836001600160a01b03161415613fb75760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610ca9565b6001600160a01b03838116600081815260066020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b803b6140725760405162461bcd60e51b815260206004820152601a60248201527f41646472657373206d757374206265206120636f6e74726163740000000000006044820152606401610ca9565b6001600160a01b0381166000908152600d602052604090205460ff16156140db5760405162461bcd60e51b815260206004820152601c60248201527f436f6e747261637420616c72656164792077686974656c6973746564000000006044820152606401610ca9565b6001600160a01b0381166000818152600d6020526040808220805460ff19166001179055517ffbd3cde7ff522a917e485c8ed2a6e87590887ab399f5ac312307903f498543079190a250565b61413284848461393b565b61413e84848484614613565b612a7e5760405162461bcd60e51b8152600401610ca990615543565b6001600160a01b0381166000908152600d602052604090205460ff166141c25760405162461bcd60e51b815260206004820152601860248201527f436f6e7472616374206e6f742077686974656c697374656400000000000000006044820152606401610ca9565b6001600160a01b0381166000818152600d6020526040808220805460ff19169055517f8e81447740597754af5db3e176253a36f7981a9549f48ace3f0cb233913f9d859190a250565b60608161422f5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115614259578061424381615486565b91506142529050600a8361545c565b9150614233565b60008167ffffffffffffffff81111561427457614274614ed4565b6040519080825280601f01601f19166020018201604052801561429e576020820181803683370190505b5090505b84156128e5576142b36001836154ba565b91506142c0600a86615595565b6142cb90603061540f565b60f81b8183815181106142e0576142e0615470565b60200101906001600160f81b031916908160001a905350614302600a8661545c565b94506142a2565b60125460105460115460405163b91ac49560e01b81526001600160a01b0392831660048201529082166024820152604481018590526000606482018190526084820185905292919091169063b91ac4959060a401613db3565b60006143b7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166137bc9092919063ffffffff16565b805190915015610d4a57808060200190518101906143d591906155a9565b610d4a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610ca9565b6060824710156144955760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610ca9565b6001600160a01b0385163b6144ec5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610ca9565b600080866001600160a01b0316858760405161450891906155c6565b60006040518083038185875af1925050503d8060008114614545576040519150601f19603f3d011682016040523d82523d6000602084013e61454a565b606091505b509150915061455a82828661471d565b979650505050505050565b60006001600160e01b0319821663780e9d6360e01b1480610b755750610b7582614756565b610d4a8383836147a6565b61459f8282612852565b61116e576145b7816001600160a01b0316601461485e565b6145c283602061485e565b6040516020016145d39291906155e2565b60408051601f198184030181529082905262461bcd60e51b8252610ca991600401614d96565b61116e8282604051806020016040528060008152506149fa565b60006001600160a01b0384163b1561471557604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614657903390899088908890600401615657565b602060405180830381600087803b15801561467157600080fd5b505af19250505080156146a1575060408051601f3d908101601f1916820190925261469e91810190615694565b60015b6146fb573d8080156146cf576040519150601f19603f3d011682016040523d82523d6000602084013e6146d4565b606091505b5080516146f35760405162461bcd60e51b8152600401610ca990615543565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506128e5565b5060016128e5565b6060831561472c57508161217e565b82511561473c5782518084602001fd5b8160405162461bcd60e51b8152600401610ca99190614d96565b60006001600160e01b031982166380ac58cd60e01b148061478757506001600160e01b03198216635b5e139f60e01b145b80610b7557506301ffc9a760e01b6001600160e01b0319831614610b75565b6001600160a01b038316614801576147fc81600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b614824565b816001600160a01b0316836001600160a01b031614614824576148248382614a2d565b6001600160a01b03821661483b57610d4a81614aca565b826001600160a01b0316826001600160a01b031614610d4a57610d4a8282614b79565b6060600061486d836002615427565b61487890600261540f565b67ffffffffffffffff81111561489057614890614ed4565b6040519080825280601f01601f1916602001820160405280156148ba576020820181803683370190505b509050600360fc1b816000815181106148d5576148d5615470565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061490457614904615470565b60200101906001600160f81b031916908160001a9053506000614928846002615427565b61493390600161540f565b90505b60018111156149ab576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061496757614967615470565b1a60f81b82828151811061497d5761497d615470565b60200101906001600160f81b031916908160001a90535060049490941c936149a4816156b1565b9050614936565b50831561217e5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610ca9565b614a048383614bbd565b614a116000848484614613565b610d4a5760405162461bcd60e51b8152600401610ca990615543565b60006001614a3a84612062565b614a4491906154ba565b600083815260086020526040902054909150808214614a97576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b600954600090614adc906001906154ba565b6000838152600a602052604081205460098054939450909284908110614b0457614b04615470565b906000526020600020015490508060098381548110614b2557614b25615470565b6000918252602080832090910192909255828152600a90915260408082208490558582528120556009805480614b5d57614b5d6156c8565b6001900381819060005260206000200160009055905550505050565b6000614b8483612062565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b6001600160a01b038216614c135760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610ca9565b6000818152600360205260409020546001600160a01b031615614c785760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610ca9565b614c846000838361458a565b6001600160a01b0382166000908152600460205260408120805460019290614cad90849061540f565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160e01b03198116811461195f57600080fd5b600060208284031215614d3357600080fd5b813561217e81614d0b565b60005b83811015614d59578181015183820152602001614d41565b83811115612a7e5750506000910152565b60008151808452614d82816020860160208601614d3e565b601f01601f19169290920160200192915050565b60208152600061217e6020830184614d6a565b600060208284031215614dbb57600080fd5b5035919050565b80356001600160a01b0381168114613edb57600080fd5b60008060408385031215614dec57600080fd5b614df583614dc2565b946020939093013593505050565b600060208284031215614e1557600080fd5b61217e82614dc2565b600080600060608486031215614e3357600080fd5b614e3c84614dc2565b9250614e4a60208501614dc2565b9150604084013590509250925092565b60008060408385031215614e6d57600080fd5b82359150614e7d60208401614dc2565b90509250929050565b600080600060608486031215614e9b57600080fd5b505081359360208301359350604090920135919050565b60008060408385031215614ec557600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614f1357614f13614ed4565b604052919050565b60006020808385031215614f2e57600080fd5b823567ffffffffffffffff80821115614f4657600080fd5b818501915085601f830112614f5a57600080fd5b813581811115614f6c57614f6c614ed4565b8060051b9150614f7d848301614eea565b8181529183018401918481019088841115614f9757600080fd5b938501935b83851015614fb557843582529385019390850190614f9c565b98975050505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614ff957835183529284019291840191600101614fdd565b50909695505050505050565b801515811461195f57600080fd5b6000806000806080858703121561502957600080fd5b843561503481615005565b966020860135965060408601359560600135945092505050565b60008060006040848603121561506357600080fd5b833567ffffffffffffffff8082111561507b57600080fd5b818601915086601f83011261508f57600080fd5b81358181111561509e57600080fd5b8760208260051b85010111156150b357600080fd5b602092830195509350508401356150c981615005565b809150509250925092565b6000806000606084860312156150e957600080fd5b8335925060208401356150fb81615005565b915061510960408501614dc2565b90509250925092565b6000806040838503121561512557600080fd5b61512e83614dc2565b9150602083013561513e81615005565b809150509250929050565b600060e0828403121561515b57600080fd5b60405160e0810181811067ffffffffffffffff8211171561517e5761517e614ed4565b60405261518a83614dc2565b815261519860208401614dc2565b60208201526151a960408401614dc2565b60408201526151ba60608401614dc2565b60608201526151cb60808401614dc2565b60808201526151dc60a08401614dc2565b60a08201526151ed60c08401614dc2565b60c08201529392505050565b6000806000806080858703121561520f57600080fd5b61521885614dc2565b93506020615227818701614dc2565b935060408601359250606086013567ffffffffffffffff8082111561524b57600080fd5b818801915088601f83011261525f57600080fd5b81358181111561527157615271614ed4565b615283601f8201601f19168501614eea565b9150808252898482850101111561529957600080fd5b808484018584013760008482840101525080935050505092959194509250565b600080604083850312156152cc57600080fd5b6152d583614dc2565b9150614e7d60208401614dc2565b6000806000606084860312156152f857600080fd5b833592506020840135915061510960408501614dc2565b600181811c9082168061532357607f821691505b6020821081141561137257634e487b7160e01b600052602260045260246000fd5b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526016908201527524b73b30b634b2103bb934ba32903837b9b4ba34b7b760511b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60008219821115615422576154226153f9565b500190565b6000816000190483118215151615615441576154416153f9565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261546b5761546b615446565b500490565b634e487b7160e01b600052603260045260246000fd5b600060001982141561549a5761549a6153f9565b5060010190565b6000602082840312156154b357600080fd5b5051919050565b6000828210156154cc576154cc6153f9565b500390565b600083516154e3818460208801614d3e565b8351908301906154f7818360208801614d3e565b01949350505050565b60208082526023908201527f46756e64696e672072617465206d75737420626520677265617465722074686160408201526206e20360ec1b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6000826155a4576155a4615446565b500690565b6000602082840312156155bb57600080fd5b815161217e81615005565b600082516155d8818460208701614d3e565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161561a816017850160208801614d3e565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161564b816028840160208801614d3e565b01602801949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061568a90830184614d6a565b9695505050505050565b6000602082840312156156a657600080fd5b815161217e81614d0b565b6000816156c0576156c06153f9565b506000190190565b634e487b7160e01b600052603160045260246000fdfe241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08a26469706673582212207d03e8cdca424291abcf53fa0968b1e199002c42cb6fc739a64dc8a98b5900ec64736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000ff970a61a04b1ca14834a43f5de4533ebddb5cc800000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab1000000000000000000000000b854384baf57716df2231af260fcc9a548d2726c00000000000000000000000019e6ee4c2cbe7bcc4cd1ef0bcf7e764fece23cc60000000000000000000000007745370dfcc3780dd7675995b529d4e24960c0150000000000000000000000002b99e3d67dad973c1b9747da742b7e26c8bdd67b00000000000000000000000055594cce8cc0014ea08c49fd820d731308f204c100000000000000000000000000000000000000000000000000000000000000174554482041746c616e746963205374726164646c65203200000000000000000000000000000000000000000000000000000000000000000000000000000000174554482d41544c414e5449432d5354524144444c452d32000000000000000000
-----Decoded View---------------
Arg [0] : _name (string): ETH Atlantic Straddle 2
Arg [1] : _symbol (string): ETH-ATLANTIC-STRADDLE-2
Arg [2] : _addresses (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
-----Encoded View---------------
13 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [2] : 000000000000000000000000ff970a61a04b1ca14834a43f5de4533ebddb5cc8
Arg [3] : 00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab1
Arg [4] : 000000000000000000000000b854384baf57716df2231af260fcc9a548d2726c
Arg [5] : 00000000000000000000000019e6ee4c2cbe7bcc4cd1ef0bcf7e764fece23cc6
Arg [6] : 0000000000000000000000007745370dfcc3780dd7675995b529d4e24960c015
Arg [7] : 0000000000000000000000002b99e3d67dad973c1b9747da742b7e26c8bdd67b
Arg [8] : 00000000000000000000000055594cce8cc0014ea08c49fd820d731308f204c1
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000017
Arg [10] : 4554482041746c616e746963205374726164646c652032000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000017
Arg [12] : 4554482d41544c414e5449432d5354524144444c452d32000000000000000000
Deployed ByteCode Sourcemap
83723:32279:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;115772:227;;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;115772:227:0;;;;;;;;23733:100;;;:::i;:::-;;;;;;;:::i;25343:221::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1692:32:1;;;1674:51;;1662:2;1647:18;25343:221:0;1528:203:1;24860:417:0;;;;;;:::i;:::-;;:::i;:::-;;81816:188;;;;;;:::i;:::-;81943:17;81988:8;;;81816:188;39125:113;39213:10;:17;39125:113;;;2510:25:1;;;2498:2;2483:18;39125:113:0;2364:177:1;26175:373:0;;;;;;:::i;:::-;;:::i;70845:181::-;;;;;;:::i;:::-;70964:7;70996:12;;;:6;:12;;;;;:22;;;;70845:181;85584:41;;;;;;93518:736;;;;;;:::i;:::-;;:::i;71336:188::-;;;;;;:::i;:::-;;:::i;38706:343::-;;;;;;:::i;:::-;;:::i;112942:740::-;;;;;;:::i;:::-;;:::i;85780:66::-;;;;;;72562:287;;;;;;:::i;:::-;;:::i;106309:1031::-;;;;;;:::i;:::-;;:::i;80264:52::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;107566:2534;;;;;;:::i;:::-;;:::i;99757:260::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;105690:481::-;;;;;;:::i;:::-;;:::i;113954:86::-;;;:::i;84566:44::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;26619:185;;;;;;:::i;:::-;;:::i;101512:142::-;;;:::i;84686:49::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;39315:320;;;;;;:::i;:::-;;:::i;103942:1038::-;;;;;;:::i;:::-;;:::i;85248:50::-;;85294:4;85248:50;;78999:86;79070:7;;;;78999:86;;23394:272;;;;;;:::i;:::-;;:::i;102264:414::-;;;;;;:::i;:::-;;:::i;92980:373::-;;;;;;:::i;:::-;;:::i;110164:726::-;;;:::i;84311:46::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6968:25:1;;;7024:2;7009:18;;7002:34;;;;7052:18;;;7045:34;;;;7110:2;7095:18;;7088:34;;;;7153:3;7138:19;;7131:35;7197:3;7182:19;;7175:35;7241:3;7226:19;;7219:35;6955:3;6940:19;84311:46:0;6653:607:1;23038:294:0;;;;;;:::i;:::-;;:::i;103357:486::-;;;;;;:::i;:::-;;:::i;84086:27::-;;;;;;105096:475;;;;;;:::i;:::-;;:::i;115009:464::-;;;;;;:::i;:::-;;:::i;89962:969::-;;;;;;:::i;:::-;;:::i;113786:82::-;;;:::i;98022:1614::-;;;;;;:::i;:::-;;:::i;84977:61::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8639:25:1;;;8695:2;8680:18;;8673:34;;;;8723:18;;;8716:34;8781:2;8766:18;;8759:34;8626:3;8611:19;84977:61:0;8408:391:1;69255:197:0;;;;;;:::i;:::-;;:::i;86009:57::-;;;;;;84807:46;;;;;;:::i;:::-;;;;;;;;;;;;;;;;23902:104;;;:::i;84428:68::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9063:25:1;;;9119:2;9104:18;;9097:34;;;;9147:18;;;9140:34;;;;9205:2;9190:18;;9183:34;9248:3;9233:19;;9226:35;9050:3;9035:19;84428:68:0;8804:463:1;102881:334:0;;;;;;:::i;:::-;;:::i;68284:49::-;;68329:4;68284:49;;25636:187;;;;;;:::i;:::-;;:::i;114233:165::-;;;;;;:::i;:::-;;:::i;111069:193::-;;;;;;:::i;:::-;;:::i;26875:360::-;;;;;;:::i;:::-;;:::i;85661:56::-;;;;;;85154:43;;85194:3;85154:43;;101774:209;;;;;;:::i;:::-;;:::i;114598:175::-;;;;;;:::i;:::-;;:::i;24077:378::-;;;;;;:::i;:::-;;:::i;85920:51::-;;;;;;111371:337;;;;;;:::i;:::-;;:::i;71817:190::-;;;;;;:::i;:::-;;:::i;85490:54::-;;;;;;84243:26;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;84243:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;11839:15:1;;;11821:34;;11891:15;;;11886:2;11871:18;;11864:43;11943:15;;;11923:18;;;11916:43;;;;11995:15;;;11990:2;11975:18;;11968:43;12048:15;;12042:3;12027:19;;12020:44;12101:15;;11801:3;12080:19;;12073:44;12154:15;;;12148:3;12133:19;;12126:44;11770:3;11755:19;84243:26:0;11468:708:1;92602:276:0;;;;;;:::i;:::-;;:::i;25894:214::-;;;;;;:::i;:::-;-1:-1:-1;;;;;26065:25:0;;;26036:4;26065:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;25894:214;94540:3357;;;;;;:::i;:::-;;:::i;84143:64::-;;-1:-1:-1;;;;;;;;;;;84143:64:0;;84886:55;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12969:25:1;;;13025:2;13010:18;;13003:34;;;;13080:14;13073:22;13053:18;;;13046:50;12957:2;12942:18;84886:55:0;12773:329:1;91255:1191:0;;;;;;:::i;:::-;;:::i;112322:320::-;;;;;;:::i;:::-;;:::i;111874:292::-;;;;;;:::i;:::-;;:::i;85419:39::-;;;;;;115772:227;115926:4;115955:36;115979:11;115955:23;:36::i;:::-;115948:43;115772:227;-1:-1:-1;;115772:227:0:o;23733:100::-;23787:13;23820:5;23813:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23733:100;:::o;25343:221::-;25464:7;25489:23;25504:7;25489:14;:23::i;:::-;-1:-1:-1;25532:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;25532:24:0;;25343:221::o;24860:417::-;24941:13;24957:23;24972:7;24957:14;:23::i;:::-;24941:39;;25005:5;-1:-1:-1;;;;;24999:11:0;:2;-1:-1:-1;;;;;24999:11:0;;;24991:57;;;;-1:-1:-1;;;24991:57:0;;13694:2:1;24991:57:0;;;13676:21:1;13733:2;13713:18;;;13706:30;13772:34;13752:18;;;13745:62;-1:-1:-1;;;13823:18:1;;;13816:31;13864:19;;24991:57:0;;;;;;;;;17971:10;-1:-1:-1;;;;;25083:21:0;;;;:62;;-1:-1:-1;25108:37:0;25125:5;17971:10;25894:214;:::i;25108:37::-;25061:174;;;;-1:-1:-1;;;25061:174:0;;14096:2:1;25061:174:0;;;14078:21:1;14135:2;14115:18;;;14108:30;14174:34;14154:18;;;14147:62;14245:32;14225:18;;;14218:60;14295:19;;25061:174:0;13894:426:1;25061:174:0;25248:21;25257:2;25261:7;25248:8;:21::i;:::-;24930:347;24860:417;;:::o;26175:373::-;26384:41;17971:10;26417:7;26384:18;:41::i;:::-;26362:137;;;;-1:-1:-1;;;26362:137:0;;;;;;;:::i;:::-;26512:28;26522:4;26528:2;26532:7;26512:9;:28::i;93518:736::-;93629:24;78604:19;:17;:19::i;:::-;76543:1:::1;77141:7;;:19;;77133:63;;;;-1:-1:-1::0;;;77133:63:0::1;;;;;;;:::i;:::-;76543:1;77274:7;:18:::0;93671:19:::2;:17;:19::i;:::-;93724:10;93709:11;93717:2:::0;93709:7:::2;:11::i;:::-;-1:-1:-1::0;;;;;93709:25:0::2;;93701:51;;;::::0;-1:-1:-1;;;93701:51:0;;15302:2:1;93701:51:0::2;::::0;::::2;15284:21:1::0;15341:2;15321:18;;;15314:30;-1:-1:-1;;;15360:18:1;;;15353:43;15413:18;;93701:51:0::2;15100:337:1::0;93701:51:0::2;93765:29;93797:18:::0;;;:14:::2;:18;::::0;;;;;;;;93765:50;;::::2;::::0;::::2;::::0;;;;;;;::::2;::::0;::::2;::::0;;;::::2;::::0;;;;::::2;::::0;;::::2;::::0;::::2;;;;::::0;;;;;;;93828:54:::2;;;;-1:-1:-1::0;;;93828:54:0::2;;;;;;;:::i;:::-;93916:14:::0;;93901:30:::2;::::0;;;:14:::2;:30;::::0;;;;;::::2;;93893:63;;;::::0;-1:-1:-1;;;93893:63:0;;15995:2:1;93893:63:0::2;::::0;::::2;15977:21:1::0;16034:2;16014:18;;;16007:30;-1:-1:-1;;;16053:18:1;;;16046:50;16113:18;;93893:63:0::2;15793:344:1::0;93893:63:0::2;93988:29;94014:2;93988:25;:29::i;:::-;93969:48;;94030:9;94036:2;94030:5;:9::i;:::-;94060:21:::0;94052:57:::2;;;::::0;-1:-1:-1;;;94052:57:0;;16344:2:1;94052:57:0::2;::::0;::::2;16326:21:1::0;16383:2;16363:18;;;16356:30;-1:-1:-1;;;16402:18:1;;;16395:53;16465:18;;94052:57:0::2;16142:347:1::0;94052:57:0::2;94129:9;:13:::0;94122:64:::2;::::0;-1:-1:-1;;;;;94129:13:0::2;94157:10;94169:16:::0;94122:34:::2;:64::i;:::-;94204:42;::::0;;16668:25:1;;;16724:2;16709:18;;16702:34;;;94213:10:0::2;::::0;94204:42:::2;::::0;16641:18:1;94204:42:0::2;;;;;;;-1:-1:-1::0;76499:1:0::1;77453:7;:22:::0;93518:736;;-1:-1:-1;93518:736:0:o;71336:188::-;70964:7;70996:12;;;:6;:12;;;;;:22;;;68775:16;68786:4;68775:10;:16::i;:::-;71491:25:::1;71502:4;71508:7;71491:10;:25::i;38706:343::-:0;38848:7;38903:23;38920:5;38903:16;:23::i;:::-;38895:5;:31;38873:124;;;;-1:-1:-1;;;38873:124:0;;16949:2:1;38873:124:0;;;16931:21:1;16988:2;16968:18;;;16961:30;17027:34;17007:18;;;17000:62;-1:-1:-1;;;17078:18:1;;;17071:41;17129:19;;38873:124:0;16747:407:1;38873:124:0;-1:-1:-1;;;;;;39015:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;38706:343::o;112942:740::-;68329:4;68775:16;68329:4;68775:10;:16::i;:::-;113190:1:::1;113168:19;:23;:69;;;;;113236:1;113212:21;:25;113168:69;:121;;;;;113288:1;113258:27;:31;113168:121;113146:202;;;::::0;-1:-1:-1;;;113146:202:0;;17361:2:1;113146:202:0::1;::::0;::::1;17343:21:1::0;17400:2;17380:18;;;17373:30;17439:33;17419:18;;;17412:61;17490:18;;113146:202:0::1;17159:355:1::0;113146:202:0::1;113359:18;:40:::0;;;113410:20:::1;:44:::0;;;113465:26:::1;:56:::0;;;113537:137:::1;::::0;;17721:25:1;;;17762:18;;;17755:34;;;17805:18;;17798:34;;;113537:137:0::1;::::0;17709:2:1;17694:18;113537:137:0::1;;;;;;;112942:740:::0;;;;:::o;72562:287::-;-1:-1:-1;;;;;72704:23:0;;17971:10;72704:23;72682:120;;;;-1:-1:-1;;;72682:120:0;;18045:2:1;72682:120:0;;;18027:21:1;18084:2;18064:18;;;18057:30;18123:34;18103:18;;;18096:62;-1:-1:-1;;;18174:18:1;;;18167:45;18229:19;;72682:120:0;17843:411:1;72682:120:0;72815:26;72827:4;72833:7;72815:11;:26::i;:::-;72562:287;;:::o;106309:1031::-;106435:4;78604:19;:17;:19::i;:::-;-1:-1:-1;;;;;;;;;;;68775:16:0::1;68786:4;68775:10;:16::i;:::-;106457:17:::2;106477:12;;106492:1;106477:16;;;;:::i;:::-;106457:36;;106544:6;106526:15;:24;106504:110;;;::::0;-1:-1:-1;;;106504:110:0;;18726:2:1;106504:110:0::2;::::0;::::2;18708:21:1::0;18765:2;18745:18;;;18738:30;18804:34;18784:18;;;18777:62;-1:-1:-1;;;18855:18:1;;;18848:34;18899:19;;106504:110:0::2;18524:400:1::0;106504:110:0::2;106647:12;::::0;:17;;:45:::2;;-1:-1:-1::0;106669:23:0::2;::::0;;;:12:::2;:23;::::0;;;;;::::2;;106668:24;106647:45;106625:131;;;::::0;-1:-1:-1;;;106625:131:0;;19131:2:1;106625:131:0::2;::::0;::::2;19113:21:1::0;19170:2;19150:18;;;19143:30;19209:34;19189:18;;;19182:62;-1:-1:-1;;;19260:18:1;;;19253:34;19304:19;;106625:131:0::2;18929:400:1::0;106625:131:0::2;106771:12;::::0;:16;106767:202:::2;;106845:12;::::0;106830:28:::2;::::0;;;:14:::2;:28;::::0;;;;;::::2;;106804:153;;;::::0;-1:-1:-1;;;106804:153:0;;19536:2:1;106804:153:0::2;::::0;::::2;19518:21:1::0;19575:2;19555:18;;;19548:30;19614:34;19594:18;;;19587:62;19685:33;19665:18;;;19658:61;19736:19;;106804:153:0::2;19334:427:1::0;106804:153:0::2;107018:20;::::0;;;:9:::2;:20;::::0;;;;;;;107051:15:::2;107018:48:::0;;107077:27:::2;::::0;;::::2;:36:::0;;;107166:12:::2;:23:::0;;;;;;:30;;-1:-1:-1;;107166:30:0::2;::::0;;::::2;::::0;;;107246:12:::2;:24:::0;;;107288:20;;2510:25:1;;;107288:20:0::2;::::0;2483:18:1;107288:20:0::2;;;;;;;107328:4;107321:11;;;68802:1;78634::::1;106309:1031:::0;;;:::o;107566:2534::-;107720:4;78604:19;:17;:19::i;:::-;-1:-1:-1;;;;;;;;;;;68775:16:0::1;68786:4;68775:10;:16::i;:::-;107776:12:::2;::::0;107742:21:::2;107766:23:::0;;;:9:::2;:23;::::0;;;;;;;;107742:47;;::::2;::::0;::::2;::::0;;;;;;::::2;::::0;::::2;::::0;;;::::2;::::0;;;;::::2;::::0;::::2;::::0;;;;;;;;::::2;::::0;::::2;::::0;;;;;::::2;::::0;::::2;::::0;;;;;::::2;::::0;::::2;::::0;;;;;::::2;::::0;;::::2;::::0;;;;;107808:14;107800:49:::2;;;::::0;-1:-1:-1;;;107800:49:0;;19968:2:1;107800:49:0::2;::::0;::::2;19950:21:1::0;20007:2;19987:18;;;19980:30;-1:-1:-1;;;20026:18:1;;;20019:52;20088:18;;107800:49:0::2;19766:346:1::0;107800:49:0::2;107901:4;:11;;;107882:15;:30;;107860:109;;;::::0;-1:-1:-1;;;107860:109:0;;20319:2:1;107860:109:0::2;::::0;::::2;20301:21:1::0;20358:2;20338:18;;;20331:30;20397:31;20377:18;;;20370:59;20446:18;;107860:109:0::2;20117:353:1::0;107860:109:0::2;108021:12;::::0;108003:31:::2;::::0;;;:17:::2;:31;::::0;;;;;::::2;;108002:32;107980:111;;;::::0;-1:-1:-1;;;107980:111:0;;20677:2:1;107980:111:0::2;::::0;::::2;20659:21:1::0;20716:2;20696:18;;;20689:30;20755:31;20735:18;;;20728:59;20804:18;;107980:111:0::2;20475:353:1::0;107980:111:0::2;108126:12;::::0;108111:28:::2;::::0;;;:14:::2;:28;::::0;;;;;::::2;;108110:29;108102:67;;;::::0;-1:-1:-1;;;108102:67:0;;21035:2:1;108102:67:0::2;::::0;::::2;21017:21:1::0;21074:2;21054:18;;;21047:30;-1:-1:-1;;;21093:18:1;;;21086:55;21158:18;;108102:67:0::2;20833:349:1::0;108102:67:0::2;108245:23;85120:3;108245;:23;:::i;:::-;108230:10;108202:4;:25;;;:38;;;;:::i;:::-;:67;;108180:147;;;::::0;-1:-1:-1;;;108180:147:0;;21562:2:1;108180:147:0::2;::::0;::::2;21544:21:1::0;21601:2;21581:18;;;21574:30;21640:32;21620:18;;;21613:60;21690:18;;108180:147:0::2;21360:354:1::0;108180:147:0::2;108399:24;108482:23;85120:3;108482;:23;:::i;:::-;108454:10;108427:4;:24;;;:37;;;;:::i;:::-;108426:80;;;;:::i;:::-;108399:107:::0;-1:-1:-1;108519:33:0::2;108569:20:::0;;108565:912:::2;;108606:19;108628:97;108666:16;108701:9;108628:19;:97::i;:::-;108606:119;;108825:11;108740:20;:34;108761:12;;108740:34;;;;;;;;;;;:81;;;:96;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;108853:23:0::2;::::0;-1:-1:-1;108944:16:0;108880:60:::2;86142:18;108880:11:::0;:60:::2;:::i;:::-;108879:81;;;;:::i;:::-;108853:107;;109177:10;109149:4;:25;;;:38;;;;:::i;:::-;109098:28;109116:10:::0;109098:15;:28:::2;:::i;:::-;109047:4;:25;;;109024:4;:20;;;:48;;;;:::i;:::-;109023:104;;;;:::i;:::-;109022:166;;;;:::i;:::-;108977:211;;109253:10;109205:9;:23;109215:12;;109205:23;;;;;;;;;;;:44;;;:58;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;108565:912:0::2;::::0;-1:-1:-1;;;108565:912:0::2;;109324:20;:18;:20::i;:::-;109296:48:::0;-1:-1:-1;109425:40:0::2;85120:3;109425;:40;:::i;:::-;109371:12;::::0;109361:23:::2;::::0;;;:9:::2;:23;::::0;;;;:44:::2;;:104:::0;108565:912:::2;109503:12;::::0;109493:23:::2;::::0;;;:9:::2;:23;::::0;;;;:39:::2;;::::0;109489:344:::2;;109564:12;::::0;109554:23:::2;::::0;;;:9:::2;:23;::::0;;;;:39:::2;;:67:::0;;;109489:344:::2;;;109733:12;::::0;109723:23:::2;::::0;;;:9:::2;:23;::::0;;;;:39:::2;;::::0;109696:125:::2;::::0;109781:25;109696:8:::2;:125::i;:::-;109664:12;::::0;109654:23:::2;::::0;;;:9:::2;:23;::::0;;;;:39:::2;;:167:::0;109489:344:::2;109924:22;85120:3;109924:2;:22;:::i;:::-;109873:12;::::0;109863:23:::2;::::0;;;:9:::2;:23;::::0;;;;:44:::2;;::::0;:84:::2;109845:179;;;109992:12;::::0;109974:31:::2;::::0;;;:17:::2;:31;::::0;;;;:38;;-1:-1:-1;;109974:38:0::2;110008:4;109974:38;::::0;;109845:179:::2;110041:27;::::0;110057:10:::2;1674:51:1::0;;110041:27:0::2;::::0;1662:2:1;1647:18;110041:27:0::2;;;;;;;-1:-1:-1::0;110088:4:0::2;::::0;107566:2534;-1:-1:-1;;;;;;107566:2534:0:o;99757:260::-;99836:21;99896:3;:10;99882:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;99882:25:0;;99875:32;;99923:9;99918:92;99942:3;:10;99938:1;:14;99918:92;;;99984:14;99991:3;99995:1;99991:6;;;;;;;;:::i;:::-;;;;;;;99984;:14::i;:::-;99974:4;99979:1;99974:7;;;;;;;;:::i;:::-;;;;;;;;;;:24;99954:3;;;;:::i;:::-;;;;99918:92;;105690:481;105787:25;105830:23;105856:16;105866:5;105856:9;:16::i;:::-;105830:42;;105908:15;105894:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;105894:30:0;;105883:41;;105940:9;105935:229;105955:15;105951:1;:19;105935:229;;;105992:15;106010:29;106030:5;106037:1;106010:19;:29::i;:::-;106058:26;;;;:17;:26;;;;;:32;105992:47;;-1:-1:-1;106058:37:0;106054:99;;106130:7;106116:8;106125:1;106116:11;;;;;;;;:::i;:::-;;;;;;:21;;;;;106054:99;-1:-1:-1;105972:3:0;;;;:::i;:::-;;;;105935:229;;;;105819:352;105690:481;;;:::o;113954:86::-;68329:4;68775:16;68329:4;68775:10;:16::i;:::-;114022:10:::1;:8;:10::i;:::-;113954:86:::0;:::o;26619:185::-;26757:39;26774:4;26780:2;26784:7;26757:39;;;;;;;;;;;;:16;:39::i;101512:142::-;101603:21;;101590:56;;;-1:-1:-1;;;101590:56:0;;;;101563:7;;-1:-1:-1;;;;;101603:21:0;;101590:54;;:56;;;;;;;;;;;;;;101603:21;101590:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;101583:63;;101512:142;:::o;39315:320::-;39435:7;39490:30;39213:10;:17;;39125:113;39490:30;39482:5;:38;39460:132;;;;-1:-1:-1;;;39460:132:0;;22639:2:1;39460:132:0;;;22621:21:1;22678:2;22658:18;;;22651:30;22717:34;22697:18;;;22690:62;-1:-1:-1;;;22768:18:1;;;22761:42;22820:19;;39460:132:0;22437:408:1;39460:132:0;39610:10;39621:5;39610:17;;;;;;;;:::i;:::-;;;;;;;;;39603:24;;39315:320;;;:::o;103942:1038::-;104040:16;104103:21;;;:17;:21;;;;;;;;104074:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104137:51;;;;-1:-1:-1;;;104137:51:0;;23052:2:1;104137:51:0;;;23034:21:1;23091:2;23071:18;;;23064:30;-1:-1:-1;;;23110:18:1;;;23103:55;23175:18;;104137:51:0;22850:349:1;104137:51:0;104237:8;;104201:23;104227:19;;;:9;:19;;;;;;;:35;;;104295:11;;;;104430:29;;;104426:411;;;104521:9;;;;104488:29;104502:15;104488:11;:29;:::i;:::-;104487:43;;;;:::i;:::-;104625:22;;;;104476:54;;-1:-1:-1;104575:29:0;104589:15;104575:11;:29;:::i;:::-;104574:73;;;;:::i;:::-;104545:102;;;;:::i;:::-;;;104426:411;;;104803:22;;;;104753:29;104771:11;104753:15;:29;:::i;:::-;104752:73;;;;:::i;:::-;104723:102;;;;:::i;:::-;;;104426:411;104849:41;86142:18;104849:41;;:::i;:::-;;-1:-1:-1;104948:23:0;85120:3;104948;:23;:::i;:::-;104925:18;;104914:29;;:8;:29;:::i;:::-;104913:59;;;;:::i;:::-;104901:71;;;;:::i;:::-;;103942:1038;-1:-1:-1;;;;;103942:1038:0:o;23394:272::-;23511:7;23552:16;;;:7;:16;;;;;;-1:-1:-1;;;;;23552:16:0;23587:19;23579:56;;;;-1:-1:-1;;;23579:56:0;;23536:2:1;23579:56:0;;;23518:21:1;23575:2;23555:18;;;23548:30;-1:-1:-1;;;23594:18:1;;;23587:54;23658:18;;23579:56:0;23334:348:1;102264:414:0;102472:23;;102418:15;;102662:7;;-1:-1:-1;;;;;102472:23:0;102457:54;102526:6;102547:7;102569;102591:20;:18;:20::i;:::-;102626:22;102640:7;102626:13;:22::i;:::-;102457:202;;-1:-1:-1;;;;;;102457:202:0;;;;;;;23965:14:1;;23958:22;102457:202:0;;;23940:41:1;23997:18;;;23990:34;;;;24040:18;;;24033:34;;;;24083:18;;;24076:34;24126:19;;;24119:35;23912:19;;102457:202:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:212;;;;:::i;92980:373::-;78604:19;:17;:19::i;:::-;76543:1:::1;77141:7;;:19;;77133:63;;;;-1:-1:-1::0;;;77133:63:0::1;;;;;;;:::i;:::-;76543:1;77274:7;:18:::0;93063:19:::2;:17;:19::i;:::-;93116:10;93101:11;93109:2:::0;93101:7:::2;:11::i;:::-;-1:-1:-1::0;;;;;93101:25:0::2;;93093:51;;;::::0;-1:-1:-1;;;93093:51:0;;15302:2:1;93093:51:0::2;::::0;::::2;15284:21:1::0;15341:2;15321:18;;;15314:30;-1:-1:-1;;;15360:18:1;;;15353:43;15413:18;;93093:51:0::2;15100:337:1::0;93093:51:0::2;93163:18;::::0;;;:14:::2;:18;::::0;;;;:24;93155:58:::2;;;::::0;-1:-1:-1;;;93155:58:0;;24367:2:1;93155:58:0::2;::::0;::::2;24349:21:1::0;24406:2;24386:18;;;24379:30;-1:-1:-1;;;24425:18:1;;;24418:46;24481:18;;93155:58:0::2;24165:340:1::0;93155:58:0::2;93255:18;::::0;;;:14:::2;:18;::::0;;;;;;;;:27:::2;;::::0;;::::2;::::0;;::::2;93254:28;-1:-1:-1::0;;93224:58:0;;::::2;::::0;::::2;::::0;;;93298:47;;24678:25:1;;;93317:27:0;;24746:14:1;24739:22;24719:18;;;24712:50;;;;93298:47:0::2;::::0;24651:18:1;93298:47:0::2;;;;;;;-1:-1:-1::0;76499:1:0::1;77453:7;:22:::0;92980:373::o;110164:726::-;110278:12;78604:19;:17;:19::i;:::-;-1:-1:-1;;;;;;;;;;;68775:16:0::1;68786:4;68775:10;:16::i;:::-;110359:12:::2;::::0;110349:23:::2;::::0;;;:9:::2;:23;::::0;;;;:30:::2;;::::0;110330:15:::2;:49;;110308:128;;;::::0;-1:-1:-1;;;110308:128:0;;20319:2:1;110308:128:0::2;::::0;::::2;20301:21:1::0;20358:2;20338:18;;;20331:30;20397:31;20377:18;;;20370:59;20446:18;;110308:128:0::2;20117:353:1::0;110308:128:0::2;110473:12;::::0;110455:31:::2;::::0;;;:17:::2;:31;::::0;;;;;::::2;;110447:69;;;::::0;-1:-1:-1;;;110447:69:0;;24975:2:1;110447:69:0::2;::::0;::::2;24957:21:1::0;25014:2;24994:18;;;24987:30;-1:-1:-1;;;25033:18:1;;;25026:55;25098:18;;110447:69:0::2;24773:349:1::0;110447:69:0::2;110551:12;::::0;110536:28:::2;::::0;;;:14:::2;:28;::::0;;;;;::::2;;110535:29;110527:67;;;::::0;-1:-1:-1;;;110527:67:0;;21035:2:1;110527:67:0::2;::::0;::::2;21017:21:1::0;21074:2;21054:18;;;21047:30;-1:-1:-1;;;21093:18:1;;;21086:55;21158:18;;110527:67:0::2;20833:349:1::0;110527:67:0::2;110632:12;::::0;110611:34:::2;::::0;;;:20:::2;:34;::::0;;;;:50:::2;;::::0;110607:234:::2;;110698:12;::::0;110683:28:::2;::::0;;;:14:::2;:28;::::0;;;;:35;;-1:-1:-1;;110683:35:0::2;110714:4;110683:35:::0;;::::2;::::0;;;110714:4;-1:-1:-1;110607:234:0::2;;;110780:49;::::0;-1:-1:-1;;;110780:49:0;;25329:2:1;110780:49:0::2;::::0;::::2;25311:21:1::0;25368:2;25348:18;;;25341:30;25407:34;25387:18;;;25380:62;-1:-1:-1;;;25458:18:1;;;25451:37;25505:19;;110780:49:0::2;25127:403:1::0;110607:234:0::2;110858:24;::::0;110871:10:::2;1674:51:1::0;;110858:24:0::2;::::0;1662:2:1;1647:18;110858:24:0::2;;;;;;;78634:1:::1;110164:726:::0;:::o;23038:294::-;23155:7;-1:-1:-1;;;;;23202:19:0;;23180:110;;;;-1:-1:-1;;;23180:110:0;;25737:2:1;23180:110:0;;;25719:21:1;25776:2;25756:18;;;25749:30;25815:34;25795:18;;;25788:62;-1:-1:-1;;;25866:18:1;;;25859:39;25915:19;;23180:110:0;25535:405:1;23180:110:0;-1:-1:-1;;;;;;23308:16:0;;;;;:9;:16;;;;;;;23038:294::o;103357:486::-;103452:24;103526:18;;;:14;:18;;;;;;;;103494:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;103555:54;;;;-1:-1:-1;;;103555:54:0;;;;;;;:::i;:::-;103808:14;;103798:25;;;;:9;:25;;;;;;;;:37;;;103715:14;;103694:36;;:20;:36;;;;:87;;;103655:19;;;;:126;;103694:87;103655:126;:::i;:::-;103654:181;;;;:::i;:::-;103622:213;103357:486;-1:-1:-1;;;103357:486:0:o;105096:475::-;105190:25;105233:23;105259:16;105269:5;105259:9;:16::i;:::-;105233:42;;105311:15;105297:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;105297:30:0;;105286:41;;105343:9;105338:226;105358:15;105354:1;:19;105338:226;;;105395:15;105413:29;105433:5;105440:1;105413:19;:29::i;:::-;105461:23;;;;:14;:23;;;;;:29;105395:47;;-1:-1:-1;105461:34:0;105457:96;;105530:7;105516:8;105525:1;105516:11;;;;;;;;:::i;:::-;;;;;;:21;;;;;105457:96;-1:-1:-1;105375:3:0;;;;:::i;:::-;;;;105338:226;;115009:464;68329:4;68775:16;68329:4;68775:10;:16::i;:::-;78863::::1;:14;:16::i;:::-;115180:14:::2;115176:98;;;115211:51;::::0;115219:10:::2;::::0;115240:21:::2;115211:51:::0;::::2;;;::::0;::::2;::::0;;;115240:21;115219:10;115211:51;::::2;;;;;;;;;;;;;::::0;::::2;;;;;;115176:98;115291:9;115286:180;115306:17:::0;;::::2;115286:180;;;115345:12;115367:6;;115374:1;115367:9;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;115423:30;::::0;-1:-1:-1;;;115423:30:0;;115447:4:::2;115423:30;::::0;::::2;1674:51:1::0;115345:32:0;;-1:-1:-1;115392:62:0::2;::::0;115411:10:::2;::::0;-1:-1:-1;;;;;115423:15:0;::::2;::::0;::::2;::::0;1647:18:1;;115423:30:0::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;115392:18:0;::::2;::::0;:62;:18:::2;:62::i;:::-;-1:-1:-1::0;115325:3:0;::::2;::::0;::::2;:::i;:::-;;;;115286:180;;;;115009:464:::0;;;;:::o;89962:969::-;90109:15;78604:19;:17;:19::i;:::-;76543:1:::1;77141:7;;:19;;77133:63;;;;-1:-1:-1::0;;;77133:63:0::1;;;;;;;:::i;:::-;76543:1;77274:7;:18:::0;90137:19:::2;:17;:19::i;:::-;90184:1;90175:6;:10;90167:46;;;::::0;-1:-1:-1;;;90167:46:0;;26147:2:1;90167:46:0::2;::::0;::::2;26129:21:1::0;26186:2;26166:18;;;26159:30;26225:25;26205:18;;;26198:53;26268:18;;90167:46:0::2;25945:347:1::0;90167:46:0::2;90224:17;90244:12;;90259:1;90244:16;;;;:::i;:::-;90224:36;;90309:6;90273:9;:20;90283:9;90273:20;;;;;;;;;;;:32;;;:42;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;90326:31:0::2;::::0;;;:20:::2;:31;::::0;;;;:60:::2;;:70:::0;;90390:6;;90326:31;:70:::2;::::0;90390:6;;90326:70:::2;:::i;:::-;::::0;;;-1:-1:-1;90419:24:0::2;::::0;-1:-1:-1;90438:4:0;90419:18:::2;:24::i;:::-;90482:129;::::0;;::::2;::::0;::::2;::::0;;;;;::::2;::::0;;::::2;::::0;;;;::::2;;::::0;;;;;;-1:-1:-1;90456:23:0;;;:14:::2;:23:::0;;;;;;;:155;;;;;::::2;::::0;::::2;::::0;;;::::2;::::0;;::::2;::::0;;-1:-1:-1;;90456:155:0::2;::::0;::::2;;::::0;;;::::2;::::0;;90631:9:::2;:13:::0;90456:23;;-1:-1:-1;90624:123:0::2;::::0;-1:-1:-1;;;;;90631:13:0::2;90677:10;90710:4;90482:129:::0;90624:38:::2;:123::i;:::-;90765:158;::::0;;26578:25:1;;;26634:2;26619:18;;26612:34;;;26689:14;;26682:22;26662:18;;;26655:50;-1:-1:-1;;;;;26779:15:1;;26774:2;26759:18;;26752:43;90880:10:0::2;26826:3:1::0;26811:19;;26804:44;26732:3;26864:19;;26857:35;;;90765:158:0;;::::2;::::0;;;;26565:3:1;90765:158:0;;::::2;-1:-1:-1::0;76499:1:0::1;77453:7;:22:::0;89962:969;;-1:-1:-1;;;89962:969:0:o;113786:82::-;68329:4;68775:16;68329:4;68775:10;:16::i;:::-;113852:8:::1;:6;:8::i;98022:1614::-:0;98129:7;78604:19;:17;:19::i;:::-;76543:1:::1;77141:7;;:19;;77133:63;;;;-1:-1:-1::0;;;77133:63:0::1;;;;;;;:::i;:::-;76543:1;77274:7;:18:::0;98154:19:::2;:17;:19::i;:::-;98186:26;98215:21:::0;;;:17:::2;:21;::::0;;;;;;;;98186:50;;::::2;::::0;::::2;::::0;;;;;;;::::2;::::0;::::2;::::0;;;::::2;::::0;;;;::::2;::::0;::::2;::::0;;;;;;;;::::2;;::::0;;;;;98247:51:::2;;;::::0;-1:-1:-1;;;98247:51:0;;23052:2:1;98247:51:0::2;::::0;::::2;23034:21:1::0;23091:2;23071:18;;;23064:30;-1:-1:-1;;;23110:18:1;;;23103:55;23175:18;;98247:51:0::2;22850:349:1::0;98247:51:0::2;98335:8:::0;;98317:27:::2;::::0;;;:17:::2;:27;::::0;;;;;::::2;;98309:65;;;::::0;-1:-1:-1;;;98309:65:0;;24975:2:1;98309:65:0::2;::::0;::::2;24957:21:1::0;25014:2;24994:18;;;24987:30;-1:-1:-1;;;25033:18:1;;;25026:55;25098:18;;98309:65:0::2;24773:349:1::0;98309:65:0::2;98387:16;98406:32;98435:2;98406:28;:32::i;:::-;98387:51;;98449:13;98465:11;98473:2;98465:7;:11::i;:::-;98449:27;;98489:9;98495:2;98489:5;:9::i;:::-;98519:13:::0;98511:46:::2;;;::::0;-1:-1:-1;;;98511:46:0;;27105:2:1;98511:46:0::2;::::0;::::2;27087:21:1::0;27144:2;27124:18;;;27117:30;-1:-1:-1;;;27163:18:1;;;27156:50;27223:18;;98511:46:0::2;26903:344:1::0;98511:46:0::2;98570:19;98642:23;85120:3;98662;98642:23;:::i;:::-;98604:20;::::0;98593:31:::2;::::0;:8;:31:::2;:::i;:::-;98592:74;;;;:::i;:::-;98570:96:::0;-1:-1:-1;98677:21:0::2;-1:-1:-1::0;;;;;98776:19:0;::::2;98785:10;98776:19;98772:243;;98905:23;85120:3;98925;98905:23;:::i;:::-;98857:26;::::0;98846:37:::2;::::0;:8;:37:::2;:::i;:::-;98845:84;;;;:::i;:::-;98812:117;;98960:43;98969:13;98984:18;;98960:8;:43::i;:::-;98944:59;;98772:243;99040:27;99054:13:::0;99040:11;:27:::2;:::i;:::-;99027:41;::::0;;::::2;:::i;:::-;99102:8:::0;;99081:30:::2;::::0;;;:20:::2;:30;::::0;;;;:46:::2;;:51:::0;;99027:41;;-1:-1:-1;99131:1:0::2;::::0;99081:46;;:30;:51:::2;::::0;99131:1;;99081:51:::2;:::i;:::-;::::0;;;-1:-1:-1;99272:13:0;;-1:-1:-1;99221:35:0::2;99245:11:::0;99221:8;:35:::2;:::i;:::-;:64;;;;:::i;:::-;99164:8:::0;;99143:30:::2;::::0;;;:20:::2;:30;::::0;;;;:73:::2;;:143:::0;;:73;;:30;:143:::2;::::0;;;::::2;:::i;:::-;::::0;;;-1:-1:-1;;99348:24:0;;:9:::2;99306:13:::0;99299:110:::2;::::0;-1:-1:-1;;;;;99306:13:0;;::::2;::::0;99348:24:::2;99387:11:::0;99299:34:::2;:110::i;:::-;99427:9;:13:::0;99420:51:::2;::::0;-1:-1:-1;;;;;99427:13:0::2;99455:5:::0;99462:8;99420:34:::2;:51::i;:::-;99489:9;:13:::0;99482:61:::2;::::0;-1:-1:-1;;;;;99489:13:0::2;99517:10;99529:13:::0;99482:34:::2;:61::i;:::-;99561:39;::::0;;16668:25:1;;;16724:2;16709:18;;16702:34;;;-1:-1:-1;;;;;99561:39:0;::::2;::::0;99568:10:::2;::::0;99561:39:::2;::::0;16641:18:1;99561:39:0::2;;;;;;;-1:-1:-1::0;;76499:1:0::1;77453:7;:22:::0;-1:-1:-1;99620:8:0;98022:1614;-1:-1:-1;;;98022:1614:0:o;69255:197::-;69386:4;69415:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;69415:29:0;;;;;;;;;;;;;;;69255:197::o;23902:104::-;23958:13;23991:7;23984:14;;;;;:::i;102881:334::-;103020:15;103206:1;103186:3;103147:34;85120:3;85373:8;103147:34;:::i;:::-;103118:7;103102:13;103083:16;;103074:6;:25;;;;:::i;:::-;:41;;;;:::i;:::-;:51;;;;:::i;:::-;103073:109;;;;:::i;:::-;103072:117;;;;:::i;:::-;103071:136;;;;:::i;:::-;103048:159;102881:334;-1:-1:-1;;;;102881:334:0:o;25636:187::-;25763:52;17971:10;25796:8;25806;25763:18;:52::i;114233:165::-;68329:4;68775:16;68329:4;68775:10;:16::i;:::-;114356:34:::1;114380:9;114356:23;:34::i;111069:193::-:0;68329:4;68775:16;68329:4;68775:10;:16::i;:::-;111192:22;;:9:::1;:22:::0;;-1:-1:-1;;;;;111192:22:0;;::::1;-1:-1:-1::0;;;;;;111192:22:0;;::::1;;::::0;;;::::1;::::0;::::1;::::0;;;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;::::1;::::0;::::1;::::0;;;::::1;::::0;;;111230:24;::::1;::::0;::::1;::::0;111204:10;;27513:13:1;;-1:-1:-1;;;;;27509:22:1;;;27491:41;;27592:4;27580:17;;;27574:24;27570:33;;27548:20;;;27541:63;27664:4;27652:17;;;27646:24;27642:33;;27620:20;;;27613:63;27736:4;27724:17;;;27718:24;27714:33;;27692:20;;;27685:63;27808:4;27796:17;;;27790:24;27786:33;;27764:20;;;27757:63;27471:3;27868:17;;;27862:24;27858:33;;27836:20;;;27829:63;27952:4;27940:17;;;27934:24;27930:33;27908:20;;;27901:63;;;;27440:3;27425:19;;27252:718;111230:24:0::1;;;;;;;;111069:193:::0;;:::o;26875:360::-;27063:41;17971:10;27096:7;27063:18;:41::i;:::-;27041:137;;;;-1:-1:-1;;;27041:137:0;;;;;;;:::i;:::-;27189:38;27203:4;27209:2;27213:7;27222:4;27189:13;:38::i;:::-;26875:360;;;;:::o;101774:209::-;101893:26;;101875:100;;-1:-1:-1;;;101875:100:0;;101893:26;101875:100;;2510:25:1;;;101835:7:0;;-1:-1:-1;;;;;101893:26:0;;101875:59;;2483:18:1;;101875:100:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;114598:175::-;68329:4;68775:16;68329:4;68775:10;:16::i;:::-;114726:39:::1;114755:9;114726:28;:39::i;24077:378::-:0;24195:13;24226:23;24241:7;24226:14;:23::i;:::-;24262:21;24286:10;24781:9;;;;;;;;;-1:-1:-1;24781:9:0;;;24704:94;24286:10;24262:34;;24351:1;24333:7;24327:21;:25;:120;;;;;;;;;;;;;;;;;24396:7;24405:18;:7;:16;:18::i;:::-;24379:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;24307:140;24077:378;-1:-1:-1;;;24077:378:0:o;111371:337::-;111500:4;;68775:16;111500:4;68775:10;:16::i;:::-;111539:7:::1;111530:6;:16;111522:69;;;::::0;-1:-1:-1;;;111522:69:0;;28652:2:1;111522:69:0::1;::::0;::::1;28634:21:1::0;28691:2;28671:18;;;28664:30;28730:34;28710:18;;;28703:62;-1:-1:-1;;;28781:18:1;;;28774:38;28829:19;;111522:69:0::1;28450:404:1::0;111522:69:0::1;111602:26;:35:::0;;;111653:25:::1;::::0;2510::1;;;111653::0::1;::::0;2498:2:1;2483:18;111653:25:0::1;;;;;;;-1:-1:-1::0;111696:4:0::1;::::0;111371:337;-1:-1:-1;;111371:337:0:o;71817:190::-;70964:7;70996:12;;;:6;:12;;;;;:22;;;68775:16;68786:4;68775:10;:16::i;:::-;71973:26:::1;71985:4;71991:7;71973:11;:26::i;92602:276::-:0;92683:25;92751:3;:10;92737:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;92737:25:0;;92726:36;;92778:9;92773:98;92797:3;:10;92793:1;:14;92773:98;;;92843:16;92852:3;92856:1;92852:6;;;;;;;;:::i;:::-;;;;;;;92843:8;:16::i;:::-;92829:8;92838:1;92829:11;;;;;;;;:::i;:::-;;;;;;;;;;:30;92809:3;;;;:::i;:::-;;;;92773:98;;94540:3357;94686:15;78604:19;:17;:19::i;:::-;76543:1:::1;77141:7;;:19;;77133:63;;;;-1:-1:-1::0;;;77133:63:0::1;;;;;;;:::i;:::-;76543:1;77274:7;:18:::0;94714:19:::2;:17;:19::i;:::-;94767:1;94752:12;;:16;94744:42;;;::::0;-1:-1:-1;;;94744:42:0;;29061:2:1;94744:42:0::2;::::0;::::2;29043:21:1::0;29100:2;29080:18;;;29073:30;-1:-1:-1;;;29119:18:1;;;29112:43;29172:18;;94744:42:0::2;28859:337:1::0;94744:42:0::2;85294:4;94805:6;:28;94797:55;;;::::0;-1:-1:-1;;;94797:55:0;;29403:2:1;94797:55:0::2;::::0;::::2;29385:21:1::0;29442:2;29422:18;;;29415:30;-1:-1:-1;;;29461:18:1;;;29454:44;29515:18;;94797:55:0::2;29201:338:1::0;94797:55:0::2;94953:26;::::0;94930:12:::2;::::0;94920:23:::2;::::0;;;:9:::2;:23;::::0;;;;:30:::2;;::::0;:59:::2;::::0;94953:26;94920:59:::2;:::i;:::-;94885:15;:94;94863:182;;;::::0;-1:-1:-1;;;94863:182:0;;29746:2:1;94863:182:0::2;::::0;::::2;29728:21:1::0;29785:2;29765:18;;;29758:30;29824:34;29804:18;;;29797:62;-1:-1:-1;;;29875:18:1;;;29868:36;29921:19;;94863:182:0::2;29544:402:1::0;94863:182:0::2;95058:20;95081;:18;:20::i;:::-;95145:12;::::0;95112:20:::2;95135:23:::0;;;:9:::2;:23;::::0;;;;:30:::2;;::::0;95058:43;;-1:-1:-1;95112:20:0;95135:48:::2;::::0;95168:15:::2;::::0;95135:48:::2;:::i;:::-;95112:71:::0;-1:-1:-1;86142:18:0::2;95391:21;95406:6:::0;95391:12;:21:::2;:::i;:::-;95390:55;;;;:::i;:::-;95284:12;::::0;95274:23:::2;::::0;;;:9:::2;:23;::::0;;;;:41:::2;;::::0;:94:::2;::::0;86142:18:::2;::::0;95274:94:::2;:::i;:::-;95228:12;::::0;95218:23:::2;::::0;;;:9:::2;:23;::::0;;;;:35:::2;;::::0;:151:::2;::::0;;::::2;:::i;:::-;:227;;95196:310;;;::::0;-1:-1:-1;;;95196:310:0;;30153:2:1;95196:310:0::2;::::0;::::2;30135:21:1::0;30192:2;30172:18;;;30165:30;30231:34;30211:18;;;30204:62;-1:-1:-1;;;30282:18:1;;;30275:31;30323:19;;95196:310:0::2;29951:397:1::0;95196:310:0::2;95561:27;95591:128;86142:18;95650:1;95625:21;95640:6:::0;95625:12;:21:::2;:::i;:::-;95624:27;;;;:::i;:::-;95623:61;;;;:::i;:::-;95699:9;95591:17;:128::i;:::-;95561:158:::0;-1:-1:-1;86142:18:0::2;95837:1;95812:21;95827:6:::0;95812:12;:21:::2;:::i;:::-;95811:27;;;;:::i;:::-;95810:74;;;;:::i;:::-;95751:12;::::0;95730:34:::2;::::0;;;:20:::2;:34;::::0;;;;:63:::2;;:154:::0;;:63;;:34;:154:::2;::::0;;;::::2;:::i;:::-;::::0;;;-1:-1:-1;95897:17:0::2;::::0;-1:-1:-1;95944:23:0::2;:19:::0;95966:1:::2;95944:23;:::i;:::-;95918:21;95933:6:::0;95918:12;:21:::2;:::i;:::-;95917:51;;;;:::i;:::-;95897:71;;96028:19;95981:9;:23;95991:12;;95981:23;;;;;;;;;;;:43;;;:66;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;96165:23:0::2;::::0;-1:-1:-1;96165:19:0;96187:1:::2;96165:23;:::i;:::-;96139:50;::::0;:9;:50:::2;:::i;:::-;96091:12;::::0;96081:23:::2;::::0;;;:9:::2;:23;::::0;;;;:41:::2;;:108:::0;;:41;;:23;:108:::2;::::0;;;::::2;:::i;:::-;::::0;;;-1:-1:-1;96202:17:0::2;::::0;-1:-1:-1;96222:153:0::2;96253:4;96272:9:::0;96296:23:::2;:19:::0;96318:1:::2;96296:23;:::i;:::-;96344:12;::::0;96334:23:::2;::::0;;;:9:::2;:23;::::0;;;;:30:::2;;::::0;96222:16:::2;:153::i;:::-;96202:173:::0;-1:-1:-1;96388:17:0::2;96408:118;96441:9:::0;96465:23:::2;:19:::0;96487:1:::2;96465:23;:::i;:::-;96503:12;96408:18;:118::i;:::-;96584:12;::::0;96563:34:::2;::::0;;;:20:::2;:34;::::0;;;;:59;;96388:138;;-1:-1:-1;96613:9:0;;96563:34;;;:59:::2;::::0;96613:9;;96563:59:::2;:::i;:::-;::::0;;;-1:-1:-1;;96654:12:0::2;::::0;96633:34:::2;::::0;;;:20:::2;:34;::::0;;;;:45:::2;;:58:::0;;96682:9;;96633:34;:58:::2;::::0;96682:9;;96633:58:::2;:::i;:::-;::::0;;;-1:-1:-1;96750:23:0::2;::::0;-1:-1:-1;96750:19:0;96772:1:::2;96750:23;:::i;:::-;96723:12;::::0;96702:34:::2;::::0;;;:20:::2;:34;::::0;;;;:44:::2;;:71:::0;;:44;;:34;:71:::2;::::0;;;::::2;:::i;:::-;::::0;;;-1:-1:-1;;96805:12:0::2;::::0;96784:34:::2;::::0;;;:20:::2;:34;::::0;;;;:50:::2;;:55:::0;;96838:1:::2;::::0;96784:34;:55:::2;::::0;96838:1;;96784:55:::2;:::i;:::-;::::0;;;-1:-1:-1;96903:24:0::2;::::0;-1:-1:-1;96922:4:0;96903:18:::2;:24::i;:::-;96893:34;;96967:198;;;;;;;;97006:12;;96967:198;;;;97041:19;97063:1;97041:23;;;;:::i;:::-;96967:198:::0;;::::2;::::0;;::::2;::::0;;;;;;;;;;-1:-1:-1;96938:26:0;;;:17:::2;:26:::0;;;;;:227;;;;;;::::2;::::0;::::2;::::0;::::2;::::0;;;::::2;::::0;::::2;::::0;::::2;::::0;::::2;::::0;;::::2;::::0;::::2;::::0;;::::2;::::0;;;;97249:49:::2;86142:18;85120:3;97249:49;:::i;:::-;:55;::::0;97301:3:::2;97249:55;:::i;:::-;97213:18;::::0;97201:30:::2;::::0;:9;:30:::2;:::i;:::-;97200:105;;;;:::i;:::-;97178:127:::0;-1:-1:-1;97318:220:0::2;97371:10;97404:4;97178:127:::0;86142:18:::2;97425:21;97437:9:::0;97425;:21:::2;:::i;:::-;97424:72;;;;:::i;:::-;:103;;;;:::i;:::-;97325:9;:13:::0;-1:-1:-1;;;;;97325:13:0::2;::::0;97318:220;;:38:::2;:220::i;:::-;97600:24:::0;;:9:::2;97558:13:::0;97551:110:::2;::::0;-1:-1:-1;;;;;97558:13:0;;::::2;::::0;97600:24:::2;97639:11:::0;97551:34:::2;:110::i;:::-;86142:18;97757:21;97769:9:::0;97757;:21:::2;:::i;:::-;97756:68;;;;:::i;:::-;97695:12;::::0;97674:34:::2;::::0;;;:20:::2;:34;::::0;;;;:77:::2;;:151:::0;;:77;;:34;:151:::2;::::0;;;::::2;:::i;:::-;::::0;;;-1:-1:-1;97843:46:0::2;::::0;-1:-1:-1;97852:4:0;97858:7;97867:21:::2;97879:9:::0;97867;:21:::2;:::i;:::-;97843:46;::::0;;-1:-1:-1;;;;;30573:32:1;;;30555:51;;30637:2;30622:18;;30615:34;;;;30665:18;;;30658:34;30543:2;30528:18;97843:46:0::2;;;;;;;-1:-1:-1::0;;76499:1:0::1;77453:7;:22:::0;-1:-1:-1;94540:3357:0;;;-1:-1:-1;;;;;;;94540:3357:0:o;91255:1191::-;91364:15;78604:19;:17;:19::i;:::-;76543:1:::1;77141:7;;:19;;77133:63;;;;-1:-1:-1::0;;;77133:63:0::1;;;;;;;:::i;:::-;76543:1;77274:7;:18:::0;91397:19:::2;:17;:19::i;:::-;91427:29;91459:18:::0;;;:14:::2;:18;::::0;;;;;;;;91427:50;;::::2;::::0;::::2;::::0;;;;;;::::2;::::0;::::2;::::0;;;::::2;::::0;;;;::::2;;::::0;::::2;;;;::::0;;;;;;;91490:53:::2;;;::::0;-1:-1:-1;;;91490:53:0;;30905:2:1;91490:53:0::2;::::0;::::2;30887:21:1::0;30944:2;30924:18;;;30917:30;30983:25;30963:18;;;30956:53;31026:18;;91490:53:0::2;30703:347:1::0;91490:53:0::2;91562:14:::0;;91554:54:::2;;;;-1:-1:-1::0;;;91554:54:0::2;;;;;;;:::i;:::-;91642:14:::0;;91627:30:::2;::::0;;;:14:::2;:30;::::0;;;;;::::2;;91619:64;;;::::0;-1:-1:-1;;;91619:64:0;;31257:2:1;91619:64:0::2;::::0;::::2;31239:21:1::0;31296:2;31276:18;;;31269:30;-1:-1:-1;;;31315:18:1;;;31308:51;31376:18;;91619:64:0::2;31055:345:1::0;91619:64:0::2;91696:22;91721:29;91747:2;91721:25;:29::i;:::-;91696:54;;91763:12;91778:11;91786:2;91778:7;:11::i;:::-;91763:26;;91802:9;91808:2;91802:5;:9::i;:::-;91832:19:::0;91824:55:::2;;;::::0;-1:-1:-1;;;91824:55:0;;16344:2:1;91824:55:0::2;::::0;::::2;16326:21:1::0;16383:2;16363:18;;;16356:30;-1:-1:-1;;;16402:18:1;;;16395:53;16465:18;;91824:55:0::2;16142:347:1::0;91824:55:0::2;91897:34;::::0;;16668:25:1;;;16724:2;16709:18;;16702:34;;;-1:-1:-1;;;;;91897:34:0;::::2;::::0;::::2;::::0;16641:18:1;91897:34:0::2;;;;;;;91944:17;91964:12;;91979:1;91964:16;;;;:::i;:::-;91944:36;;92029:14;91993:9;:20;92003:9;91993:20;;;;;;;;;;;:32;;;:50;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;92054:31:0::2;::::0;;;:20:::2;:31;::::0;;;;:74:::2;;:92:::0;;92132:14;;92054:31;:92:::2;::::0;92132:14;;92054:92:::2;:::i;:::-;::::0;;;-1:-1:-1;92169:24:0::2;::::0;-1:-1:-1;92188:4:0;92169:18:::2;:24::i;:::-;92232:127;::::0;;::::2;::::0;;::::2;::::0;;;;;::::2;::::0;;::::2;::::0;;;92343:4:::2;92232:127:::0;;;;;;-1:-1:-1;92206:23:0;;;:14:::2;:23:::0;;;;;:153;;;;;;;;::::2;::::0;;;::::2;::::0;;::::2;::::0;;-1:-1:-1;;92206:153:0::2;::::0;::::2;;::::0;;;::::2;::::0;;;92377:61;;26578:25:1;;;26619:18;;;26612:34;;;26662:18;;;26655:50;;;;-1:-1:-1;;;;;26779:15:1;;26759:18;;;26752:43;;;26826:3;26811:19;;26804:44;26732:3;26864:19;;26857:35;;;92206:23:0;;-1:-1:-1;92377:61:0::2;::::0;26565:3:1;26550:19;92377:61:0::2;;;;;;;-1:-1:-1::0;;76499:1:0::1;77453:7;:22:::0;-1:-1:-1;91255:1191:0;;;-1:-1:-1;;91255:1191:0:o;112322:320::-;68329:4;68775:16;68329:4;68775:10;:16::i;:::-;112484:1:::1;112462:19;:23;112454:71;;;;-1:-1:-1::0;;;112454:71:0::1;;;;;;;:::i;:::-;112536:18;:40:::0;;;112592:42:::1;::::0;2510:25:1;;;112592:42:0::1;::::0;2498:2:1;2483:18;112592:42:0::1;2364:177:1::0;111874:292:0;68329:4;68775:16;68329:4;68775:10;:16::i;:::-;112023:1:::1;112003:17;:21;111995:69;;;;-1:-1:-1::0;;;111995:69:0::1;;;;;;;:::i;:::-;112075:16;:36:::0;;;112127:31:::1;::::0;2510:25:1;;;112127:31:0::1;::::0;2498:2:1;2483:18;112127:31:0::1;2364:177:1::0;60631:420:0;60785:39;;-1:-1:-1;;;60785:39:0;;60809:4;60785:39;;;32021:34:1;-1:-1:-1;;;;;32091:15:1;;;32071:18;;;32064:43;60762:20:0;;60827:5;;60785:15;;;;;31956:18:1;;60785:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:47;;;;:::i;:::-;60897:135;;-1:-1:-1;;;;;32310:32:1;;60897:135:0;;;32292:51:1;32359:18;;;32352:34;;;60762:70:0;;-1:-1:-1;60843:200:0;;60877:5;;-1:-1:-1;;;60938:22:0;32265:18:1;;60897:135:0;;;;-1:-1:-1;;60897:135:0;;;;;;;;;;;;;;-1:-1:-1;;;;;60897:135:0;-1:-1:-1;;;;;;60897:135:0;;;;;;;;;;60843:19;:200::i;12406:229::-;12543:12;12575:52;12597:6;12605:4;12611:1;12614:12;12575:21;:52::i;68883:280::-;69013:4;-1:-1:-1;;;;;;69055:47:0;;-1:-1:-1;;;69055:47:0;;:100;;;69119:36;69143:11;69119:23;:36::i;33665:135::-;28844:4;28868:16;;;:7;:16;;;;;;-1:-1:-1;;;;;28868:16:0;33739:53;;;;-1:-1:-1;;;33739:53:0;;23536:2:1;33739:53:0;;;23518:21:1;23575:2;23555:18;;;23548:30;-1:-1:-1;;;23594:18:1;;;23587:54;23658:18;;33739:53:0;23334:348:1;32944:174:0;33019:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;33019:29:0;-1:-1:-1;;;;;33019:29:0;;;;;;;;:24;;33073:23;33019:24;33073:14;:23::i;:::-;-1:-1:-1;;;;;33064:46:0;;;;;;;;;;;32944:174;;:::o;29073:331::-;29202:4;29224:13;29240:23;29255:7;29240:14;:23::i;:::-;29224:39;;29293:5;-1:-1:-1;;;;;29282:16:0;:7;-1:-1:-1;;;;;29282:16:0;;:65;;;-1:-1:-1;;;;;;26065:25:0;;;26036:4;26065:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;29315:32;29282:113;;;;29388:7;-1:-1:-1;;;;;29364:31:0;:20;29376:7;29364:11;:20::i;:::-;-1:-1:-1;;;;;29364:31:0;;29274:122;29073:331;-1:-1:-1;;;;29073:331:0:o;32163:662::-;32336:4;-1:-1:-1;;;;;32309:31:0;:23;32324:7;32309:14;:23::i;:::-;-1:-1:-1;;;;;32309:31:0;;32287:118;;;;-1:-1:-1;;;32287:118:0;;32599:2:1;32287:118:0;;;32581:21:1;32638:2;32618:18;;;32611:30;32677:34;32657:18;;;32650:62;-1:-1:-1;;;32728:18:1;;;32721:35;32773:19;;32287:118:0;32397:401:1;32287:118:0;-1:-1:-1;;;;;32424:16:0;;32416:65;;;;-1:-1:-1;;;32416:65:0;;33005:2:1;32416:65:0;;;32987:21:1;33044:2;33024:18;;;33017:30;33083:34;33063:18;;;33056:62;-1:-1:-1;;;33134:18:1;;;33127:34;33178:19;;32416:65:0;32803:400:1;32416:65:0;32494:39;32515:4;32521:2;32525:7;32494:20;:39::i;:::-;32598:29;32615:1;32619:7;32598:8;:29::i;:::-;-1:-1:-1;;;;;32640:15:0;;;;;;:9;:15;;;;;:20;;32659:1;;32640:15;:20;;32659:1;;32640:20;:::i;:::-;;;;-1:-1:-1;;;;;;;32671:13:0;;;;;;:9;:13;;;;;:18;;32688:1;;32671:13;:18;;32688:1;;32671:18;:::i;:::-;;;;-1:-1:-1;;32700:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;32700:21:0;-1:-1:-1;;;;;32700:21:0;;;;;;;;;32739:27;;32700:16;;32739:27;;;;;;;24930:347;24860:417;;:::o;79158:108::-;79070:7;;;;79228:9;79220:38;;;;-1:-1:-1;;;79220:38:0;;33410:2:1;79220:38:0;;;33392:21:1;33449:2;33429:18;;;33422:30;-1:-1:-1;;;33468:18:1;;;33461:46;33524:18;;79220:38:0;33208:340:1;79220:38:0;79158:108::o;81312:305::-;81449:10;81463:9;81449:23;81445:164;;81534:10;81513:32;;;;:20;:32;;;;;;;;81487:122;;;;-1:-1:-1;;;81487:122:0;;33755:2:1;81487:122:0;;;33737:21:1;33794:2;33774:18;;;33767:30;33833;33813:18;;;33806:58;33881:18;;81487:122:0;33553:352:1;31406:420:0;31466:13;31482:23;31497:7;31482:14;:23::i;:::-;31466:39;;31518:48;31539:5;31554:1;31558:7;31518:20;:48::i;:::-;31607:29;31624:1;31628:7;31607:8;:29::i;:::-;-1:-1:-1;;;;;31649:16:0;;;;;;:9;:16;;;;;:21;;31669:1;;31649:16;:21;;31669:1;;31649:21;:::i;:::-;;;;-1:-1:-1;;31688:16:0;;;;:7;:16;;;;;;31681:23;;-1:-1:-1;;;;;;31681:23:0;;;31722:36;31696:7;;31688:16;-1:-1:-1;;;;;31722:36:0;;;;;31688:16;;31722:36;72562:287;;:::o;59160:248::-;59331:58;;-1:-1:-1;;;;;32310:32:1;;59331:58:0;;;32292:51:1;32359:18;;;32352:34;;;59277:123:0;;59311:5;;-1:-1:-1;;;59354:23:0;32265:18:1;;59331:58:0;32118:274:1;69756:105:0;69823:30;69834:4;17971:10;69823;:30::i;74228:238::-;74312:22;74320:4;74326:7;74312;:22::i;:::-;74307:152;;74351:12;;;;:6;:12;;;;;;;;-1:-1:-1;;;;;74351:29:0;;;;;;;;;:36;;-1:-1:-1;;74351:36:0;74383:4;74351:36;;;74434:12;17971:10;;17891:98;74434:12;-1:-1:-1;;;;;74407:40:0;74425:7;-1:-1:-1;;;;;74407:40:0;74419:4;74407:40;;;;;;;;;;74228:238;;:::o;74646:239::-;74730:22;74738:4;74744:7;74730;:22::i;:::-;74726:152;;;74801:5;74769:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;74769:29:0;;;;;;;;;;:37;;-1:-1:-1;;74769:37:0;;;74826:40;17971:10;;74769:12;;74826:40;;74801:5;74826:40;74646:239;;:::o;101059:341::-;101224:22;;101272:20;;101224:9;101307:13;101210:182;;-1:-1:-1;;;101210:182:0;;-1:-1:-1;;;;;101272:20:0;;;101210:182;;;34215:34:1;101307:13:0;;;34265:18:1;;;34258:43;34317:18;;;34310:34;;;101159:19:0;34360:18:1;;;34353:34;;;34403:19;;;34396:35;;;101159:19:0;101224:22;;;;;101210:47;;34149:19:1;;101210:182:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;45215:106::-;45273:7;45304:1;45300;:5;:13;;45312:1;45300:13;;;-1:-1:-1;45308:1:0;;45215:106;-1:-1:-1;45215:106:0:o;79854:120::-;78863:16;:14;:16::i;:::-;79913:7:::1;:15:::0;;-1:-1:-1;;79913:15:0::1;::::0;;79944:22:::1;17971:10:::0;79953:12:::1;79944:22;::::0;-1:-1:-1;;;;;1692:32:1;;;1674:51;;1662:2;1647:18;79944:22:0::1;;;;;;;79854:120::o:0;79343:108::-;79070:7;;;;79402:41;;;;-1:-1:-1;;;79402:41:0;;34644:2:1;79402:41:0;;;34626:21:1;34683:2;34663:18;;;34656:30;-1:-1:-1;;;34702:18:1;;;34695:50;34762:18;;79402:41:0;34442:344:1;100181:199:0;100238:15;100276:25;:15;884:14;;792:114;100276:25;100266:35;;100312:27;:15;1003:19;;1021:1;1003:19;;;914:127;100312:27;100350:22;100360:2;100364:7;100350:9;:22::i;:::-;100181:199;;;:::o;59416:285::-;59614:68;;-1:-1:-1;;;;;35049:15:1;;;59614:68:0;;;35031:34:1;35101:15;;35081:18;;;35074:43;35133:18;;;35126:34;;;59560:133:0;;59594:5;;-1:-1:-1;;;59637:27:0;34966:18:1;;59614:68:0;34791:375:1;79595:118:0;78604:19;:17;:19::i;:::-;79655:7:::1;:14:::0;;-1:-1:-1;;79655:14:0::1;79665:4;79655:14;::::0;;79685:20:::1;79692:12;17971:10:::0;;17891:98;33261:315;33416:8;-1:-1:-1;;;;;33407:17:0;:5;-1:-1:-1;;;;;33407:17:0;;;33399:55;;;;-1:-1:-1;;;33399:55:0;;35373:2:1;33399:55:0;;;35355:21:1;35412:2;35392:18;;;35385:30;35451:27;35431:18;;;35424:55;35496:18;;33399:55:0;35171:349:1;33399:55:0;-1:-1:-1;;;;;33465:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;33465:46:0;;;;;;;;;;33527:41;;540::1;;;33527::0;;513:18:1;33527:41:0;;;;;;;33261:315;;;:::o;80485:363::-;81943:17;;80557:60;;;;-1:-1:-1;;;80557:60:0;;35727:2:1;80557:60:0;;;35709:21:1;35766:2;35746:18;;;35739:30;35805:28;35785:18;;;35778:56;35851:18;;80557:60:0;35525:350:1;80557:60:0;-1:-1:-1;;;;;80651:31:0;;;;;;:20;:31;;;;;;;;80650:32;80628:110;;;;-1:-1:-1;;;80628:110:0;;36082:2:1;80628:110:0;;;36064:21:1;36121:2;36101:18;;;36094:30;36160;36140:18;;;36133:58;36208:18;;80628:110:0;35880:352:1;80628:110:0;-1:-1:-1;;;;;80751:31:0;;;;;;:20;:31;;;;;;:38;;-1:-1:-1;;80751:38:0;80785:4;80751:38;;;80807:33;;;80751:31;80807:33;80485:363;:::o;28116:350::-;28272:28;28282:4;28288:2;28292:7;28272:9;:28::i;:::-;28333:47;28356:4;28362:2;28366:7;28375:4;28333:22;:47::i;:::-;28311:147;;;;-1:-1:-1;;;28311:147:0;;;;;;;:::i;80998:261::-;-1:-1:-1;;;;;81083:31:0;;;;;;:20;:31;;;;;;;;81075:68;;;;-1:-1:-1;;;81075:68:0;;36858:2:1;81075:68:0;;;36840:21:1;36897:2;36877:18;;;36870:30;36936:26;36916:18;;;36909:54;36980:18;;81075:68:0;36656:348:1;81075:68:0;-1:-1:-1;;;;;81156:31:0;;81190:5;81156:31;;;:20;:31;;;;;;:39;;-1:-1:-1;;81156:39:0;;;81213:38;;;81190:5;81213:38;80998:261;:::o;18381:723::-;18437:13;18658:10;18654:53;;-1:-1:-1;;18685:10:0;;;;;;;;;;;;-1:-1:-1;;;18685:10:0;;;;;18381:723::o;18654:53::-;18732:5;18717:12;18773:78;18780:9;;18773:78;;18806:8;;;;:::i;:::-;;-1:-1:-1;18829:10:0;;-1:-1:-1;18837:2:0;18829:10;;:::i;:::-;;;18773:78;;;18861:19;18893:6;18883:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;18883:17:0;;18861:39;;18911:154;18918:10;;18911:154;;18945:11;18955:1;18945:11;;:::i;:::-;;-1:-1:-1;19014:10:0;19022:2;19014:5;:10;:::i;:::-;19001:24;;:2;:24;:::i;:::-;18988:39;;18971:6;18978;18971:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;18971:56:0;;;;;;;;-1:-1:-1;19042:11:0;19051:2;19042:11;;:::i;:::-;;;18911:154;;100535:355;100714:22;;:9;100762:13;100790:20;;100700:182;;-1:-1:-1;;;100700:182:0;;-1:-1:-1;;;;;100762:13:0;;;100700:182;;;34215:34:1;100790:20:0;;;34265:18:1;;;34258:43;34317:18;;;34310:34;;;100633:27:0;34360:18:1;;;34353:34;;;34403:19;;;34396:35;;;100633:27:0;100714:22;;;;;100700:47;;34149:19:1;;100700:182:0;33910:527:1;62658:802:0;63082:23;63108:106;63150:4;63108:106;;;;;;;;;;;;;;;;;63116:5;-1:-1:-1;;;;;63108:27:0;;;:106;;;;;:::i;:::-;63229:17;;63082:132;;-1:-1:-1;63229:21:0;63225:228;;63344:10;63333:30;;;;;;;;;;;;:::i;:::-;63307:134;;;;-1:-1:-1;;;63307:134:0;;37578:2:1;63307:134:0;;;37560:21:1;37617:2;37597:18;;;37590:30;37656:34;37636:18;;;37629:62;-1:-1:-1;;;37707:18:1;;;37700:40;37757:19;;63307:134:0;37376:406:1;13622:571:0;13792:12;13864:5;13839:21;:30;;13817:118;;;;-1:-1:-1;;;13817:118:0;;37989:2:1;13817:118:0;;;37971:21:1;38028:2;38008:18;;;38001:30;38067:34;38047:18;;;38040:62;-1:-1:-1;;;38118:18:1;;;38111:36;38164:19;;13817:118:0;37787:402:1;13817:118:0;-1:-1:-1;;;;;9859:19:0;;;13946:60;;;;-1:-1:-1;;;13946:60:0;;38396:2:1;13946:60:0;;;38378:21:1;38435:2;38415:18;;;38408:30;38474:31;38454:18;;;38447:59;38523:18;;13946:60:0;38194:353:1;13946:60:0;14020:12;14034:23;14061:6;-1:-1:-1;;;;;14061:11:0;14080:5;14101:4;14061:55;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14019:97;;;;14134:51;14151:7;14160:10;14172:12;14134:16;:51::i;:::-;14127:58;13622:571;-1:-1:-1;;;;;;;13622:571:0:o;38322:300::-;38469:4;-1:-1:-1;;;;;;38511:50:0;;-1:-1:-1;;;38511:50:0;;:103;;;38578:36;38602:11;38578:23;:36::i;115549:215::-;115711:45;115738:4;115744:2;115748:7;115711:26;:45::i;70151:505::-;70240:22;70248:4;70254:7;70240;:22::i;:::-;70235:414;;70428:41;70456:7;-1:-1:-1;;;;;70428:41:0;70466:2;70428:19;:41::i;:::-;70542:38;70570:4;70577:2;70542:19;:38::i;:::-;70333:270;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;70333:270:0;;;;;;;;;;-1:-1:-1;;;70279:358:0;;;;;;;:::i;29746:110::-;29822:26;29832:2;29836:7;29822:26;;;;;;;;;;;;:9;:26::i;34364:1034::-;34518:4;-1:-1:-1;;;;;34539:13:0;;9859:19;:23;34535:856;;34592:174;;-1:-1:-1;;;34592:174:0;;-1:-1:-1;;;;;34592:36:0;;;;;:174;;17971:10;;34686:4;;34713:7;;34743:4;;34592:174;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34592:174:0;;;;;;;;-1:-1:-1;;34592:174:0;;;;;;;;;;;;:::i;:::-;;;34571:765;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34949:13:0;;34945:376;;34992:108;;-1:-1:-1;;;34992:108:0;;;;;;;:::i;34945:376::-;35271:6;35265:13;35256:6;35252:2;35248:15;35241:38;34571:765;-1:-1:-1;;;;;;34830:51:0;-1:-1:-1;;;34830:51:0;;-1:-1:-1;34823:58:0;;34535:856;-1:-1:-1;35375:4:0;35368:11;;16582:762;16732:12;16761:7;16757:580;;;-1:-1:-1;16792:10:0;16785:17;;16757:580;16906:17;;:21;16902:424;;17154:10;17148:17;17215:15;17202:10;17198:2;17194:19;17187:44;16902:424;17297:12;17290:20;;-1:-1:-1;;;17290:20:0;;;;;;;;:::i;22619:355::-;22766:4;-1:-1:-1;;;;;;22808:40:0;;-1:-1:-1;;;22808:40:0;;:105;;-1:-1:-1;;;;;;;22865:48:0;;-1:-1:-1;;;22865:48:0;22808:105;:158;;;-1:-1:-1;;;;;;;;;;21337:40:0;;;22930:36;21178:207;40248:589;-1:-1:-1;;;;;40454:18:0;;40450:187;;40489:40;40521:7;41664:10;:17;;41637:24;;;;:15;:24;;;;;:44;;;41692:24;;;;;;;;;;;;41560:164;40489:40;40450:187;;;40559:2;-1:-1:-1;;;;;40551:10:0;:4;-1:-1:-1;;;;;40551:10:0;;40547:90;;40578:47;40611:4;40617:7;40578:32;:47::i;:::-;-1:-1:-1;;;;;40651:16:0;;40647:183;;40684:45;40721:7;40684:36;:45::i;40647:183::-;40757:4;-1:-1:-1;;;;;40751:10:0;:2;-1:-1:-1;;;;;40751:10:0;;40747:83;;40778:40;40806:2;40810:7;40778:27;:40::i;19682:483::-;19784:13;19815:19;19847:10;19851:6;19847:1;:10;:::i;:::-;:14;;19860:1;19847:14;:::i;:::-;19837:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19837:25:0;;19815:47;;-1:-1:-1;;;19873:6:0;19880:1;19873:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;19873:15:0;;;;;;;;;-1:-1:-1;;;19899:6:0;19906:1;19899:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;19899:15:0;;;;;;;;-1:-1:-1;19930:9:0;19942:10;19946:6;19942:1;:10;:::i;:::-;:14;;19955:1;19942:14;:::i;:::-;19930:26;;19925:135;19962:1;19958;:5;19925:135;;;-1:-1:-1;;;20010:5:0;20018:3;20010:11;19997:25;;;;;;;:::i;:::-;;;;19985:6;19992:1;19985:9;;;;;;;;:::i;:::-;;;;:37;-1:-1:-1;;;;;19985:37:0;;;;;;;;-1:-1:-1;20047:1:0;20037:11;;;;;19965:3;;;:::i;:::-;;;19925:135;;;-1:-1:-1;20078:10:0;;20070:55;;;;-1:-1:-1;;;20070:55:0;;40713:2:1;20070:55:0;;;40695:21:1;;;40732:18;;;40725:30;40791:34;40771:18;;;40764:62;40843:18;;20070:55:0;40511:356:1;30083:319:0;30212:18;30218:2;30222:7;30212:5;:18::i;:::-;30263:53;30294:1;30298:2;30302:7;30311:4;30263:22;:53::i;:::-;30241:153;;;;-1:-1:-1;;;30241:153:0;;;;;;;:::i;42351:1002::-;42631:22;42681:1;42656:22;42673:4;42656:16;:22::i;:::-;:26;;;;:::i;:::-;42693:18;42714:26;;;:17;:26;;;;;;42631:51;;-1:-1:-1;42847:28:0;;;42843:328;;-1:-1:-1;;;;;42914:18:0;;42892:19;42914:18;;;:12;:18;;;;;;;;:34;;;;;;;;;42965:30;;;;;;:44;;;43082:30;;:17;:30;;;;;:43;;;42843:328;-1:-1:-1;43267:26:0;;;;:17;:26;;;;;;;;43260:33;;;-1:-1:-1;;;;;43311:18:0;;;;;:12;:18;;;;;:34;;;;;;;43304:41;42351:1002::o;43648:1079::-;43926:10;:17;43901:22;;43926:21;;43946:1;;43926:21;:::i;:::-;43958:18;43979:24;;;:15;:24;;;;;;44352:10;:26;;43901:46;;-1:-1:-1;43979:24:0;;43901:46;;44352:26;;;;;;:::i;:::-;;;;;;;;;44330:48;;44416:11;44391:10;44402;44391:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;44496:28;;;:15;:28;;;;;;;:41;;;44668:24;;;;;44661:31;44703:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;43719:1008;;;43648:1079;:::o;41138:221::-;41223:14;41240:20;41257:2;41240:16;:20::i;:::-;-1:-1:-1;;;;;41271:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;41316:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;41138:221:0:o;30738:439::-;-1:-1:-1;;;;;30818:16:0;;30810:61;;;;-1:-1:-1;;;30810:61:0;;41206:2:1;30810:61:0;;;41188:21:1;;;41225:18;;;41218:30;41284:34;41264:18;;;41257:62;41336:18;;30810:61:0;41004:356:1;30810:61:0;28844:4;28868:16;;;:7;:16;;;;;;-1:-1:-1;;;;;28868:16:0;:30;30882:58;;;;-1:-1:-1;;;30882:58:0;;41567:2:1;30882:58:0;;;41549:21:1;41606:2;41586:18;;;41579:30;41645;41625:18;;;41618:58;41693:18;;30882:58:0;41365:352:1;30882:58:0;30953:45;30982:1;30986:2;30990:7;30953:20;:45::i;:::-;-1:-1:-1;;;;;31011:13:0;;;;;;:9;:13;;;;;:18;;31028:1;;31011:13;:18;;31028:1;;31011:18;:::i;:::-;;;;-1:-1:-1;;31040:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;31040:21:0;-1:-1:-1;;;;;31040:21:0;;;;;;;;31079:33;;31040:16;;;31079:33;;31040:16;;31079:33;72562:287;;:::o;14:131:1:-;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;-1:-1:-1;;840:1:1;822:16;;815:27;592:258::o;855:::-;897:3;935:5;929:12;962:6;957:3;950:19;978:63;1034:6;1027:4;1022:3;1018:14;1011:4;1004:5;1000:16;978:63;:::i;:::-;1095:2;1074:15;-1:-1:-1;;1070:29:1;1061:39;;;;1102:4;1057:50;;855:258;-1:-1:-1;;855:258:1:o;1118:220::-;1267:2;1256:9;1249:21;1230:4;1287:45;1328:2;1317:9;1313:18;1305:6;1287:45;:::i;1343:180::-;1402:6;1455:2;1443:9;1434:7;1430:23;1426:32;1423:52;;;1471:1;1468;1461:12;1423:52;-1:-1:-1;1494:23:1;;1343:180;-1:-1:-1;1343:180:1:o;1736:173::-;1804:20;;-1:-1:-1;;;;;1853:31:1;;1843:42;;1833:70;;1899:1;1896;1889:12;1914:254;1982:6;1990;2043:2;2031:9;2022:7;2018:23;2014:32;2011:52;;;2059:1;2056;2049:12;2011:52;2082:29;2101:9;2082:29;:::i;:::-;2072:39;2158:2;2143:18;;;;2130:32;;-1:-1:-1;;;1914:254:1:o;2173:186::-;2232:6;2285:2;2273:9;2264:7;2260:23;2256:32;2253:52;;;2301:1;2298;2291:12;2253:52;2324:29;2343:9;2324:29;:::i;2546:328::-;2623:6;2631;2639;2692:2;2680:9;2671:7;2667:23;2663:32;2660:52;;;2708:1;2705;2698:12;2660:52;2731:29;2750:9;2731:29;:::i;:::-;2721:39;;2779:38;2813:2;2802:9;2798:18;2779:38;:::i;:::-;2769:48;;2864:2;2853:9;2849:18;2836:32;2826:42;;2546:328;;;;;:::o;3246:254::-;3314:6;3322;3375:2;3363:9;3354:7;3350:23;3346:32;3343:52;;;3391:1;3388;3381:12;3343:52;3427:9;3414:23;3404:33;;3456:38;3490:2;3479:9;3475:18;3456:38;:::i;:::-;3446:48;;3246:254;;;;;:::o;3505:316::-;3582:6;3590;3598;3651:2;3639:9;3630:7;3626:23;3622:32;3619:52;;;3667:1;3664;3657:12;3619:52;-1:-1:-1;;3690:23:1;;;3760:2;3745:18;;3732:32;;-1:-1:-1;3811:2:1;3796:18;;;3783:32;;3505:316;-1:-1:-1;3505:316:1:o;3826:248::-;3894:6;3902;3955:2;3943:9;3934:7;3930:23;3926:32;3923:52;;;3971:1;3968;3961:12;3923:52;-1:-1:-1;;3994:23:1;;;4064:2;4049:18;;;4036:32;;-1:-1:-1;3826:248:1:o;4079:127::-;4140:10;4135:3;4131:20;4128:1;4121:31;4171:4;4168:1;4161:15;4195:4;4192:1;4185:15;4211:275;4282:2;4276:9;4347:2;4328:13;;-1:-1:-1;;4324:27:1;4312:40;;4382:18;4367:34;;4403:22;;;4364:62;4361:88;;;4429:18;;:::i;:::-;4465:2;4458:22;4211:275;;-1:-1:-1;4211:275:1:o;4491:946::-;4575:6;4606:2;4649;4637:9;4628:7;4624:23;4620:32;4617:52;;;4665:1;4662;4655:12;4617:52;4705:9;4692:23;4734:18;4775:2;4767:6;4764:14;4761:34;;;4791:1;4788;4781:12;4761:34;4829:6;4818:9;4814:22;4804:32;;4874:7;4867:4;4863:2;4859:13;4855:27;4845:55;;4896:1;4893;4886:12;4845:55;4932:2;4919:16;4954:2;4950;4947:10;4944:36;;;4960:18;;:::i;:::-;5006:2;5003:1;4999:10;4989:20;;5029:28;5053:2;5049;5045:11;5029:28;:::i;:::-;5091:15;;;5161:11;;;5157:20;;;5122:12;;;;5189:19;;;5186:39;;;5221:1;5218;5211:12;5186:39;5245:11;;;;5265:142;5281:6;5276:3;5273:15;5265:142;;;5347:17;;5335:30;;5298:12;;;;5385;;;;5265:142;;;5426:5;4491:946;-1:-1:-1;;;;;;;;4491:946:1:o;5442:632::-;5613:2;5665:21;;;5735:13;;5638:18;;;5757:22;;;5584:4;;5613:2;5836:15;;;;5810:2;5795:18;;;5584:4;5879:169;5893:6;5890:1;5887:13;5879:169;;;5954:13;;5942:26;;6023:15;;;;5988:12;;;;5915:1;5908:9;5879:169;;;-1:-1:-1;6065:3:1;;5442:632;-1:-1:-1;;;;;;5442:632:1:o;6079:118::-;6165:5;6158:13;6151:21;6144:5;6141:32;6131:60;;6187:1;6184;6177:12;6202:446;6285:6;6293;6301;6309;6362:3;6350:9;6341:7;6337:23;6333:33;6330:53;;;6379:1;6376;6369:12;6330:53;6418:9;6405:23;6437:28;6459:5;6437:28;:::i;:::-;6484:5;6536:2;6521:18;;6508:32;;-1:-1:-1;6587:2:1;6572:18;;6559:32;;6638:2;6623:18;6610:32;;-1:-1:-1;6202:446:1;-1:-1:-1;;;6202:446:1:o;7265:750::-;7357:6;7365;7373;7426:2;7414:9;7405:7;7401:23;7397:32;7394:52;;;7442:1;7439;7432:12;7394:52;7482:9;7469:23;7511:18;7552:2;7544:6;7541:14;7538:34;;;7568:1;7565;7558:12;7538:34;7606:6;7595:9;7591:22;7581:32;;7651:7;7644:4;7640:2;7636:13;7632:27;7622:55;;7673:1;7670;7663:12;7622:55;7713:2;7700:16;7739:2;7731:6;7728:14;7725:34;;;7755:1;7752;7745:12;7725:34;7810:7;7803:4;7793:6;7790:1;7786:14;7782:2;7778:23;7774:34;7771:47;7768:67;;;7831:1;7828;7821:12;7768:67;7862:4;7854:13;;;;-1:-1:-1;7886:6:1;-1:-1:-1;;7927:20:1;;7914:34;7957:28;7914:34;7957:28;:::i;:::-;8004:5;7994:15;;;7265:750;;;;;:::o;8020:383::-;8094:6;8102;8110;8163:2;8151:9;8142:7;8138:23;8134:32;8131:52;;;8179:1;8176;8169:12;8131:52;8215:9;8202:23;8192:33;;8275:2;8264:9;8260:18;8247:32;8288:28;8310:5;8288:28;:::i;:::-;8335:5;-1:-1:-1;8359:38:1;8393:2;8378:18;;8359:38;:::i;:::-;8349:48;;8020:383;;;;;:::o;9272:315::-;9337:6;9345;9398:2;9386:9;9377:7;9373:23;9369:32;9366:52;;;9414:1;9411;9404:12;9366:52;9437:29;9456:9;9437:29;:::i;:::-;9427:39;;9516:2;9505:9;9501:18;9488:32;9529:28;9551:5;9529:28;:::i;:::-;9576:5;9566:15;;;9272:315;;;;;:::o;9592:886::-;9678:6;9731:3;9719:9;9710:7;9706:23;9702:33;9699:53;;;9748:1;9745;9738:12;9699:53;9781:2;9775:9;9823:3;9815:6;9811:16;9893:6;9881:10;9878:22;9857:18;9845:10;9842:34;9839:62;9836:88;;;9904:18;;:::i;:::-;9940:2;9933:22;9979:29;9998:9;9979:29;:::i;:::-;9971:6;9964:45;10042:38;10076:2;10065:9;10061:18;10042:38;:::i;:::-;10037:2;10029:6;10025:15;10018:63;10114:38;10148:2;10137:9;10133:18;10114:38;:::i;:::-;10109:2;10101:6;10097:15;10090:63;10186:38;10220:2;10209:9;10205:18;10186:38;:::i;:::-;10181:2;10173:6;10169:15;10162:63;10259:39;10293:3;10282:9;10278:19;10259:39;:::i;:::-;10253:3;10245:6;10241:16;10234:65;10333:39;10367:3;10356:9;10352:19;10333:39;:::i;:::-;10327:3;10319:6;10315:16;10308:65;10407:39;10441:3;10430:9;10426:19;10407:39;:::i;:::-;10401:3;10389:16;;10382:65;10393:6;9592:886;-1:-1:-1;;;9592:886:1:o;10483:980::-;10578:6;10586;10594;10602;10655:3;10643:9;10634:7;10630:23;10626:33;10623:53;;;10672:1;10669;10662:12;10623:53;10695:29;10714:9;10695:29;:::i;:::-;10685:39;;10743:2;10764:38;10798:2;10787:9;10783:18;10764:38;:::i;:::-;10754:48;;10849:2;10838:9;10834:18;10821:32;10811:42;;10904:2;10893:9;10889:18;10876:32;10927:18;10968:2;10960:6;10957:14;10954:34;;;10984:1;10981;10974:12;10954:34;11022:6;11011:9;11007:22;10997:32;;11067:7;11060:4;11056:2;11052:13;11048:27;11038:55;;11089:1;11086;11079:12;11038:55;11125:2;11112:16;11147:2;11143;11140:10;11137:36;;;11153:18;;:::i;:::-;11195:53;11238:2;11219:13;;-1:-1:-1;;11215:27:1;11211:36;;11195:53;:::i;:::-;11182:66;;11271:2;11264:5;11257:17;11311:7;11306:2;11301;11297;11293:11;11289:20;11286:33;11283:53;;;11332:1;11329;11322:12;11283:53;11387:2;11382;11378;11374:11;11369:2;11362:5;11358:14;11345:45;11431:1;11426:2;11421;11414:5;11410:14;11406:23;11399:34;;11452:5;11442:15;;;;;10483:980;;;;;;;:::o;12181:260::-;12249:6;12257;12310:2;12298:9;12289:7;12285:23;12281:32;12278:52;;;12326:1;12323;12316:12;12278:52;12349:29;12368:9;12349:29;:::i;:::-;12339:39;;12397:38;12431:2;12420:9;12416:18;12397:38;:::i;12446:322::-;12523:6;12531;12539;12592:2;12580:9;12571:7;12567:23;12563:32;12560:52;;;12608:1;12605;12598:12;12560:52;12644:9;12631:23;12621:33;;12701:2;12690:9;12686:18;12673:32;12663:42;;12724:38;12758:2;12747:9;12743:18;12724:38;:::i;13107:380::-;13186:1;13182:12;;;;13229;;;13250:61;;13304:4;13296:6;13292:17;13282:27;;13250:61;13357:2;13349:6;13346:14;13326:18;13323:38;13320:161;;;13403:10;13398:3;13394:20;13391:1;13384:31;13438:4;13435:1;13428:15;13466:4;13463:1;13456:15;14325:410;14527:2;14509:21;;;14566:2;14546:18;;;14539:30;14605:34;14600:2;14585:18;;14578:62;-1:-1:-1;;;14671:2:1;14656:18;;14649:44;14725:3;14710:19;;14325:410::o;14740:355::-;14942:2;14924:21;;;14981:2;14961:18;;;14954:30;15020:33;15015:2;15000:18;;14993:61;15086:2;15071:18;;14740:355::o;15442:346::-;15644:2;15626:21;;;15683:2;15663:18;;;15656:30;-1:-1:-1;;;15717:2:1;15702:18;;15695:52;15779:2;15764:18;;15442:346::o;18259:127::-;18320:10;18315:3;18311:20;18308:1;18301:31;18351:4;18348:1;18341:15;18375:4;18372:1;18365:15;18391:128;18431:3;18462:1;18458:6;18455:1;18452:13;18449:39;;;18468:18;;:::i;:::-;-1:-1:-1;18504:9:1;;18391:128::o;21187:168::-;21227:7;21293:1;21289;21285:6;21281:14;21278:1;21275:21;21270:1;21263:9;21256:17;21252:45;21249:71;;;21300:18;;:::i;:::-;-1:-1:-1;21340:9:1;;21187:168::o;21719:127::-;21780:10;21775:3;21771:20;21768:1;21761:31;21811:4;21808:1;21801:15;21835:4;21832:1;21825:15;21851:120;21891:1;21917;21907:35;;21922:18;;:::i;:::-;-1:-1:-1;21956:9:1;;21851:120::o;21976:127::-;22037:10;22032:3;22028:20;22025:1;22018:31;22068:4;22065:1;22058:15;22092:4;22089:1;22082:15;22108:135;22147:3;-1:-1:-1;;22168:17:1;;22165:43;;;22188:18;;:::i;:::-;-1:-1:-1;22235:1:1;22224:13;;22108:135::o;22248:184::-;22318:6;22371:2;22359:9;22350:7;22346:23;22342:32;22339:52;;;22387:1;22384;22377:12;22339:52;-1:-1:-1;22410:16:1;;22248:184;-1:-1:-1;22248:184:1:o;23204:125::-;23244:4;23272:1;23269;23266:8;23263:34;;;23277:18;;:::i;:::-;-1:-1:-1;23314:9:1;;23204:125::o;27975:470::-;28154:3;28192:6;28186:13;28208:53;28254:6;28249:3;28242:4;28234:6;28230:17;28208:53;:::i;:::-;28324:13;;28283:16;;;;28346:57;28324:13;28283:16;28380:4;28368:17;;28346:57;:::i;:::-;28419:20;;27975:470;-1:-1:-1;;;;27975:470:1:o;31405:399::-;31607:2;31589:21;;;31646:2;31626:18;;;31619:30;31685:34;31680:2;31665:18;;31658:62;-1:-1:-1;;;31751:2:1;31736:18;;31729:33;31794:3;31779:19;;31405:399::o;36237:414::-;36439:2;36421:21;;;36478:2;36458:18;;;36451:30;36517:34;36512:2;36497:18;;36490:62;-1:-1:-1;;;36583:2:1;36568:18;;36561:48;36641:3;36626:19;;36237:414::o;37009:112::-;37041:1;37067;37057:35;;37072:18;;:::i;:::-;-1:-1:-1;37106:9:1;;37009:112::o;37126:245::-;37193:6;37246:2;37234:9;37225:7;37221:23;37217:32;37214:52;;;37262:1;37259;37252:12;37214:52;37294:9;37288:16;37313:28;37335:5;37313:28;:::i;38552:274::-;38681:3;38719:6;38713:13;38735:53;38781:6;38776:3;38769:4;38761:6;38757:17;38735:53;:::i;:::-;38804:16;;;;;38552:274;-1:-1:-1;;38552:274:1:o;38831:786::-;39242:25;39237:3;39230:38;39212:3;39297:6;39291:13;39313:62;39368:6;39363:2;39358:3;39354:12;39347:4;39339:6;39335:17;39313:62;:::i;:::-;-1:-1:-1;;;39434:2:1;39394:16;;;39426:11;;;39419:40;39484:13;;39506:63;39484:13;39555:2;39547:11;;39540:4;39528:17;;39506:63;:::i;:::-;39589:17;39608:2;39585:26;;38831:786;-1:-1:-1;;;;38831:786:1:o;39622:489::-;-1:-1:-1;;;;;39891:15:1;;;39873:34;;39943:15;;39938:2;39923:18;;39916:43;39990:2;39975:18;;39968:34;;;40038:3;40033:2;40018:18;;40011:31;;;39816:4;;40059:46;;40085:19;;40077:6;40059:46;:::i;:::-;40051:54;39622:489;-1:-1:-1;;;;;;39622:489:1:o;40116:249::-;40185:6;40238:2;40226:9;40217:7;40213:23;40209:32;40206:52;;;40254:1;40251;40244:12;40206:52;40286:9;40280:16;40305:30;40329:5;40305:30;:::i;40370:136::-;40409:3;40437:5;40427:39;;40446:18;;:::i;:::-;-1:-1:-1;;;40482:18:1;;40370:136::o;40872:127::-;40933:10;40928:3;40924:20;40921:1;40914:31;40964:4;40961:1;40954:15;40988:4;40985:1;40978:15
Metadata Hash
ipfs://7d03e8cdca424291abcf53fa0968b1e199002c42cb6fc739a64dc8a98b5900ec