Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 3,967 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Set Approval For... | 21110672 | 50 days ago | IN | 0 ETH | 0.00010405 | ||||
Set Approval For... | 21105821 | 50 days ago | IN | 0 ETH | 0.00013625 | ||||
Set Approval For... | 21013478 | 63 days ago | IN | 0 ETH | 0.00057799 | ||||
Set Approval For... | 20704072 | 106 days ago | IN | 0 ETH | 0.00006429 | ||||
Set Approval For... | 20465495 | 140 days ago | IN | 0 ETH | 0.00009237 | ||||
Mint | 20453416 | 141 days ago | IN | 0 ETH | 0.00003928 | ||||
Set Approval For... | 20424032 | 145 days ago | IN | 0 ETH | 0.00011235 | ||||
Set Approval For... | 20002325 | 204 days ago | IN | 0 ETH | 0.00030233 | ||||
Set Approval For... | 19947113 | 212 days ago | IN | 0 ETH | 0.00035595 | ||||
Set Approval For... | 19834295 | 228 days ago | IN | 0 ETH | 0.00032236 | ||||
Set Approval For... | 19535604 | 270 days ago | IN | 0 ETH | 0.00199058 | ||||
Set Approval For... | 19239916 | 311 days ago | IN | 0 ETH | 0.00122687 | ||||
Set Approval For... | 19171555 | 321 days ago | IN | 0 ETH | 0.00152386 | ||||
Set Approval For... | 19087332 | 333 days ago | IN | 0 ETH | 0.00068052 | ||||
Set Approval For... | 19011237 | 343 days ago | IN | 0 ETH | 0.00071553 | ||||
Set Approval For... | 18727678 | 383 days ago | IN | 0 ETH | 0.00368343 | ||||
Set Approval For... | 18721797 | 384 days ago | IN | 0 ETH | 0.0056189 | ||||
Set Approval For... | 18615711 | 399 days ago | IN | 0 ETH | 0.00254752 | ||||
Set Approval For... | 18596270 | 401 days ago | IN | 0 ETH | 0.00138776 | ||||
Set Approval For... | 18408421 | 428 days ago | IN | 0 ETH | 0.00062784 | ||||
Set Approval For... | 18400984 | 429 days ago | IN | 0 ETH | 0.00061433 | ||||
Set Approval For... | 18362992 | 434 days ago | IN | 0 ETH | 0.00056399 | ||||
Set Approval For... | 18317983 | 440 days ago | IN | 0 ETH | 0.00033249 | ||||
Set Approval For... | 18296108 | 443 days ago | IN | 0 ETH | 0.00047989 | ||||
Set Approval For... | 18237251 | 452 days ago | IN | 0 ETH | 0.00049293 |
Loading...
Loading
Contract Name:
BitcoinApePunks
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-03-15 */ /** *Submitted for verification at Etherscan.io on 2022-12-28 */ // SPDX-License-Identifier: MIT // File: @openzeppelin/contracts/utils/structs/EnumerableSet.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } } // File: contracts/IOperatorFilterRegistry.sol pragma solidity ^0.8.13; interface IOperatorFilterRegistry { function isOperatorAllowed(address registrant, address operator) external view returns (bool); function register(address registrant) external; function registerAndSubscribe(address registrant, address subscription) external; function registerAndCopyEntries(address registrant, address registrantToCopy) external; function unregister(address addr) external; function updateOperator(address registrant, address operator, bool filtered) external; function updateOperators(address registrant, address[] calldata operators, bool filtered) external; function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external; function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external; function subscribe(address registrant, address registrantToSubscribe) external; function unsubscribe(address registrant, bool copyExistingEntries) external; function subscriptionOf(address addr) external returns (address registrant); function subscribers(address registrant) external returns (address[] memory); function subscriberAt(address registrant, uint256 index) external returns (address); function copyEntriesOf(address registrant, address registrantToCopy) external; function isOperatorFiltered(address registrant, address operator) external returns (bool); function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool); function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool); function filteredOperators(address addr) external returns (address[] memory); function filteredCodeHashes(address addr) external returns (bytes32[] memory); function filteredOperatorAt(address registrant, uint256 index) external returns (address); function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32); function isRegistered(address addr) external returns (bool); function codeHashOf(address addr) external returns (bytes32); } // File: contracts/OperatorFilterer.sol // OpenZeppelin Contracts (last updated v4.8.0) (access/Ownable2Step.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership} and {acceptOwnership}. * * This module is used through inheritance. It will make available all functions * from parent (Ownable). */ pragma solidity ^0.8.13; /** * @title OwnedRegistrant * @notice Ownable contract that registers itself with the OperatorFilterRegistry and administers its own entries, * to facilitate a subscription whose ownership can be transferred. */ pragma solidity ^0.8.13; contract OperatorFilterRegistryErrorsAndEvents { error CannotFilterEOAs(); error AddressAlreadyFiltered(address operator); error AddressNotFiltered(address operator); error CodeHashAlreadyFiltered(bytes32 codeHash); error CodeHashNotFiltered(bytes32 codeHash); error OnlyAddressOrOwner(); error NotRegistered(address registrant); error AlreadyRegistered(); error AlreadySubscribed(address subscription); error NotSubscribed(); error CannotUpdateWhileSubscribed(address subscription); error CannotSubscribeToSelf(); error CannotSubscribeToZeroAddress(); error NotOwnable(); error AddressFiltered(address filtered); error CodeHashFiltered(address account, bytes32 codeHash); error CannotSubscribeToRegistrantWithSubscription(address registrant); error CannotCopyFromSelf(); event RegistrationUpdated(address indexed registrant, bool indexed registered); event OperatorUpdated(address indexed registrant, address indexed operator, bool indexed filtered); event OperatorsUpdated(address indexed registrant, address[] operators, bool indexed filtered); event CodeHashUpdated(address indexed registrant, bytes32 indexed codeHash, bool indexed filtered); event CodeHashesUpdated(address indexed registrant, bytes32[] codeHashes, bool indexed filtered); event SubscriptionUpdated(address indexed registrant, address indexed subscription, bool indexed subscribed); } pragma solidity ^0.8.13; /** * @title OperatorFilterRegistry * @notice Borrows heavily from the QQL BlacklistOperatorFilter contract: * https://github.com/qql-art/contracts/blob/main/contracts/BlacklistOperatorFilter.sol * @notice This contracts allows tokens or token owners to register specific addresses or codeHashes that may be * * restricted according to the isOperatorAllowed function. */ contract OperatorFilterRegistry is IOperatorFilterRegistry, OperatorFilterRegistryErrorsAndEvents { using EnumerableSet for EnumerableSet.AddressSet; using EnumerableSet for EnumerableSet.Bytes32Set; /// @dev initialized accounts have a nonzero codehash (see https://eips.ethereum.org/EIPS/eip-1052) /// Note that this will also be a smart contract's codehash when making calls from its constructor. bytes32 constant EOA_CODEHASH = keccak256(""); mapping(address => EnumerableSet.AddressSet) private _filteredOperators; mapping(address => EnumerableSet.Bytes32Set) private _filteredCodeHashes; mapping(address => address) private _registrations; mapping(address => EnumerableSet.AddressSet) private _subscribers; /** * @notice restricts method caller to the address or EIP-173 "owner()" */ modifier onlyAddressOrOwner(address addr) { if (msg.sender != addr) { try Ownable(addr).owner() returns (address owner) { if (msg.sender != owner) { revert OnlyAddressOrOwner(); } } catch (bytes memory reason) { if (reason.length == 0) { revert NotOwnable(); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } _; } /** * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns * true if supplied registrant address is not registered. */ function isOperatorAllowed(address registrant, address operator) external view returns (bool) { address registration = _registrations[registrant]; if (registration != address(0)) { EnumerableSet.AddressSet storage filteredOperatorsRef; EnumerableSet.Bytes32Set storage filteredCodeHashesRef; filteredOperatorsRef = _filteredOperators[registration]; filteredCodeHashesRef = _filteredCodeHashes[registration]; if (filteredOperatorsRef.contains(operator)) { revert AddressFiltered(operator); } if (operator.code.length > 0) { bytes32 codeHash = operator.codehash; if (filteredCodeHashesRef.contains(codeHash)) { revert CodeHashFiltered(operator, codeHash); } } } return true; } ////////////////// // AUTH METHODS // ////////////////// /** * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner. */ function register(address registrant) external onlyAddressOrOwner(registrant) { if (_registrations[registrant] != address(0)) { revert AlreadyRegistered(); } _registrations[registrant] = registrant; emit RegistrationUpdated(registrant, true); } /** * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner. * Note that this does not remove any filtered addresses or codeHashes. * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes. */ function unregister(address registrant) external onlyAddressOrOwner(registrant) { address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration != registrant) { _subscribers[registration].remove(registrant); emit SubscriptionUpdated(registrant, registration, false); } _registrations[registrant] = address(0); emit RegistrationUpdated(registrant, false); } /** * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes. */ function registerAndSubscribe(address registrant, address subscription) external onlyAddressOrOwner(registrant) { address registration = _registrations[registrant]; if (registration != address(0)) { revert AlreadyRegistered(); } if (registrant == subscription) { revert CannotSubscribeToSelf(); } address subscriptionRegistration = _registrations[subscription]; if (subscriptionRegistration == address(0)) { revert NotRegistered(subscription); } if (subscriptionRegistration != subscription) { revert CannotSubscribeToRegistrantWithSubscription(subscription); } _registrations[registrant] = subscription; _subscribers[subscription].add(registrant); emit RegistrationUpdated(registrant, true); emit SubscriptionUpdated(registrant, subscription, true); } /** * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another * address without subscribing. */ function registerAndCopyEntries(address registrant, address registrantToCopy) external onlyAddressOrOwner(registrant) { if (registrantToCopy == registrant) { revert CannotCopyFromSelf(); } address registration = _registrations[registrant]; if (registration != address(0)) { revert AlreadyRegistered(); } address registrantRegistration = _registrations[registrantToCopy]; if (registrantRegistration == address(0)) { revert NotRegistered(registrantToCopy); } _registrations[registrant] = registrant; emit RegistrationUpdated(registrant, true); _copyEntries(registrant, registrantToCopy); } /** * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered. */ function updateOperator(address registrant, address operator, bool filtered) external onlyAddressOrOwner(registrant) { address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration != registrant) { revert CannotUpdateWhileSubscribed(registration); } EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant]; if (!filtered) { bool removed = filteredOperatorsRef.remove(operator); if (!removed) { revert AddressNotFiltered(operator); } } else { bool added = filteredOperatorsRef.add(operator); if (!added) { revert AddressAlreadyFiltered(operator); } } emit OperatorUpdated(registrant, operator, filtered); } /** * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered. */ function updateCodeHash(address registrant, bytes32 codeHash, bool filtered) external onlyAddressOrOwner(registrant) { if (codeHash == EOA_CODEHASH) { revert CannotFilterEOAs(); } address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration != registrant) { revert CannotUpdateWhileSubscribed(registration); } EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant]; if (!filtered) { bool removed = filteredCodeHashesRef.remove(codeHash); if (!removed) { revert CodeHashNotFiltered(codeHash); } } else { bool added = filteredCodeHashesRef.add(codeHash); if (!added) { revert CodeHashAlreadyFiltered(codeHash); } } emit CodeHashUpdated(registrant, codeHash, filtered); } /** * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates. */ function updateOperators(address registrant, address[] calldata operators, bool filtered) external onlyAddressOrOwner(registrant) { address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration != registrant) { revert CannotUpdateWhileSubscribed(registration); } EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant]; uint256 operatorsLength = operators.length; unchecked { if (!filtered) { for (uint256 i = 0; i < operatorsLength; ++i) { address operator = operators[i]; bool removed = filteredOperatorsRef.remove(operator); if (!removed) { revert AddressNotFiltered(operator); } } } else { for (uint256 i = 0; i < operatorsLength; ++i) { address operator = operators[i]; bool added = filteredOperatorsRef.add(operator); if (!added) { revert AddressAlreadyFiltered(operator); } } } } emit OperatorsUpdated(registrant, operators, filtered); } /** * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates. */ function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external onlyAddressOrOwner(registrant) { address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration != registrant) { revert CannotUpdateWhileSubscribed(registration); } EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant]; uint256 codeHashesLength = codeHashes.length; unchecked { if (!filtered) { for (uint256 i = 0; i < codeHashesLength; ++i) { bytes32 codeHash = codeHashes[i]; bool removed = filteredCodeHashesRef.remove(codeHash); if (!removed) { revert CodeHashNotFiltered(codeHash); } } } else { for (uint256 i = 0; i < codeHashesLength; ++i) { bytes32 codeHash = codeHashes[i]; if (codeHash == EOA_CODEHASH) { revert CannotFilterEOAs(); } bool added = filteredCodeHashesRef.add(codeHash); if (!added) { revert CodeHashAlreadyFiltered(codeHash); } } } } emit CodeHashesUpdated(registrant, codeHashes, filtered); } /** * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous * subscription if present. * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case, * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be * used. */ function subscribe(address registrant, address newSubscription) external onlyAddressOrOwner(registrant) { if (registrant == newSubscription) { revert CannotSubscribeToSelf(); } if (newSubscription == address(0)) { revert CannotSubscribeToZeroAddress(); } address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration == newSubscription) { revert AlreadySubscribed(newSubscription); } address newSubscriptionRegistration = _registrations[newSubscription]; if (newSubscriptionRegistration == address(0)) { revert NotRegistered(newSubscription); } if (newSubscriptionRegistration != newSubscription) { revert CannotSubscribeToRegistrantWithSubscription(newSubscription); } if (registration != registrant) { _subscribers[registration].remove(registrant); emit SubscriptionUpdated(registrant, registration, false); } _registrations[registrant] = newSubscription; _subscribers[newSubscription].add(registrant); emit SubscriptionUpdated(registrant, newSubscription, true); } /** * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes. */ function unsubscribe(address registrant, bool copyExistingEntries) external onlyAddressOrOwner(registrant) { address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration == registrant) { revert NotSubscribed(); } _subscribers[registration].remove(registrant); _registrations[registrant] = registrant; emit SubscriptionUpdated(registrant, registration, false); if (copyExistingEntries) { _copyEntries(registrant, registration); } } /** * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr. */ function copyEntriesOf(address registrant, address registrantToCopy) external onlyAddressOrOwner(registrant) { if (registrant == registrantToCopy) { revert CannotCopyFromSelf(); } address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration != registrant) { revert CannotUpdateWhileSubscribed(registration); } address registrantRegistration = _registrations[registrantToCopy]; if (registrantRegistration == address(0)) { revert NotRegistered(registrantToCopy); } _copyEntries(registrant, registrantToCopy); } /// @dev helper to copy entries from registrantToCopy to registrant and emit events function _copyEntries(address registrant, address registrantToCopy) private { EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrantToCopy]; EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrantToCopy]; uint256 filteredOperatorsLength = filteredOperatorsRef.length(); uint256 filteredCodeHashesLength = filteredCodeHashesRef.length(); unchecked { for (uint256 i = 0; i < filteredOperatorsLength; ++i) { address operator = filteredOperatorsRef.at(i); bool added = _filteredOperators[registrant].add(operator); if (added) { emit OperatorUpdated(registrant, operator, true); } } for (uint256 i = 0; i < filteredCodeHashesLength; ++i) { bytes32 codehash = filteredCodeHashesRef.at(i); bool added = _filteredCodeHashes[registrant].add(codehash); if (added) { emit CodeHashUpdated(registrant, codehash, true); } } } } ////////////////// // VIEW METHODS // ////////////////// /** * @notice Get the subscription address of a given registrant, if any. */ function subscriptionOf(address registrant) external view returns (address subscription) { subscription = _registrations[registrant]; if (subscription == address(0)) { revert NotRegistered(registrant); } else if (subscription == registrant) { subscription = address(0); } } /** * @notice Get the set of addresses subscribed to a given registrant. * Note that order is not guaranteed as updates are made. */ function subscribers(address registrant) external view returns (address[] memory) { return _subscribers[registrant].values(); } /** * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant. * Note that order is not guaranteed as updates are made. */ function subscriberAt(address registrant, uint256 index) external view returns (address) { return _subscribers[registrant].at(index); } /** * @notice Returns true if operator is filtered by a given address or its subscription. */ function isOperatorFiltered(address registrant, address operator) external view returns (bool) { address registration = _registrations[registrant]; if (registration != registrant) { return _filteredOperators[registration].contains(operator); } return _filteredOperators[registrant].contains(operator); } /** * @notice Returns true if a codeHash is filtered by a given address or its subscription. */ function isCodeHashFiltered(address registrant, bytes32 codeHash) external view returns (bool) { address registration = _registrations[registrant]; if (registration != registrant) { return _filteredCodeHashes[registration].contains(codeHash); } return _filteredCodeHashes[registrant].contains(codeHash); } /** * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription. */ function isCodeHashOfFiltered(address registrant, address operatorWithCode) external view returns (bool) { bytes32 codeHash = operatorWithCode.codehash; address registration = _registrations[registrant]; if (registration != registrant) { return _filteredCodeHashes[registration].contains(codeHash); } return _filteredCodeHashes[registrant].contains(codeHash); } /** * @notice Returns true if an address has registered */ function isRegistered(address registrant) external view returns (bool) { return _registrations[registrant] != address(0); } /** * @notice Returns a list of filtered operators for a given address or its subscription. */ function filteredOperators(address registrant) external view returns (address[] memory) { address registration = _registrations[registrant]; if (registration != registrant) { return _filteredOperators[registration].values(); } return _filteredOperators[registrant].values(); } /** * @notice Returns the set of filtered codeHashes for a given address or its subscription. * Note that order is not guaranteed as updates are made. */ function filteredCodeHashes(address registrant) external view returns (bytes32[] memory) { address registration = _registrations[registrant]; if (registration != registrant) { return _filteredCodeHashes[registration].values(); } return _filteredCodeHashes[registrant].values(); } /** * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or * its subscription. * Note that order is not guaranteed as updates are made. */ function filteredOperatorAt(address registrant, uint256 index) external view returns (address) { address registration = _registrations[registrant]; if (registration != registrant) { return _filteredOperators[registration].at(index); } return _filteredOperators[registrant].at(index); } /** * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or * its subscription. * Note that order is not guaranteed as updates are made. */ function filteredCodeHashAt(address registrant, uint256 index) external view returns (bytes32) { address registration = _registrations[registrant]; if (registration != registrant) { return _filteredCodeHashes[registration].at(index); } return _filteredCodeHashes[registrant].at(index); } /// @dev Convenience method to compute the code hash of an arbitrary contract function codeHashOf(address a) external view returns (bytes32) { return a.codehash; } } pragma solidity ^0.8.13; abstract contract OperatorFilterer { error OperatorNotAllowed(address operator); IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); constructor(address subscriptionOrRegistrantToCopy, bool subscribe) { // If an inheriting token contract is deployed to a network without the registry deployed, the modifier // will not revert, but the contract will need to be registered with the registry once it is deployed in // order for the modifier to filter addresses. if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { if (subscribe) { OPERATOR_FILTER_REGISTRY.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy); } else { if (subscriptionOrRegistrantToCopy != address(0)) { OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy); } else { OPERATOR_FILTER_REGISTRY.register(address(this)); } } } } modifier onlyAllowedOperator(address from) virtual { // Allow spending tokens from addresses with balance // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred // from an EOA. if (from != msg.sender) { _checkFilterOperator(msg.sender); } _; } modifier onlyAllowedOperatorApproval(address operator) virtual { _checkFilterOperator(operator); _; } function _checkFilterOperator(address operator) internal view virtual { // Check registry code length to facilitate testing in environments without a deployed registry. if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) { revert OperatorNotAllowed(operator); } } } } // File: contracts/DefaultOperatorFilterer.sol pragma solidity ^0.8.13; /** * @title DefaultOperatorFilterer * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription. */ abstract contract DefaultOperatorFilterer is OperatorFilterer { address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {} } // File: @openzeppelin/contracts/utils/math/Math.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @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. If 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)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 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) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _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) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @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] = _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); } } // File: @openzeppelin/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or 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 { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @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); } // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) // File: @openzeppelin/contracts/utils/introspection/ERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } pragma solidity ^0.8.0; /** * @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; } } // File: @openzeppelin/contracts/token/ERC721/IERC721.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; /** * @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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * 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); } // File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; /** * @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); } // File: @openzeppelin/contracts/utils/Context.sol pragma solidity ^0.8.0; interface IERC721Enumerable is IERC721 { function totalSupply() external view returns (uint256); function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); function tokenByIndex(uint256 index) external view returns (uint256); } pragma solidity ^0.8.0; abstract contract ReentrancyGuard { uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } modifier nonReentrant() { require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); _status = _ENTERED; _; _status = _NOT_ENTERED; } } // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @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; } } // File: @openzeppelin/contracts/token/ERC721/ERC721.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; error ApprovalCallerNotOwnerNorApproved(); error ApprovalQueryForNonexistentToken(); error ApproveToCaller(); error ApprovalToCurrentOwner(); error BalanceQueryForZeroAddress(); error MintToZeroAddress(); error MintZeroQuantity(); error OwnerQueryForNonexistentToken(); error TransferCallerNotOwnerNorApproved(); error TransferFromIncorrectOwner(); error TransferToNonERC721ReceiverImplementer(); error TransferToZeroAddress(); error URIQueryForNonexistentToken(); /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension. Built to optimize for lower gas during batch mints. * * Assumes serials are sequentially minted starting at _startTokenId() (defaults to 0, e.g. 0, 1, 2, 3..). * * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable, DefaultOperatorFilterer { using Address for address; using Strings for uint256; // Compiler will pack this into a single 256bit word. struct TokenOwnership { // The address of the owner. address addr; // Keeps track of the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; } // Compiler will pack this into a single 256bit word. struct AddressData { // Realistically, 2**64-1 is more than enough. uint64 balance; // Keeps track of mint count with minimal overhead for tokenomics. uint64 numberMinted; // Keeps track of burn count with minimal overhead for tokenomics. uint64 numberBurned; // For miscellaneous variable(s) pertaining to the address // (e.g. number of whitelist mint slots used). // If there are multiple variables, please pack them into a uint64. uint64 aux; } // The tokenId of the next token to be minted. uint256 internal _currentIndex; // The number of tokens burned. uint256 internal _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. See _ownershipOf implementation for details. mapping(uint256 => TokenOwnership) internal _ownerships; // Mapping owner address to address data mapping(address => AddressData) private _addressData; // 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; constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); } /** * To change the starting tokenId, please override this function. */ function _startTokenId() internal view virtual returns (uint256) { return 0; } /** * @dev Burned tokens are calculated here, use _totalMinted() if you want to count just minted tokens. */ function totalSupply() public view returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than _currentIndex - _startTokenId() times unchecked { return _currentIndex - _burnCounter - _startTokenId(); } } function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) { require(index < balanceOf(owner), "ERC721A: owner index out of bounds"); uint256 numMintedSoFar = totalSupply(); uint256 tokenIdsIdx; address currOwnershipAddr; unchecked { for (uint256 i; i < numMintedSoFar; i++) { TokenOwnership memory ownership = _ownerships[i]; if (ownership.addr != address(0)) { currOwnershipAddr = ownership.addr; } if (currOwnershipAddr == owner) { if (tokenIdsIdx == index) { return i; } tokenIdsIdx++; } } } revert("ERC721A: unable to get token of owner by index"); } function tokenByIndex(uint256 index) public view override returns (uint256) { require(index < totalSupply(), "ERC721A: global index out of bounds"); return index; } /** * Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view returns (uint256) { // Counter underflow is impossible as _currentIndex does not decrement, // and it is initialized to _startTokenId() unchecked { return _currentIndex - _startTokenId(); } } /** * @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 || interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view override returns (uint256) { if (owner == address(0)) revert BalanceQueryForZeroAddress(); return uint256(_addressData[owner].balance); } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return uint256(_addressData[owner].numberMinted); } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return uint256(_addressData[owner].numberBurned); } /** * Returns the auxillary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return _addressData[owner].aux; } /** * Sets the auxillary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal { _addressData[owner].aux = aux; } /** * Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around in the collection over time. */ function _ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) { uint256 curr = tokenId; unchecked { if (_startTokenId() <= curr && curr < _currentIndex) { TokenOwnership memory ownership = _ownerships[curr]; if (!ownership.burned) { if (ownership.addr != address(0)) { return ownership; } // Invariant: // There will always be an ownership that has an address and is not burned // before an ownership that does not have an address and is not burned. // Hence, curr will not underflow. while (true) { curr--; ownership = _ownerships[curr]; if (ownership.addr != address(0)) { return ownership; } } } } } revert OwnerQueryForNonexistentToken(); } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view override returns (address) { return _ownershipOf(tokenId).addr; } /** * @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) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ''; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overriden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override onlyAllowedOperator(to) { address owner = ERC721A.ownerOf(tokenId); require(to != owner, "ERC721A: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721A: approve caller is not owner nor approved for all" ); _approve(to, tokenId, owner); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override onlyAllowedOperator(operator) { require(operator != _msgSender(), "ERC721A: approve to caller"); _operatorApprovals[_msgSender()][operator] = approved; emit ApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override onlyAllowedOperator(from){ _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override onlyAllowedOperator(from) { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public virtual override onlyAllowedOperator(from){ _transfer(from, to, tokenId); if (to.isContract() && !_checkContractOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @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`), */ function _exists(uint256 tokenId) internal view returns (bool) { return _startTokenId() <= tokenId && tokenId < _currentIndex && !_ownerships[tokenId].burned; } function _safeMint(address to, uint256 quantity) internal { _safeMint(to, quantity, ''); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * Emits a {Transfer} event. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal { _mint(to, quantity, _data, true); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event. */ function _mint( address to, uint256 quantity, bytes memory _data, bool safe ) internal { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1 // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1 unchecked { _addressData[to].balance += uint64(quantity); _addressData[to].numberMinted += uint64(quantity); _ownerships[startTokenId].addr = to; _ownerships[startTokenId].startTimestamp = uint64(block.timestamp); uint256 updatedIndex = startTokenId; uint256 end = updatedIndex + quantity; if (safe && to.isContract()) { do { emit Transfer(address(0), to, updatedIndex); if (!_checkContractOnERC721Received(address(0), to, updatedIndex++, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } while (updatedIndex != end); // Reentrancy protection if (_currentIndex != startTokenId) revert(); } else { do { emit Transfer(address(0), to, updatedIndex++); } while (updatedIndex != end); } _currentIndex = updatedIndex; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Transfers `tokenId` from `from` to `to`. * * 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 ) private { TokenOwnership memory prevOwnership = _ownershipOf(tokenId); if (prevOwnership.addr != from) revert TransferFromIncorrectOwner(); bool isApprovedOrOwner = (_msgSender() == from || isApprovedForAll(from, _msgSender()) || getApproved(tokenId) == _msgSender()); if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved(); if (to == address(0)) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner _approve(address(0), tokenId, from); // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256. unchecked { _addressData[from].balance -= 1; _addressData[to].balance += 1; TokenOwnership storage currSlot = _ownerships[tokenId]; currSlot.addr = to; currSlot.startTimestamp = uint64(block.timestamp); // If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it. // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls. uint256 nextTokenId = tokenId + 1; TokenOwnership storage nextSlot = _ownerships[nextTokenId]; if (nextSlot.addr == address(0)) { // This will suffice for checking _exists(nextTokenId), // as a burned slot cannot contain the zero address. if (nextTokenId != _currentIndex) { nextSlot.addr = from; nextSlot.startTimestamp = prevOwnership.startTimestamp; } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev This is equivalent to _burn(tokenId, false) */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { TokenOwnership memory prevOwnership = _ownershipOf(tokenId); address from = prevOwnership.addr; if (approvalCheck) { bool isApprovedOrOwner = (_msgSender() == from || isApprovedForAll(from, _msgSender()) || getApproved(tokenId) == _msgSender()); if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved(); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner _approve(address(0), tokenId, from); // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256. unchecked { AddressData storage addressData = _addressData[from]; addressData.balance -= 1; addressData.numberBurned += 1; // Keep track of who burned the token, and the timestamp of burning. TokenOwnership storage currSlot = _ownerships[tokenId]; currSlot.addr = from; currSlot.startTimestamp = uint64(block.timestamp); currSlot.burned = true; // If the ownership slot of tokenId+1 is not explicitly set, that means the burn initiator owns it. // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls. uint256 nextTokenId = tokenId + 1; TokenOwnership storage nextSlot = _ownerships[nextTokenId]; if (nextSlot.addr == address(0)) { // This will suffice for checking _exists(nextTokenId), // as a burned slot cannot contain the zero address. if (nextTokenId != _currentIndex) { nextSlot.addr = from; nextSlot.startTimestamp = prevOwnership.startTimestamp; } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { _burnCounter++; } } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve( address to, uint256 tokenId, address owner ) private { _tokenApprovals[tokenId] = to; emit Approval(owner, to, tokenId); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target 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 _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) { return retval == IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } /** * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting. * And also called before burning one token. * * startTokenId - the first token id to be transferred * quantity - the amount to be transferred * * 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, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes * minting. * And also called after one token has been burned. * * startTokenId - the first token id to be transferred * quantity - the amount to be transferred * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} } /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } abstract contract Ownable2Step is Ownable { address private _pendingOwner; event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); /** * @dev Returns the address of the pending owner. */ function pendingOwner() public view virtual returns (address) { return _pendingOwner; } /** * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual override onlyOwner { _pendingOwner = newOwner; emit OwnershipTransferStarted(owner(), newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual override { delete _pendingOwner; super._transferOwnership(newOwner); } /** * @dev The new owner accepts the ownership transfer. */ function acceptOwnership() external { address sender = _msgSender(); require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner"); _transferOwnership(sender); } } contract OwnedRegistrant is Ownable2Step { address constant registry = 0x000000000000AAeB6D7670E522A718067333cd4E; constructor(address _owner) { IOperatorFilterRegistry(registry).register(address(this)); transferOwnership(_owner); } } pragma solidity ^0.8.13; /** * @title UpdatableOperatorFilterer * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another * registrant's entries in the OperatorFilterRegistry. This contract allows the Owner to update the * OperatorFilterRegistry address via updateOperatorFilterRegistryAddress, including to the zero address, * which will bypass registry checks. * Note that OpenSea will still disable creator fee enforcement if filtered operators begin fulfilling orders * on-chain, eg, if the registry is revoked or bypassed. * @dev This smart contract is meant to be inherited by token contracts so they can use the following: * - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods. * - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods. */ abstract contract UpdatableOperatorFilterer { error OperatorNotAllowed(address operator); error OnlyOwner(); IOperatorFilterRegistry public operatorFilterRegistry; constructor(address _registry, address subscriptionOrRegistrantToCopy, bool subscribe) { IOperatorFilterRegistry registry = IOperatorFilterRegistry(_registry); operatorFilterRegistry = registry; // If an inheriting token contract is deployed to a network without the registry deployed, the modifier // will not revert, but the contract will need to be registered with the registry once it is deployed in // order for the modifier to filter addresses. if (address(registry).code.length > 0) { if (subscribe) { registry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy); } else { if (subscriptionOrRegistrantToCopy != address(0)) { registry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy); } else { registry.register(address(this)); } } } } modifier onlyAllowedOperator(address from) virtual { // Allow spending tokens from addresses with balance // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred // from an EOA. if (from != msg.sender) { _checkFilterOperator(msg.sender); } _; } modifier onlyAllowedOperatorApproval(address operator) virtual { _checkFilterOperator(operator); _; } /** * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero * address, checks will be bypassed. OnlyOwner. */ function updateOperatorFilterRegistryAddress(address newRegistry) public virtual { if (msg.sender != owner()) { revert OnlyOwner(); } operatorFilterRegistry = IOperatorFilterRegistry(newRegistry); } /** * @dev assume the contract has an owner, but leave specific Ownable implementation up to inheriting contract */ function owner() public view virtual returns (address); function _checkFilterOperator(address operator) internal view virtual { IOperatorFilterRegistry registry = operatorFilterRegistry; // Check registry code length to facilitate testing in environments without a deployed registry. if (address(registry) != address(0) && address(registry).code.length > 0) { if (!registry.isOperatorAllowed(address(this), operator)) { revert OperatorNotAllowed(operator); } } } } pragma solidity ^0.8.13; /** * @title RevokableOperatorFilterer * @notice This contract is meant to allow contracts to permanently skip OperatorFilterRegistry checks if desired. The * Registry itself has an "unregister" function, but if the contract is ownable, the owner can re-register at * any point. As implemented, this abstract contract allows the contract owner to permanently skip the * OperatorFilterRegistry checks by calling revokeOperatorFilterRegistry. Once done, the registry * address cannot be further updated. * Note that OpenSea will still disable creator fee enforcement if filtered operators begin fulfilling orders * on-chain, eg, if the registry is revoked or bypassed. */ abstract contract RevokableOperatorFilterer is UpdatableOperatorFilterer { error RegistryHasBeenRevoked(); error InitialRegistryAddressCannotBeZeroAddress(); bool public isOperatorFilterRegistryRevoked; constructor(address _registry, address subscriptionOrRegistrantToCopy, bool subscribe) UpdatableOperatorFilterer(_registry, subscriptionOrRegistrantToCopy, subscribe) { // don't allow creating a contract with a permanently revoked registry if (_registry == address(0)) { revert InitialRegistryAddressCannotBeZeroAddress(); } } function _checkFilterOperator(address operator) internal view virtual override { if (address(operatorFilterRegistry) != address(0)) { super._checkFilterOperator(operator); } } /** * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero * address, checks will be permanently bypassed, and the address cannot be updated again. OnlyOwner. */ function updateOperatorFilterRegistryAddress(address newRegistry) public override { if (msg.sender != owner()) { revert OnlyOwner(); } // if registry has been revoked, do not allow further updates if (isOperatorFilterRegistryRevoked) { revert RegistryHasBeenRevoked(); } operatorFilterRegistry = IOperatorFilterRegistry(newRegistry); } /** * @notice Revoke the OperatorFilterRegistry address, permanently bypassing checks. OnlyOwner. */ function revokeOperatorFilterRegistry() public { if (msg.sender != owner()) { revert OnlyOwner(); } // if registry has been revoked, do not allow further updates if (isOperatorFilterRegistryRevoked) { revert RegistryHasBeenRevoked(); } // set to zero address to bypass checks operatorFilterRegistry = IOperatorFilterRegistry(address(0)); isOperatorFilterRegistryRevoked = true; } } pragma solidity ^0.8.13; /** * @title RevokableDefaultOperatorFilterer * @notice Inherits from RevokableOperatorFilterer and automatically subscribes to the default OpenSea subscription. * Note that OpenSea will disable creator fee enforcement if filtered operators begin fulfilling orders * on-chain, eg, if the registry is revoked or bypassed. */ abstract contract RevokableDefaultOperatorFilterer is RevokableOperatorFilterer { address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); constructor() RevokableOperatorFilterer(0x000000000000AAeB6D7670E522A718067333cd4E, DEFAULT_SUBSCRIPTION, true) {} } pragma solidity ^0.8.9; contract BitcoinApePunks is ERC721A, Ownable, ReentrancyGuard { using Strings for uint256; uint public price = 0.0069 ether; uint public maxTx = 20; uint public maxSupply = 10000; uint256 public reservedSupply = 100; string private baseURI; bool public mintEnabled; uint public maxPerFree = 1; uint public totalFreeMinted = 0; uint public totalFree = 10000; uint256 public bridgeFee; bool public inscriptionPhaseActive = false; mapping(address => uint256) public _FreeMinted; constructor() ERC721A("Bitcoin Ape Punks", "BAP") {} function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) { require(_exists(_tokenId),"ERC721Metadata: URI query for nonexistent token"); string memory currentBaseURI = _baseURI(); return bytes(currentBaseURI).length > 0 ? string(abi.encodePacked(currentBaseURI,Strings.toString(_tokenId),".json")) : ""; } function _baseURI() internal view virtual override returns (string memory) { return baseURI; } function mint(uint256 count) external payable { bool MintForFree = ((totalFreeMinted < totalFree) && (_FreeMinted[msg.sender] < maxPerFree)); if (MintForFree) { require(mintEnabled, "Mint is not live yet"); require(totalSupply() + count <= maxSupply, "No more"); require(count <= maxTx, "Max per TX reached."); if(count >= (maxPerFree - _FreeMinted[msg.sender])) { require(msg.value >= (count * price) - ((maxPerFree - _FreeMinted[msg.sender]) * price), "Please send the exact ETH amount"); _FreeMinted[msg.sender] = maxPerFree; totalFreeMinted += maxPerFree; } else if(count < (maxPerFree - _FreeMinted[msg.sender])) { require(msg.value >= 0, "Please send the exact ETH amount"); _FreeMinted[msg.sender] += count; totalFreeMinted += count; } } else{ require(mintEnabled, "Mint is not live yet"); require(msg.value >= count * price, "Please send the exact ETH amount"); require(totalSupply() + count <= maxSupply, "No more"); require(count <= maxTx, "Max per TX reached."); } _safeMint(msg.sender, count); } function reservedMint(uint256 Amount) external onlyOwner { uint256 Remaining = reservedSupply; require(totalSupply() + Amount <= maxSupply, "No more supply to be minted"); require(Remaining >= Amount, "Reserved Supply Minted"); reservedSupply = Remaining - Amount; _safeMint(msg.sender, Amount); // totalSupply() += Amount; } function toggleMinting() external onlyOwner { mintEnabled = !mintEnabled; } function setBridgeFee(uint256 _fee) public onlyOwner { bridgeFee = _fee; } function toggleInscriptionsActive() public onlyOwner { inscriptionPhaseActive = !inscriptionPhaseActive; } function bridge(uint256 _tokenId) public payable { require(ownerOf(_tokenId) == msg.sender, "You do not own this token."); require(msg.value >= bridgeFee, "Insufficient fee to inscribe this token to ordinal BTC."); _burn(_tokenId); } function bridgeMultiple(uint256[] calldata tokenIds) public payable { require(msg.value >= (tokenIds.length * bridgeFee), "Insufficient fee to inscribe this token to ordinal BTC."); for (uint i = 0; i < tokenIds.length; i++) { require(ownerOf(tokenIds[i]) == msg.sender, "You do not own this token."); _burn(tokenIds[i]); } } function burnUnbridgedTokens(uint256[] calldata tokenIds) public onlyOwner { for (uint i = 0; i < tokenIds.length; i++) { require(_exists(tokenIds[i]), "Token does not exist"); _burn(tokenIds[i]); } } function setBaseUri(string memory baseuri_) public onlyOwner { baseURI = baseuri_; } function setCost(uint256 price_) external onlyOwner { price = price_; } function costInspect() public view returns (uint256) { return price; } function setmaxTx(uint256 _MaxTx) external onlyOwner { maxTx = _MaxTx; } function setMaxTotalFree(uint256 MaxTotalFree_) external onlyOwner { totalFree = MaxTotalFree_; } function setMaxPerFree(uint256 MaxPerFree_) external onlyOwner { maxPerFree = MaxPerFree_; } function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) { super.setApprovalForAll(operator, approved); } function approve(address operator, uint256 tokenId) public override onlyAllowedOperatorApproval(operator) { super.approve(operator, tokenId); } function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { super.transferFrom(from, to, tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public override onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId, data); } function withdraw() external onlyOwner nonReentrant { (bool success, ) = msg.sender.call{value: address(this).balance}(""); require(success, "Transfer failed."); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"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":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_FreeMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","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":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"bridge","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"bridgeFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"bridgeMultiple","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"burnUnbridgedTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"costInspect","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"inscriptionPhaseActive","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":[],"name":"maxPerFree","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"Amount","type":"uint256"}],"name":"reservedMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reservedSupply","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":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseuri_","type":"string"}],"name":"setBaseUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setBridgeFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"price_","type":"uint256"}],"name":"setCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"MaxPerFree_","type":"uint256"}],"name":"setMaxPerFree","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"MaxTotalFree_","type":"uint256"}],"name":"setMaxTotalFree","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_MaxTx","type":"uint256"}],"name":"setmaxTx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleInscriptionsActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleMinting","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":"totalFree","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFreeMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040526618838370f34000600a556014600b55612710600c556064600d55600160105560006011556127106012556000601460006101000a81548160ff0219169083151502179055503480156200005757600080fd5b506040518060400160405280601181526020017f426974636f696e204170652050756e6b730000000000000000000000000000008152506040518060400160405280600381526020017f4241500000000000000000000000000000000000000000000000000000000000815250733cc6cdda760b79bafa08df41ecfa224f810dceb6600160006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115620002d057801562000196576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b81526004016200015c92919062000454565b600060405180830381600087803b1580156200017757600080fd5b505af11580156200018c573d6000803e3d6000fd5b50505050620002cf565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161462000250576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b81526004016200021692919062000454565b600060405180830381600087803b1580156200023157600080fd5b505af115801562000246573d6000803e3d6000fd5b50505050620002ce565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b815260040162000299919062000481565b600060405180830381600087803b158015620002b457600080fd5b505af1158015620002c9573d6000803e3d6000fd5b505050505b5b5b50508160029081620002e3919062000718565b508060039081620002f5919062000718565b50620003066200033c60201b60201c565b60008190555050506200032e620003226200034160201b60201c565b6200034960201b60201c565b6001600981905550620007ff565b600090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200043c826200040f565b9050919050565b6200044e816200042f565b82525050565b60006040820190506200046b600083018562000443565b6200047a602083018462000443565b9392505050565b600060208201905062000498600083018462000443565b92915050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200052057607f821691505b602082108103620005365762000535620004d8565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620005a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000561565b620005ac868362000561565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620005f9620005f3620005ed84620005c4565b620005ce565b620005c4565b9050919050565b6000819050919050565b6200061583620005d8565b6200062d620006248262000600565b8484546200056e565b825550505050565b600090565b6200064462000635565b620006518184846200060a565b505050565b5b8181101562000679576200066d6000826200063a565b60018101905062000657565b5050565b601f821115620006c85762000692816200053c565b6200069d8462000551565b81016020851015620006ad578190505b620006c5620006bc8562000551565b83018262000656565b50505b505050565b600082821c905092915050565b6000620006ed60001984600802620006cd565b1980831691505092915050565b6000620007088383620006da565b9150826002028217905092915050565b62000723826200049e565b67ffffffffffffffff8111156200073f576200073e620004a9565b5b6200074b825462000507565b620007588282856200067d565b600060209050601f8311600181146200079057600084156200077b578287015190505b620007878582620006fa565b865550620007f7565b601f198416620007a0866200053c565b60005b82811015620007ca57848901518255600182019150602085019450602081019050620007a3565b86831015620007ea5784890151620007e6601f891682620006da565b8355505b6001600288020188555050505b505050505050565b6152b6806200080f6000396000f3fe60806040526004361061027d5760003560e01c806382b12dd71161014f578063b0c2b561116100c1578063d5abeb011161007a578063d5abeb0114610944578063dad7b5c91461096f578063e945971c1461099a578063e985e9c5146109c3578063f2f0e5c914610a00578063f2fde38b14610a1c5761027d565b8063b0c2b56114610834578063b88d4fde1461085d578063b941160114610886578063c7c39ffc146108b1578063c87b56dd146108dc578063d1239730146109195761027d565b806395d89b411161011357806395d89b4114610747578063998cdf8314610772578063a035b1fe1461079b578063a0712d68146107c6578063a0bcfc7f146107e2578063a22cb4651461080b5761027d565b806382b12dd7146106835780638c74bf0e146106ae5780638da5cb5b146106d757806390fd50b3146107025780639495152d1461071e5761027d565b806341f43434116101f35780636352211e116101ac5780636352211e1461057357806370a08231146105b0578063715018a6146105ed5780637437681e146106045780637c3293db1461062f5780637d55094d1461066c5761027d565b806341f434341461046557806342842e0e1461049057806344a0d68a146104b957806344d19d2b146104e25780634f6ccce71461050d5780635a963f1b1461054a5761027d565b80632029ba95116102455780632029ba951461037b57806323b872dd146103a65780632f745c59146103cf578063333e44e61461040c5780633ccfd60b146104375780634005c0161461044e5761027d565b806301ffc9a71461028257806306fdde03146102bf578063081812fc146102ea578063095ea7b31461032757806318160ddd14610350575b600080fd5b34801561028e57600080fd5b506102a960048036038101906102a49190613ae3565b610a45565b6040516102b69190613b2b565b60405180910390f35b3480156102cb57600080fd5b506102d4610b8f565b6040516102e19190613bd6565b60405180910390f35b3480156102f657600080fd5b50610311600480360381019061030c9190613c2e565b610c21565b60405161031e9190613c9c565b60405180910390f35b34801561033357600080fd5b5061034e60048036038101906103499190613ce3565b610c9d565b005b34801561035c57600080fd5b50610365610cb6565b6040516103729190613d32565b60405180910390f35b34801561038757600080fd5b50610390610ccd565b60405161039d9190613b2b565b60405180910390f35b3480156103b257600080fd5b506103cd60048036038101906103c89190613d4d565b610ce0565b005b3480156103db57600080fd5b506103f660048036038101906103f19190613ce3565b610d2f565b6040516104039190613d32565b60405180910390f35b34801561041857600080fd5b50610421610f3a565b60405161042e9190613d32565b60405180910390f35b34801561044357600080fd5b5061044c610f40565b005b34801561045a57600080fd5b5061046361104c565b005b34801561047157600080fd5b5061047a611080565b6040516104879190613dff565b60405180910390f35b34801561049c57600080fd5b506104b760048036038101906104b29190613d4d565b611092565b005b3480156104c557600080fd5b506104e060048036038101906104db9190613c2e565b6110e1565b005b3480156104ee57600080fd5b506104f76110f3565b6040516105049190613d32565b60405180910390f35b34801561051957600080fd5b50610534600480360381019061052f9190613c2e565b6110f9565b6040516105419190613d32565b60405180910390f35b34801561055657600080fd5b50610571600480360381019061056c9190613c2e565b61114c565b005b34801561057f57600080fd5b5061059a60048036038101906105959190613c2e565b61115e565b6040516105a79190613c9c565b60405180910390f35b3480156105bc57600080fd5b506105d760048036038101906105d29190613e1a565b611174565b6040516105e49190613d32565b60405180910390f35b3480156105f957600080fd5b50610602611243565b005b34801561061057600080fd5b50610619611257565b6040516106269190613d32565b60405180910390f35b34801561063b57600080fd5b5061065660048036038101906106519190613e1a565b61125d565b6040516106639190613d32565b60405180910390f35b34801561067857600080fd5b50610681611275565b005b34801561068f57600080fd5b506106986112a9565b6040516106a59190613d32565b60405180910390f35b3480156106ba57600080fd5b506106d560048036038101906106d09190613c2e565b6112af565b005b3480156106e357600080fd5b506106ec611378565b6040516106f99190613c9c565b60405180910390f35b61071c60048036038101906107179190613c2e565b6113a2565b005b34801561072a57600080fd5b5061074560048036038101906107409190613eac565b611469565b005b34801561075357600080fd5b5061075c61151a565b6040516107699190613bd6565b60405180910390f35b34801561077e57600080fd5b5061079960048036038101906107949190613c2e565b6115ac565b005b3480156107a757600080fd5b506107b06115be565b6040516107bd9190613d32565b60405180910390f35b6107e060048036038101906107db9190613c2e565b6115c4565b005b3480156107ee57600080fd5b5061080960048036038101906108049190614029565b611ad1565b005b34801561081757600080fd5b50610832600480360381019061082d919061409e565b611aec565b005b34801561084057600080fd5b5061085b60048036038101906108569190613c2e565b611b05565b005b34801561086957600080fd5b50610884600480360381019061087f919061417f565b611b17565b005b34801561089257600080fd5b5061089b611b68565b6040516108a89190613d32565b60405180910390f35b3480156108bd57600080fd5b506108c6611b72565b6040516108d39190613d32565b60405180910390f35b3480156108e857600080fd5b5061090360048036038101906108fe9190613c2e565b611b78565b6040516109109190613bd6565b60405180910390f35b34801561092557600080fd5b5061092e611c1f565b60405161093b9190613b2b565b60405180910390f35b34801561095057600080fd5b50610959611c32565b6040516109669190613d32565b60405180910390f35b34801561097b57600080fd5b50610984611c38565b6040516109919190613d32565b60405180910390f35b3480156109a657600080fd5b506109c160048036038101906109bc9190613c2e565b611c3e565b005b3480156109cf57600080fd5b506109ea60048036038101906109e59190614202565b611c50565b6040516109f79190613b2b565b60405180910390f35b610a1a6004803603810190610a159190613eac565b611ce4565b005b348015610a2857600080fd5b50610a436004803603810190610a3e9190613e1a565b611e0e565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610b1057507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b7857507f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b885750610b8782611e91565b5b9050919050565b606060028054610b9e90614271565b80601f0160208091040260200160405190810160405280929190818152602001828054610bca90614271565b8015610c175780601f10610bec57610100808354040283529160200191610c17565b820191906000526020600020905b815481529060010190602001808311610bfa57829003601f168201915b5050505050905090565b6000610c2c82611efb565b610c62576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610ca781611f49565b610cb18383612046565b505050565b6000610cc061219d565b6001546000540303905090565b601460009054906101000a900460ff1681565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610d1e57610d1d33611f49565b5b610d298484846121a2565b50505050565b6000610d3a83611174565b8210610d7b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7290614314565b60405180910390fd5b6000610d85610cb6565b905060008060005b83811015610ef8576000600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff1615151515815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614610e9a57806000015192505b8773ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610eea57868403610ee1578195505050505050610f34565b83806001019450505b508080600101915050610d8d565b506040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2b906143a6565b60405180910390fd5b92915050565b60125481565b610f486121f1565b600260095403610f8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8490614412565b60405180910390fd5b600260098190555060003373ffffffffffffffffffffffffffffffffffffffff1647604051610fbb90614463565b60006040518083038185875af1925050503d8060008114610ff8576040519150601f19603f3d011682016040523d82523d6000602084013e610ffd565b606091505b5050905080611041576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611038906144c4565b60405180910390fd5b506001600981905550565b6110546121f1565b601460009054906101000a900460ff1615601460006101000a81548160ff021916908315150217905550565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146110d0576110cf33611f49565b5b6110db84848461226f565b50505050565b6110e96121f1565b80600a8190555050565b600d5481565b6000611103610cb6565b8210611144576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113b90614556565b60405180910390fd5b819050919050565b6111546121f1565b8060128190555050565b6000611169826122ce565b600001519050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036111db576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900467ffffffffffffffff1667ffffffffffffffff169050919050565b61124b6121f1565b611255600061255d565b565b600b5481565b60156020528060005260406000206000915090505481565b61127d6121f1565b600f60009054906101000a900460ff1615600f60006101000a81548160ff021916908315150217905550565b60135481565b6112b76121f1565b6000600d549050600c54826112ca610cb6565b6112d491906145a5565b1115611315576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130c90614625565b60405180910390fd5b81811015611358576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134f90614691565b60405180910390fd5b818161136491906146b1565b600d819055506113743383612623565b5050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b3373ffffffffffffffffffffffffffffffffffffffff166113c28261115e565b73ffffffffffffffffffffffffffffffffffffffff1614611418576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140f90614731565b60405180910390fd5b60135434101561145d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611454906147c3565b60405180910390fd5b61146681612641565b50565b6114716121f1565b60005b82829050811015611515576114a1838383818110611495576114946147e3565b5b90506020020135611efb565b6114e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114d79061485e565b60405180910390fd5b6115028383838181106114f6576114f56147e3565b5b90506020020135612641565b808061150d9061487e565b915050611474565b505050565b60606003805461152990614271565b80601f016020809104026020016040519081016040528092919081815260200182805461155590614271565b80156115a25780601f10611577576101008083540402835291602001916115a2565b820191906000526020600020905b81548152906001019060200180831161158557829003601f168201915b5050505050905090565b6115b46121f1565b8060138190555050565b600a5481565b60006012546011541080156116195750601054601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054105b9050801561198757600f60009054906101000a900460ff16611670576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166790614912565b60405180910390fd5b600c548261167c610cb6565b61168691906145a5565b11156116c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116be9061497e565b60405180910390fd5b600b5482111561170c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611703906149ea565b60405180910390fd5b601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205460105461175991906146b1565b821061187957600a54601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546010546117af91906146b1565b6117b99190614a0a565b600a54836117c79190614a0a565b6117d191906146b1565b341015611813576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180a90614a98565b60405180910390fd5b601054601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506010546011600082825461186d91906145a5565b92505081905550611982565b601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546010546118c691906146b1565b821015611981576000341015611911576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161190890614a98565b60405180910390fd5b81601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461196091906145a5565b92505081905550816011600082825461197991906145a5565b925050819055505b5b611ac3565b600f60009054906101000a900460ff166119d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119cd90614912565b60405180910390fd5b600a54826119e49190614a0a565b341015611a26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a1d90614a98565b60405180910390fd5b600c5482611a32610cb6565b611a3c91906145a5565b1115611a7d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a749061497e565b60405180910390fd5b600b54821115611ac2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ab9906149ea565b60405180910390fd5b5b611acd3383612623565b5050565b611ad96121f1565b80600e9081611ae89190614c5a565b5050565b81611af681611f49565b611b00838361264f565b505050565b611b0d6121f1565b80600b8190555050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611b5557611b5433611f49565b5b611b618585858561280e565b5050505050565b6000600a54905090565b60105481565b6060611b8382611efb565b611bc2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bb990614d9e565b60405180910390fd5b6000611bcc6128c9565b90506000815111611bec5760405180602001604052806000815250611c17565b80611bf68461295b565b604051602001611c07929190614e46565b6040516020818303038152906040525b915050919050565b600f60009054906101000a900460ff1681565b600c5481565b60115481565b611c466121f1565b8060108190555050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60135482829050611cf59190614a0a565b341015611d37576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d2e906147c3565b60405180910390fd5b60005b82829050811015611e09573373ffffffffffffffffffffffffffffffffffffffff16611d7e848484818110611d7257611d716147e3565b5b9050602002013561115e565b73ffffffffffffffffffffffffffffffffffffffff1614611dd4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dcb90614731565b60405180910390fd5b611df6838383818110611dea57611de96147e3565b5b90506020020135612641565b8080611e019061487e565b915050611d3a565b505050565b611e166121f1565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611e85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e7c90614ee7565b60405180910390fd5b611e8e8161255d565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600081611f0661219d565b11158015611f15575060005482105b8015611f42575060046000838152602001908152602001600020600001601c9054906101000a900460ff16155b9050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115612043576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401611fc0929190614f07565b602060405180830381865afa158015611fdd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120019190614f45565b61204257806040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016120399190613c9c565b60405180910390fd5b5b50565b813373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146120845761208333611f49565b5b600061208f8361115e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036120ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120f690614fe4565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661211e612a29565b73ffffffffffffffffffffffffffffffffffffffff16148061214d575061214c81612147612a29565b611c50565b5b61218c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161218390615076565b60405180910390fd5b612197848483612a31565b50505050565b600090565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146121e0576121df33611f49565b5b6121eb848484612ae3565b50505050565b6121f9612a29565b73ffffffffffffffffffffffffffffffffffffffff16612217611378565b73ffffffffffffffffffffffffffffffffffffffff161461226d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612264906150e2565b60405180910390fd5b565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146122ad576122ac33611f49565b5b6122c884848460405180602001604052806000815250611b17565b50505050565b6122d6613a34565b6000829050806122e461219d565b111580156122f3575060005481105b15612526576000600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff1615151515815250509050806040015161252457600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614612408578092505050612558565b5b60011561252357818060019003925050600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff1615151515815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff161461251e578092505050612558565b612409565b5b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61263d828260405180602001604052806000815250612f97565b5050565b61264c816000612fa9565b50565b813373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461268d5761268c33611f49565b5b612695612a29565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612702576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126f99061514e565b60405180910390fd5b816007600061270f612a29565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508273ffffffffffffffffffffffffffffffffffffffff166127bc612a29565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31846040516128019190613b2b565b60405180910390a3505050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461284c5761284b33611f49565b5b612857858585612ae3565b6128768473ffffffffffffffffffffffffffffffffffffffff16613398565b801561288b5750612889858585856133bb565b155b156128c2576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6060600e80546128d890614271565b80601f016020809104026020016040519081016040528092919081815260200182805461290490614271565b80156129515780601f1061292657610100808354040283529160200191612951565b820191906000526020600020905b81548152906001019060200180831161293457829003601f168201915b5050505050905090565b60606000600161296a8461350b565b01905060008167ffffffffffffffff81111561298957612988613efe565b5b6040519080825280601f01601f1916602001820160405280156129bb5781602001600182028036833780820191505090505b509050600082602001820190505b600115612a1e578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581612a1257612a1161516e565b5b049450600085036129c9575b819350505050919050565b600033905090565b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000612aee826122ce565b90508373ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614612b59576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff16612b7a612a29565b73ffffffffffffffffffffffffffffffffffffffff161480612ba95750612ba885612ba3612a29565b611c50565b5b80612bee5750612bb7612a29565b73ffffffffffffffffffffffffffffffffffffffff16612bd684610c21565b73ffffffffffffffffffffffffffffffffffffffff16145b905080612c27576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612c8d576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612c9a858585600161365e565b612ca660008487612a31565b6001600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160392506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506001600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000600460008581526020019081526020016000209050848160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550428160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060006001850190506000600460008381526020019081526020016000209050600073ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603612f25576000548214612f2457878160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084602001518160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b5b505050828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612f908585856001613664565b5050505050565b612fa4838383600161366a565b505050565b6000612fb4836122ce565b905060008160000151905082156130955760008173ffffffffffffffffffffffffffffffffffffffff16612fe6612a29565b73ffffffffffffffffffffffffffffffffffffffff16148061301557506130148261300f612a29565b611c50565b5b8061305a5750613023612a29565b73ffffffffffffffffffffffffffffffffffffffff1661304286610c21565b73ffffffffffffffffffffffffffffffffffffffff16145b905080613093576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b6130a381600086600161365e565b6130af60008583612a31565b6000600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060018160000160008282829054906101000a900467ffffffffffffffff160392506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060018160000160108282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000600460008781526020019081526020016000209050828160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550428160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600181600001601c6101000a81548160ff02191690831515021790555060006001870190506000600460008381526020019081526020016000209050600073ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361331257600054821461331157848160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555085602001518160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b5b5050505083600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4613380816000866001613664565b60016000815480929190600101919050555050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026133e1612a29565b8786866040518563ffffffff1660e01b815260040161340394939291906151f2565b6020604051808303816000875af192505050801561343f57506040513d601f19601f8201168201806040525081019061343c9190615253565b60015b6134b8573d806000811461346f576040519150601f19603f3d011682016040523d82523d6000602084013e613474565b606091505b5060008151036134b0576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613569577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161355f5761355e61516e565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106135a6576d04ee2d6d415b85acef8100000000838161359c5761359b61516e565b5b0492506020810190505b662386f26fc1000083106135d557662386f26fc1000083816135cb576135ca61516e565b5b0492506010810190505b6305f5e10083106135fe576305f5e10083816135f4576135f361516e565b5b0492506008810190505b61271083106136235761271083816136195761361861516e565b5b0492506004810190505b60648310613646576064838161363c5761363b61516e565b5b0492506002810190505b600a8310613655576001810190505b80915050919050565b50505050565b50505050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036136d6576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008403613710576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61371d600086838761365e565b83600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555083600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160088282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550846004600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426004600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000819050600085820190508380156138e757506138e68773ffffffffffffffffffffffffffffffffffffffff16613398565b5b156139ac575b818773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461395c60008884806001019550886133bb565b613992576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8082036138ed5782600054146139a757600080fd5b613a17565b5b818060010192508773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48082036139ad575b816000819055505050613a2d6000868387613664565b5050505050565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff1681526020016000151581525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613ac081613a8b565b8114613acb57600080fd5b50565b600081359050613add81613ab7565b92915050565b600060208284031215613af957613af8613a81565b5b6000613b0784828501613ace565b91505092915050565b60008115159050919050565b613b2581613b10565b82525050565b6000602082019050613b406000830184613b1c565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613b80578082015181840152602081019050613b65565b60008484015250505050565b6000601f19601f8301169050919050565b6000613ba882613b46565b613bb28185613b51565b9350613bc2818560208601613b62565b613bcb81613b8c565b840191505092915050565b60006020820190508181036000830152613bf08184613b9d565b905092915050565b6000819050919050565b613c0b81613bf8565b8114613c1657600080fd5b50565b600081359050613c2881613c02565b92915050565b600060208284031215613c4457613c43613a81565b5b6000613c5284828501613c19565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613c8682613c5b565b9050919050565b613c9681613c7b565b82525050565b6000602082019050613cb16000830184613c8d565b92915050565b613cc081613c7b565b8114613ccb57600080fd5b50565b600081359050613cdd81613cb7565b92915050565b60008060408385031215613cfa57613cf9613a81565b5b6000613d0885828601613cce565b9250506020613d1985828601613c19565b9150509250929050565b613d2c81613bf8565b82525050565b6000602082019050613d476000830184613d23565b92915050565b600080600060608486031215613d6657613d65613a81565b5b6000613d7486828701613cce565b9350506020613d8586828701613cce565b9250506040613d9686828701613c19565b9150509250925092565b6000819050919050565b6000613dc5613dc0613dbb84613c5b565b613da0565b613c5b565b9050919050565b6000613dd782613daa565b9050919050565b6000613de982613dcc565b9050919050565b613df981613dde565b82525050565b6000602082019050613e146000830184613df0565b92915050565b600060208284031215613e3057613e2f613a81565b5b6000613e3e84828501613cce565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f840112613e6c57613e6b613e47565b5b8235905067ffffffffffffffff811115613e8957613e88613e4c565b5b602083019150836020820283011115613ea557613ea4613e51565b5b9250929050565b60008060208385031215613ec357613ec2613a81565b5b600083013567ffffffffffffffff811115613ee157613ee0613a86565b5b613eed85828601613e56565b92509250509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613f3682613b8c565b810181811067ffffffffffffffff82111715613f5557613f54613efe565b5b80604052505050565b6000613f68613a77565b9050613f748282613f2d565b919050565b600067ffffffffffffffff821115613f9457613f93613efe565b5b613f9d82613b8c565b9050602081019050919050565b82818337600083830152505050565b6000613fcc613fc784613f79565b613f5e565b905082815260208101848484011115613fe857613fe7613ef9565b5b613ff3848285613faa565b509392505050565b600082601f8301126140105761400f613e47565b5b8135614020848260208601613fb9565b91505092915050565b60006020828403121561403f5761403e613a81565b5b600082013567ffffffffffffffff81111561405d5761405c613a86565b5b61406984828501613ffb565b91505092915050565b61407b81613b10565b811461408657600080fd5b50565b60008135905061409881614072565b92915050565b600080604083850312156140b5576140b4613a81565b5b60006140c385828601613cce565b92505060206140d485828601614089565b9150509250929050565b600067ffffffffffffffff8211156140f9576140f8613efe565b5b61410282613b8c565b9050602081019050919050565b600061412261411d846140de565b613f5e565b90508281526020810184848401111561413e5761413d613ef9565b5b614149848285613faa565b509392505050565b600082601f83011261416657614165613e47565b5b813561417684826020860161410f565b91505092915050565b6000806000806080858703121561419957614198613a81565b5b60006141a787828801613cce565b94505060206141b887828801613cce565b93505060406141c987828801613c19565b925050606085013567ffffffffffffffff8111156141ea576141e9613a86565b5b6141f687828801614151565b91505092959194509250565b6000806040838503121561421957614218613a81565b5b600061422785828601613cce565b925050602061423885828601613cce565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061428957607f821691505b60208210810361429c5761429b614242565b5b50919050565b7f455243373231413a206f776e657220696e646578206f7574206f6620626f756e60008201527f6473000000000000000000000000000000000000000000000000000000000000602082015250565b60006142fe602283613b51565b9150614309826142a2565b604082019050919050565b6000602082019050818103600083015261432d816142f1565b9050919050565b7f455243373231413a20756e61626c6520746f2067657420746f6b656e206f662060008201527f6f776e657220627920696e646578000000000000000000000000000000000000602082015250565b6000614390602e83613b51565b915061439b82614334565b604082019050919050565b600060208201905081810360008301526143bf81614383565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006143fc601f83613b51565b9150614407826143c6565b602082019050919050565b6000602082019050818103600083015261442b816143ef565b9050919050565b600081905092915050565b50565b600061444d600083614432565b91506144588261443d565b600082019050919050565b600061446e82614440565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b60006144ae601083613b51565b91506144b982614478565b602082019050919050565b600060208201905081810360008301526144dd816144a1565b9050919050565b7f455243373231413a20676c6f62616c20696e646578206f7574206f6620626f7560008201527f6e64730000000000000000000000000000000000000000000000000000000000602082015250565b6000614540602383613b51565b915061454b826144e4565b604082019050919050565b6000602082019050818103600083015261456f81614533565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006145b082613bf8565b91506145bb83613bf8565b92508282019050808211156145d3576145d2614576565b5b92915050565b7f4e6f206d6f726520737570706c7920746f206265206d696e7465640000000000600082015250565b600061460f601b83613b51565b915061461a826145d9565b602082019050919050565b6000602082019050818103600083015261463e81614602565b9050919050565b7f526573657276656420537570706c79204d696e74656400000000000000000000600082015250565b600061467b601683613b51565b915061468682614645565b602082019050919050565b600060208201905081810360008301526146aa8161466e565b9050919050565b60006146bc82613bf8565b91506146c783613bf8565b92508282039050818111156146df576146de614576565b5b92915050565b7f596f7520646f206e6f74206f776e207468697320746f6b656e2e000000000000600082015250565b600061471b601a83613b51565b9150614726826146e5565b602082019050919050565b6000602082019050818103600083015261474a8161470e565b9050919050565b7f496e73756666696369656e742066656520746f20696e7363726962652074686960008201527f7320746f6b656e20746f206f7264696e616c204254432e000000000000000000602082015250565b60006147ad603783613b51565b91506147b882614751565b604082019050919050565b600060208201905081810360008301526147dc816147a0565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f546f6b656e20646f6573206e6f74206578697374000000000000000000000000600082015250565b6000614848601483613b51565b915061485382614812565b602082019050919050565b600060208201905081810360008301526148778161483b565b9050919050565b600061488982613bf8565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036148bb576148ba614576565b5b600182019050919050565b7f4d696e74206973206e6f74206c69766520796574000000000000000000000000600082015250565b60006148fc601483613b51565b9150614907826148c6565b602082019050919050565b6000602082019050818103600083015261492b816148ef565b9050919050565b7f4e6f206d6f726500000000000000000000000000000000000000000000000000600082015250565b6000614968600783613b51565b915061497382614932565b602082019050919050565b600060208201905081810360008301526149978161495b565b9050919050565b7f4d61782070657220545820726561636865642e00000000000000000000000000600082015250565b60006149d4601383613b51565b91506149df8261499e565b602082019050919050565b60006020820190508181036000830152614a03816149c7565b9050919050565b6000614a1582613bf8565b9150614a2083613bf8565b9250828202614a2e81613bf8565b91508282048414831517614a4557614a44614576565b5b5092915050565b7f506c656173652073656e64207468652065786163742045544820616d6f756e74600082015250565b6000614a82602083613b51565b9150614a8d82614a4c565b602082019050919050565b60006020820190508181036000830152614ab181614a75565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302614b1a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614add565b614b248683614add565b95508019841693508086168417925050509392505050565b6000614b57614b52614b4d84613bf8565b613da0565b613bf8565b9050919050565b6000819050919050565b614b7183614b3c565b614b85614b7d82614b5e565b848454614aea565b825550505050565b600090565b614b9a614b8d565b614ba5818484614b68565b505050565b5b81811015614bc957614bbe600082614b92565b600181019050614bab565b5050565b601f821115614c0e57614bdf81614ab8565b614be884614acd565b81016020851015614bf7578190505b614c0b614c0385614acd565b830182614baa565b50505b505050565b600082821c905092915050565b6000614c3160001984600802614c13565b1980831691505092915050565b6000614c4a8383614c20565b9150826002028217905092915050565b614c6382613b46565b67ffffffffffffffff811115614c7c57614c7b613efe565b5b614c868254614271565b614c91828285614bcd565b600060209050601f831160018114614cc45760008415614cb2578287015190505b614cbc8582614c3e565b865550614d24565b601f198416614cd286614ab8565b60005b82811015614cfa57848901518255600182019150602085019450602081019050614cd5565b86831015614d175784890151614d13601f891682614c20565b8355505b6001600288020188555050505b505050505050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000614d88602f83613b51565b9150614d9382614d2c565b604082019050919050565b60006020820190508181036000830152614db781614d7b565b9050919050565b600081905092915050565b6000614dd482613b46565b614dde8185614dbe565b9350614dee818560208601613b62565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b6000614e30600583614dbe565b9150614e3b82614dfa565b600582019050919050565b6000614e528285614dc9565b9150614e5e8284614dc9565b9150614e6982614e23565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614ed1602683613b51565b9150614edc82614e75565b604082019050919050565b60006020820190508181036000830152614f0081614ec4565b9050919050565b6000604082019050614f1c6000830185613c8d565b614f296020830184613c8d565b9392505050565b600081519050614f3f81614072565b92915050565b600060208284031215614f5b57614f5a613a81565b5b6000614f6984828501614f30565b91505092915050565b7f455243373231413a20617070726f76616c20746f2063757272656e74206f776e60008201527f6572000000000000000000000000000000000000000000000000000000000000602082015250565b6000614fce602283613b51565b9150614fd982614f72565b604082019050919050565b60006020820190508181036000830152614ffd81614fc1565b9050919050565b7f455243373231413a20617070726f76652063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f76656420666f7220616c6c00000000000000602082015250565b6000615060603983613b51565b915061506b82615004565b604082019050919050565b6000602082019050818103600083015261508f81615053565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006150cc602083613b51565b91506150d782615096565b602082019050919050565b600060208201905081810360008301526150fb816150bf565b9050919050565b7f455243373231413a20617070726f766520746f2063616c6c6572000000000000600082015250565b6000615138601a83613b51565b915061514382615102565b602082019050919050565b600060208201905081810360008301526151678161512b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600081519050919050565b600082825260208201905092915050565b60006151c48261519d565b6151ce81856151a8565b93506151de818560208601613b62565b6151e781613b8c565b840191505092915050565b60006080820190506152076000830187613c8d565b6152146020830186613c8d565b6152216040830185613d23565b818103606083015261523381846151b9565b905095945050505050565b60008151905061524d81613ab7565b92915050565b60006020828403121561526957615268613a81565b5b60006152778482850161523e565b9150509291505056fea264697066735822122088a2040ffbac4cbf7c04cb5e67b8f5bed4d7e46ac6874c233249ab047377890664736f6c63430008130033
Deployed Bytecode
0x60806040526004361061027d5760003560e01c806382b12dd71161014f578063b0c2b561116100c1578063d5abeb011161007a578063d5abeb0114610944578063dad7b5c91461096f578063e945971c1461099a578063e985e9c5146109c3578063f2f0e5c914610a00578063f2fde38b14610a1c5761027d565b8063b0c2b56114610834578063b88d4fde1461085d578063b941160114610886578063c7c39ffc146108b1578063c87b56dd146108dc578063d1239730146109195761027d565b806395d89b411161011357806395d89b4114610747578063998cdf8314610772578063a035b1fe1461079b578063a0712d68146107c6578063a0bcfc7f146107e2578063a22cb4651461080b5761027d565b806382b12dd7146106835780638c74bf0e146106ae5780638da5cb5b146106d757806390fd50b3146107025780639495152d1461071e5761027d565b806341f43434116101f35780636352211e116101ac5780636352211e1461057357806370a08231146105b0578063715018a6146105ed5780637437681e146106045780637c3293db1461062f5780637d55094d1461066c5761027d565b806341f434341461046557806342842e0e1461049057806344a0d68a146104b957806344d19d2b146104e25780634f6ccce71461050d5780635a963f1b1461054a5761027d565b80632029ba95116102455780632029ba951461037b57806323b872dd146103a65780632f745c59146103cf578063333e44e61461040c5780633ccfd60b146104375780634005c0161461044e5761027d565b806301ffc9a71461028257806306fdde03146102bf578063081812fc146102ea578063095ea7b31461032757806318160ddd14610350575b600080fd5b34801561028e57600080fd5b506102a960048036038101906102a49190613ae3565b610a45565b6040516102b69190613b2b565b60405180910390f35b3480156102cb57600080fd5b506102d4610b8f565b6040516102e19190613bd6565b60405180910390f35b3480156102f657600080fd5b50610311600480360381019061030c9190613c2e565b610c21565b60405161031e9190613c9c565b60405180910390f35b34801561033357600080fd5b5061034e60048036038101906103499190613ce3565b610c9d565b005b34801561035c57600080fd5b50610365610cb6565b6040516103729190613d32565b60405180910390f35b34801561038757600080fd5b50610390610ccd565b60405161039d9190613b2b565b60405180910390f35b3480156103b257600080fd5b506103cd60048036038101906103c89190613d4d565b610ce0565b005b3480156103db57600080fd5b506103f660048036038101906103f19190613ce3565b610d2f565b6040516104039190613d32565b60405180910390f35b34801561041857600080fd5b50610421610f3a565b60405161042e9190613d32565b60405180910390f35b34801561044357600080fd5b5061044c610f40565b005b34801561045a57600080fd5b5061046361104c565b005b34801561047157600080fd5b5061047a611080565b6040516104879190613dff565b60405180910390f35b34801561049c57600080fd5b506104b760048036038101906104b29190613d4d565b611092565b005b3480156104c557600080fd5b506104e060048036038101906104db9190613c2e565b6110e1565b005b3480156104ee57600080fd5b506104f76110f3565b6040516105049190613d32565b60405180910390f35b34801561051957600080fd5b50610534600480360381019061052f9190613c2e565b6110f9565b6040516105419190613d32565b60405180910390f35b34801561055657600080fd5b50610571600480360381019061056c9190613c2e565b61114c565b005b34801561057f57600080fd5b5061059a60048036038101906105959190613c2e565b61115e565b6040516105a79190613c9c565b60405180910390f35b3480156105bc57600080fd5b506105d760048036038101906105d29190613e1a565b611174565b6040516105e49190613d32565b60405180910390f35b3480156105f957600080fd5b50610602611243565b005b34801561061057600080fd5b50610619611257565b6040516106269190613d32565b60405180910390f35b34801561063b57600080fd5b5061065660048036038101906106519190613e1a565b61125d565b6040516106639190613d32565b60405180910390f35b34801561067857600080fd5b50610681611275565b005b34801561068f57600080fd5b506106986112a9565b6040516106a59190613d32565b60405180910390f35b3480156106ba57600080fd5b506106d560048036038101906106d09190613c2e565b6112af565b005b3480156106e357600080fd5b506106ec611378565b6040516106f99190613c9c565b60405180910390f35b61071c60048036038101906107179190613c2e565b6113a2565b005b34801561072a57600080fd5b5061074560048036038101906107409190613eac565b611469565b005b34801561075357600080fd5b5061075c61151a565b6040516107699190613bd6565b60405180910390f35b34801561077e57600080fd5b5061079960048036038101906107949190613c2e565b6115ac565b005b3480156107a757600080fd5b506107b06115be565b6040516107bd9190613d32565b60405180910390f35b6107e060048036038101906107db9190613c2e565b6115c4565b005b3480156107ee57600080fd5b5061080960048036038101906108049190614029565b611ad1565b005b34801561081757600080fd5b50610832600480360381019061082d919061409e565b611aec565b005b34801561084057600080fd5b5061085b60048036038101906108569190613c2e565b611b05565b005b34801561086957600080fd5b50610884600480360381019061087f919061417f565b611b17565b005b34801561089257600080fd5b5061089b611b68565b6040516108a89190613d32565b60405180910390f35b3480156108bd57600080fd5b506108c6611b72565b6040516108d39190613d32565b60405180910390f35b3480156108e857600080fd5b5061090360048036038101906108fe9190613c2e565b611b78565b6040516109109190613bd6565b60405180910390f35b34801561092557600080fd5b5061092e611c1f565b60405161093b9190613b2b565b60405180910390f35b34801561095057600080fd5b50610959611c32565b6040516109669190613d32565b60405180910390f35b34801561097b57600080fd5b50610984611c38565b6040516109919190613d32565b60405180910390f35b3480156109a657600080fd5b506109c160048036038101906109bc9190613c2e565b611c3e565b005b3480156109cf57600080fd5b506109ea60048036038101906109e59190614202565b611c50565b6040516109f79190613b2b565b60405180910390f35b610a1a6004803603810190610a159190613eac565b611ce4565b005b348015610a2857600080fd5b50610a436004803603810190610a3e9190613e1a565b611e0e565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610b1057507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b7857507f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610b885750610b8782611e91565b5b9050919050565b606060028054610b9e90614271565b80601f0160208091040260200160405190810160405280929190818152602001828054610bca90614271565b8015610c175780601f10610bec57610100808354040283529160200191610c17565b820191906000526020600020905b815481529060010190602001808311610bfa57829003601f168201915b5050505050905090565b6000610c2c82611efb565b610c62576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610ca781611f49565b610cb18383612046565b505050565b6000610cc061219d565b6001546000540303905090565b601460009054906101000a900460ff1681565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610d1e57610d1d33611f49565b5b610d298484846121a2565b50505050565b6000610d3a83611174565b8210610d7b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7290614314565b60405180910390fd5b6000610d85610cb6565b905060008060005b83811015610ef8576000600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff1615151515815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614610e9a57806000015192505b8773ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610eea57868403610ee1578195505050505050610f34565b83806001019450505b508080600101915050610d8d565b506040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2b906143a6565b60405180910390fd5b92915050565b60125481565b610f486121f1565b600260095403610f8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8490614412565b60405180910390fd5b600260098190555060003373ffffffffffffffffffffffffffffffffffffffff1647604051610fbb90614463565b60006040518083038185875af1925050503d8060008114610ff8576040519150601f19603f3d011682016040523d82523d6000602084013e610ffd565b606091505b5050905080611041576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611038906144c4565b60405180910390fd5b506001600981905550565b6110546121f1565b601460009054906101000a900460ff1615601460006101000a81548160ff021916908315150217905550565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146110d0576110cf33611f49565b5b6110db84848461226f565b50505050565b6110e96121f1565b80600a8190555050565b600d5481565b6000611103610cb6565b8210611144576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113b90614556565b60405180910390fd5b819050919050565b6111546121f1565b8060128190555050565b6000611169826122ce565b600001519050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036111db576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900467ffffffffffffffff1667ffffffffffffffff169050919050565b61124b6121f1565b611255600061255d565b565b600b5481565b60156020528060005260406000206000915090505481565b61127d6121f1565b600f60009054906101000a900460ff1615600f60006101000a81548160ff021916908315150217905550565b60135481565b6112b76121f1565b6000600d549050600c54826112ca610cb6565b6112d491906145a5565b1115611315576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130c90614625565b60405180910390fd5b81811015611358576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134f90614691565b60405180910390fd5b818161136491906146b1565b600d819055506113743383612623565b5050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b3373ffffffffffffffffffffffffffffffffffffffff166113c28261115e565b73ffffffffffffffffffffffffffffffffffffffff1614611418576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140f90614731565b60405180910390fd5b60135434101561145d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611454906147c3565b60405180910390fd5b61146681612641565b50565b6114716121f1565b60005b82829050811015611515576114a1838383818110611495576114946147e3565b5b90506020020135611efb565b6114e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114d79061485e565b60405180910390fd5b6115028383838181106114f6576114f56147e3565b5b90506020020135612641565b808061150d9061487e565b915050611474565b505050565b60606003805461152990614271565b80601f016020809104026020016040519081016040528092919081815260200182805461155590614271565b80156115a25780601f10611577576101008083540402835291602001916115a2565b820191906000526020600020905b81548152906001019060200180831161158557829003601f168201915b5050505050905090565b6115b46121f1565b8060138190555050565b600a5481565b60006012546011541080156116195750601054601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054105b9050801561198757600f60009054906101000a900460ff16611670576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166790614912565b60405180910390fd5b600c548261167c610cb6565b61168691906145a5565b11156116c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116be9061497e565b60405180910390fd5b600b5482111561170c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611703906149ea565b60405180910390fd5b601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205460105461175991906146b1565b821061187957600a54601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546010546117af91906146b1565b6117b99190614a0a565b600a54836117c79190614a0a565b6117d191906146b1565b341015611813576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180a90614a98565b60405180910390fd5b601054601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506010546011600082825461186d91906145a5565b92505081905550611982565b601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546010546118c691906146b1565b821015611981576000341015611911576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161190890614a98565b60405180910390fd5b81601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461196091906145a5565b92505081905550816011600082825461197991906145a5565b925050819055505b5b611ac3565b600f60009054906101000a900460ff166119d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119cd90614912565b60405180910390fd5b600a54826119e49190614a0a565b341015611a26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a1d90614a98565b60405180910390fd5b600c5482611a32610cb6565b611a3c91906145a5565b1115611a7d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a749061497e565b60405180910390fd5b600b54821115611ac2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ab9906149ea565b60405180910390fd5b5b611acd3383612623565b5050565b611ad96121f1565b80600e9081611ae89190614c5a565b5050565b81611af681611f49565b611b00838361264f565b505050565b611b0d6121f1565b80600b8190555050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611b5557611b5433611f49565b5b611b618585858561280e565b5050505050565b6000600a54905090565b60105481565b6060611b8382611efb565b611bc2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bb990614d9e565b60405180910390fd5b6000611bcc6128c9565b90506000815111611bec5760405180602001604052806000815250611c17565b80611bf68461295b565b604051602001611c07929190614e46565b6040516020818303038152906040525b915050919050565b600f60009054906101000a900460ff1681565b600c5481565b60115481565b611c466121f1565b8060108190555050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60135482829050611cf59190614a0a565b341015611d37576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d2e906147c3565b60405180910390fd5b60005b82829050811015611e09573373ffffffffffffffffffffffffffffffffffffffff16611d7e848484818110611d7257611d716147e3565b5b9050602002013561115e565b73ffffffffffffffffffffffffffffffffffffffff1614611dd4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dcb90614731565b60405180910390fd5b611df6838383818110611dea57611de96147e3565b5b90506020020135612641565b8080611e019061487e565b915050611d3a565b505050565b611e166121f1565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611e85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e7c90614ee7565b60405180910390fd5b611e8e8161255d565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600081611f0661219d565b11158015611f15575060005482105b8015611f42575060046000838152602001908152602001600020600001601c9054906101000a900460ff16155b9050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115612043576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401611fc0929190614f07565b602060405180830381865afa158015611fdd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120019190614f45565b61204257806040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016120399190613c9c565b60405180910390fd5b5b50565b813373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146120845761208333611f49565b5b600061208f8361115e565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036120ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120f690614fe4565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661211e612a29565b73ffffffffffffffffffffffffffffffffffffffff16148061214d575061214c81612147612a29565b611c50565b5b61218c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161218390615076565b60405180910390fd5b612197848483612a31565b50505050565b600090565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146121e0576121df33611f49565b5b6121eb848484612ae3565b50505050565b6121f9612a29565b73ffffffffffffffffffffffffffffffffffffffff16612217611378565b73ffffffffffffffffffffffffffffffffffffffff161461226d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612264906150e2565b60405180910390fd5b565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146122ad576122ac33611f49565b5b6122c884848460405180602001604052806000815250611b17565b50505050565b6122d6613a34565b6000829050806122e461219d565b111580156122f3575060005481105b15612526576000600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff1615151515815250509050806040015161252457600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614612408578092505050612558565b5b60011561252357818060019003925050600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff1615151515815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff161461251e578092505050612558565b612409565b5b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61263d828260405180602001604052806000815250612f97565b5050565b61264c816000612fa9565b50565b813373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461268d5761268c33611f49565b5b612695612a29565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612702576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126f99061514e565b60405180910390fd5b816007600061270f612a29565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508273ffffffffffffffffffffffffffffffffffffffff166127bc612a29565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31846040516128019190613b2b565b60405180910390a3505050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461284c5761284b33611f49565b5b612857858585612ae3565b6128768473ffffffffffffffffffffffffffffffffffffffff16613398565b801561288b5750612889858585856133bb565b155b156128c2576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b6060600e80546128d890614271565b80601f016020809104026020016040519081016040528092919081815260200182805461290490614271565b80156129515780601f1061292657610100808354040283529160200191612951565b820191906000526020600020905b81548152906001019060200180831161293457829003601f168201915b5050505050905090565b60606000600161296a8461350b565b01905060008167ffffffffffffffff81111561298957612988613efe565b5b6040519080825280601f01601f1916602001820160405280156129bb5781602001600182028036833780820191505090505b509050600082602001820190505b600115612a1e578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581612a1257612a1161516e565b5b049450600085036129c9575b819350505050919050565b600033905090565b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000612aee826122ce565b90508373ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614612b59576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff16612b7a612a29565b73ffffffffffffffffffffffffffffffffffffffff161480612ba95750612ba885612ba3612a29565b611c50565b5b80612bee5750612bb7612a29565b73ffffffffffffffffffffffffffffffffffffffff16612bd684610c21565b73ffffffffffffffffffffffffffffffffffffffff16145b905080612c27576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612c8d576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612c9a858585600161365e565b612ca660008487612a31565b6001600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160392506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506001600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000600460008581526020019081526020016000209050848160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550428160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060006001850190506000600460008381526020019081526020016000209050600073ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603612f25576000548214612f2457878160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084602001518160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b5b505050828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612f908585856001613664565b5050505050565b612fa4838383600161366a565b505050565b6000612fb4836122ce565b905060008160000151905082156130955760008173ffffffffffffffffffffffffffffffffffffffff16612fe6612a29565b73ffffffffffffffffffffffffffffffffffffffff16148061301557506130148261300f612a29565b611c50565b5b8061305a5750613023612a29565b73ffffffffffffffffffffffffffffffffffffffff1661304286610c21565b73ffffffffffffffffffffffffffffffffffffffff16145b905080613093576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b6130a381600086600161365e565b6130af60008583612a31565b6000600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060018160000160008282829054906101000a900467ffffffffffffffff160392506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060018160000160108282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000600460008781526020019081526020016000209050828160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550428160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600181600001601c6101000a81548160ff02191690831515021790555060006001870190506000600460008381526020019081526020016000209050600073ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361331257600054821461331157848160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555085602001518160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b5b5050505083600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4613380816000866001613664565b60016000815480929190600101919050555050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026133e1612a29565b8786866040518563ffffffff1660e01b815260040161340394939291906151f2565b6020604051808303816000875af192505050801561343f57506040513d601f19601f8201168201806040525081019061343c9190615253565b60015b6134b8573d806000811461346f576040519150601f19603f3d011682016040523d82523d6000602084013e613474565b606091505b5060008151036134b0576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613569577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161355f5761355e61516e565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106135a6576d04ee2d6d415b85acef8100000000838161359c5761359b61516e565b5b0492506020810190505b662386f26fc1000083106135d557662386f26fc1000083816135cb576135ca61516e565b5b0492506010810190505b6305f5e10083106135fe576305f5e10083816135f4576135f361516e565b5b0492506008810190505b61271083106136235761271083816136195761361861516e565b5b0492506004810190505b60648310613646576064838161363c5761363b61516e565b5b0492506002810190505b600a8310613655576001810190505b80915050919050565b50505050565b50505050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036136d6576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008403613710576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61371d600086838761365e565b83600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555083600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160088282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550846004600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426004600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000819050600085820190508380156138e757506138e68773ffffffffffffffffffffffffffffffffffffffff16613398565b5b156139ac575b818773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461395c60008884806001019550886133bb565b613992576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8082036138ed5782600054146139a757600080fd5b613a17565b5b818060010192508773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48082036139ad575b816000819055505050613a2d6000868387613664565b5050505050565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff1681526020016000151581525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613ac081613a8b565b8114613acb57600080fd5b50565b600081359050613add81613ab7565b92915050565b600060208284031215613af957613af8613a81565b5b6000613b0784828501613ace565b91505092915050565b60008115159050919050565b613b2581613b10565b82525050565b6000602082019050613b406000830184613b1c565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613b80578082015181840152602081019050613b65565b60008484015250505050565b6000601f19601f8301169050919050565b6000613ba882613b46565b613bb28185613b51565b9350613bc2818560208601613b62565b613bcb81613b8c565b840191505092915050565b60006020820190508181036000830152613bf08184613b9d565b905092915050565b6000819050919050565b613c0b81613bf8565b8114613c1657600080fd5b50565b600081359050613c2881613c02565b92915050565b600060208284031215613c4457613c43613a81565b5b6000613c5284828501613c19565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613c8682613c5b565b9050919050565b613c9681613c7b565b82525050565b6000602082019050613cb16000830184613c8d565b92915050565b613cc081613c7b565b8114613ccb57600080fd5b50565b600081359050613cdd81613cb7565b92915050565b60008060408385031215613cfa57613cf9613a81565b5b6000613d0885828601613cce565b9250506020613d1985828601613c19565b9150509250929050565b613d2c81613bf8565b82525050565b6000602082019050613d476000830184613d23565b92915050565b600080600060608486031215613d6657613d65613a81565b5b6000613d7486828701613cce565b9350506020613d8586828701613cce565b9250506040613d9686828701613c19565b9150509250925092565b6000819050919050565b6000613dc5613dc0613dbb84613c5b565b613da0565b613c5b565b9050919050565b6000613dd782613daa565b9050919050565b6000613de982613dcc565b9050919050565b613df981613dde565b82525050565b6000602082019050613e146000830184613df0565b92915050565b600060208284031215613e3057613e2f613a81565b5b6000613e3e84828501613cce565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f840112613e6c57613e6b613e47565b5b8235905067ffffffffffffffff811115613e8957613e88613e4c565b5b602083019150836020820283011115613ea557613ea4613e51565b5b9250929050565b60008060208385031215613ec357613ec2613a81565b5b600083013567ffffffffffffffff811115613ee157613ee0613a86565b5b613eed85828601613e56565b92509250509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613f3682613b8c565b810181811067ffffffffffffffff82111715613f5557613f54613efe565b5b80604052505050565b6000613f68613a77565b9050613f748282613f2d565b919050565b600067ffffffffffffffff821115613f9457613f93613efe565b5b613f9d82613b8c565b9050602081019050919050565b82818337600083830152505050565b6000613fcc613fc784613f79565b613f5e565b905082815260208101848484011115613fe857613fe7613ef9565b5b613ff3848285613faa565b509392505050565b600082601f8301126140105761400f613e47565b5b8135614020848260208601613fb9565b91505092915050565b60006020828403121561403f5761403e613a81565b5b600082013567ffffffffffffffff81111561405d5761405c613a86565b5b61406984828501613ffb565b91505092915050565b61407b81613b10565b811461408657600080fd5b50565b60008135905061409881614072565b92915050565b600080604083850312156140b5576140b4613a81565b5b60006140c385828601613cce565b92505060206140d485828601614089565b9150509250929050565b600067ffffffffffffffff8211156140f9576140f8613efe565b5b61410282613b8c565b9050602081019050919050565b600061412261411d846140de565b613f5e565b90508281526020810184848401111561413e5761413d613ef9565b5b614149848285613faa565b509392505050565b600082601f83011261416657614165613e47565b5b813561417684826020860161410f565b91505092915050565b6000806000806080858703121561419957614198613a81565b5b60006141a787828801613cce565b94505060206141b887828801613cce565b93505060406141c987828801613c19565b925050606085013567ffffffffffffffff8111156141ea576141e9613a86565b5b6141f687828801614151565b91505092959194509250565b6000806040838503121561421957614218613a81565b5b600061422785828601613cce565b925050602061423885828601613cce565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061428957607f821691505b60208210810361429c5761429b614242565b5b50919050565b7f455243373231413a206f776e657220696e646578206f7574206f6620626f756e60008201527f6473000000000000000000000000000000000000000000000000000000000000602082015250565b60006142fe602283613b51565b9150614309826142a2565b604082019050919050565b6000602082019050818103600083015261432d816142f1565b9050919050565b7f455243373231413a20756e61626c6520746f2067657420746f6b656e206f662060008201527f6f776e657220627920696e646578000000000000000000000000000000000000602082015250565b6000614390602e83613b51565b915061439b82614334565b604082019050919050565b600060208201905081810360008301526143bf81614383565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006143fc601f83613b51565b9150614407826143c6565b602082019050919050565b6000602082019050818103600083015261442b816143ef565b9050919050565b600081905092915050565b50565b600061444d600083614432565b91506144588261443d565b600082019050919050565b600061446e82614440565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b60006144ae601083613b51565b91506144b982614478565b602082019050919050565b600060208201905081810360008301526144dd816144a1565b9050919050565b7f455243373231413a20676c6f62616c20696e646578206f7574206f6620626f7560008201527f6e64730000000000000000000000000000000000000000000000000000000000602082015250565b6000614540602383613b51565b915061454b826144e4565b604082019050919050565b6000602082019050818103600083015261456f81614533565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006145b082613bf8565b91506145bb83613bf8565b92508282019050808211156145d3576145d2614576565b5b92915050565b7f4e6f206d6f726520737570706c7920746f206265206d696e7465640000000000600082015250565b600061460f601b83613b51565b915061461a826145d9565b602082019050919050565b6000602082019050818103600083015261463e81614602565b9050919050565b7f526573657276656420537570706c79204d696e74656400000000000000000000600082015250565b600061467b601683613b51565b915061468682614645565b602082019050919050565b600060208201905081810360008301526146aa8161466e565b9050919050565b60006146bc82613bf8565b91506146c783613bf8565b92508282039050818111156146df576146de614576565b5b92915050565b7f596f7520646f206e6f74206f776e207468697320746f6b656e2e000000000000600082015250565b600061471b601a83613b51565b9150614726826146e5565b602082019050919050565b6000602082019050818103600083015261474a8161470e565b9050919050565b7f496e73756666696369656e742066656520746f20696e7363726962652074686960008201527f7320746f6b656e20746f206f7264696e616c204254432e000000000000000000602082015250565b60006147ad603783613b51565b91506147b882614751565b604082019050919050565b600060208201905081810360008301526147dc816147a0565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f546f6b656e20646f6573206e6f74206578697374000000000000000000000000600082015250565b6000614848601483613b51565b915061485382614812565b602082019050919050565b600060208201905081810360008301526148778161483b565b9050919050565b600061488982613bf8565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036148bb576148ba614576565b5b600182019050919050565b7f4d696e74206973206e6f74206c69766520796574000000000000000000000000600082015250565b60006148fc601483613b51565b9150614907826148c6565b602082019050919050565b6000602082019050818103600083015261492b816148ef565b9050919050565b7f4e6f206d6f726500000000000000000000000000000000000000000000000000600082015250565b6000614968600783613b51565b915061497382614932565b602082019050919050565b600060208201905081810360008301526149978161495b565b9050919050565b7f4d61782070657220545820726561636865642e00000000000000000000000000600082015250565b60006149d4601383613b51565b91506149df8261499e565b602082019050919050565b60006020820190508181036000830152614a03816149c7565b9050919050565b6000614a1582613bf8565b9150614a2083613bf8565b9250828202614a2e81613bf8565b91508282048414831517614a4557614a44614576565b5b5092915050565b7f506c656173652073656e64207468652065786163742045544820616d6f756e74600082015250565b6000614a82602083613b51565b9150614a8d82614a4c565b602082019050919050565b60006020820190508181036000830152614ab181614a75565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302614b1a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614add565b614b248683614add565b95508019841693508086168417925050509392505050565b6000614b57614b52614b4d84613bf8565b613da0565b613bf8565b9050919050565b6000819050919050565b614b7183614b3c565b614b85614b7d82614b5e565b848454614aea565b825550505050565b600090565b614b9a614b8d565b614ba5818484614b68565b505050565b5b81811015614bc957614bbe600082614b92565b600181019050614bab565b5050565b601f821115614c0e57614bdf81614ab8565b614be884614acd565b81016020851015614bf7578190505b614c0b614c0385614acd565b830182614baa565b50505b505050565b600082821c905092915050565b6000614c3160001984600802614c13565b1980831691505092915050565b6000614c4a8383614c20565b9150826002028217905092915050565b614c6382613b46565b67ffffffffffffffff811115614c7c57614c7b613efe565b5b614c868254614271565b614c91828285614bcd565b600060209050601f831160018114614cc45760008415614cb2578287015190505b614cbc8582614c3e565b865550614d24565b601f198416614cd286614ab8565b60005b82811015614cfa57848901518255600182019150602085019450602081019050614cd5565b86831015614d175784890151614d13601f891682614c20565b8355505b6001600288020188555050505b505050505050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000614d88602f83613b51565b9150614d9382614d2c565b604082019050919050565b60006020820190508181036000830152614db781614d7b565b9050919050565b600081905092915050565b6000614dd482613b46565b614dde8185614dbe565b9350614dee818560208601613b62565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b6000614e30600583614dbe565b9150614e3b82614dfa565b600582019050919050565b6000614e528285614dc9565b9150614e5e8284614dc9565b9150614e6982614e23565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614ed1602683613b51565b9150614edc82614e75565b604082019050919050565b60006020820190508181036000830152614f0081614ec4565b9050919050565b6000604082019050614f1c6000830185613c8d565b614f296020830184613c8d565b9392505050565b600081519050614f3f81614072565b92915050565b600060208284031215614f5b57614f5a613a81565b5b6000614f6984828501614f30565b91505092915050565b7f455243373231413a20617070726f76616c20746f2063757272656e74206f776e60008201527f6572000000000000000000000000000000000000000000000000000000000000602082015250565b6000614fce602283613b51565b9150614fd982614f72565b604082019050919050565b60006020820190508181036000830152614ffd81614fc1565b9050919050565b7f455243373231413a20617070726f76652063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f76656420666f7220616c6c00000000000000602082015250565b6000615060603983613b51565b915061506b82615004565b604082019050919050565b6000602082019050818103600083015261508f81615053565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006150cc602083613b51565b91506150d782615096565b602082019050919050565b600060208201905081810360008301526150fb816150bf565b9050919050565b7f455243373231413a20617070726f766520746f2063616c6c6572000000000000600082015250565b6000615138601a83613b51565b915061514382615102565b602082019050919050565b600060208201905081810360008301526151678161512b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600081519050919050565b600082825260208201905092915050565b60006151c48261519d565b6151ce81856151a8565b93506151de818560208601613b62565b6151e781613b8c565b840191505092915050565b60006080820190506152076000830187613c8d565b6152146020830186613c8d565b6152216040830185613d23565b818103606083015261523381846151b9565b905095945050505050565b60008151905061524d81613ab7565b92915050565b60006020828403121561526957615268613a81565b5b60006152778482850161523e565b9150509291505056fea264697066735822122088a2040ffbac4cbf7c04cb5e67b8f5bed4d7e46ac6874c233249ab047377890664736f6c63430008130033
Deployed Bytecode Sourcemap
113347:5942:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83744:372;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86926:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88503:204;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;118349:157;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81904:303;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;113858:42;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;118514:163;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;82215:886;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;113781:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119100:186;;;;;;;;;;;;;:::i;:::-;;116501:120;;;;;;;;;;;;;:::i;:::-;;40348:143;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;118685:171;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;117652:85;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;113594:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83109:187;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;117932:111;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;86734:125;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;84182:206;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103473:103;;;;;;;;;;;;;:::i;:::-;;113507:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;113913:46;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;116306:87;;;;;;;;;;;;;:::i;:::-;;113827:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;115902:396;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;102825:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;116633:282;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;117305:231;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;87095:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;116401:88;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;113454:46;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;114547:1347;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;117546:98;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;118165:176;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;117838:86;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;118864:228;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;117745:84;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;113699:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;114028:395;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;113665:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;113547:40;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;113741:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;118051:106;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;89176:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;116923:374;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103731:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83744:372;83846:4;83898:25;83883:40;;;:11;:40;;;;:105;;;;83955:33;83940:48;;;:11;:48;;;;83883:105;:172;;;;84020:35;84005:50;;;:11;:50;;;;83883:172;:225;;;;84072:36;84096:11;84072:23;:36::i;:::-;83883:225;83863:245;;83744:372;;;:::o;86926:100::-;86980:13;87013:5;87006:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86926:100;:::o;88503:204::-;88571:7;88596:16;88604:7;88596;:16::i;:::-;88591:64;;88621:34;;;;;;;;;;;;;;88591:64;88675:15;:24;88691:7;88675:24;;;;;;;;;;;;;;;;;;;;;88668:31;;88503:204;;;:::o;118349:157::-;118445:8;41869:30;41890:8;41869:20;:30::i;:::-;118466:32:::1;118480:8;118490:7;118466:13;:32::i;:::-;118349:157:::0;;;:::o;81904:303::-;81948:7;82173:15;:13;:15::i;:::-;82158:12;;82142:13;;:28;:46;82135:53;;81904:303;:::o;113858:42::-;;;;;;;;;;;;;:::o;118514:163::-;118615:4;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;118632:37:::1;118651:4;118657:2;118661:7;118632:18;:37::i;:::-;118514:163:::0;;;;:::o;82215:886::-;82304:7;82340:16;82350:5;82340:9;:16::i;:::-;82332:5;:24;82324:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;82406:22;82431:13;:11;:13::i;:::-;82406:38;;82455:19;82485:25;82553:9;82548:466;82568:14;82564:1;:18;82548:466;;;82608:31;82642:11;:14;82654:1;82642:14;;;;;;;;;;;82608:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82705:1;82679:28;;:9;:14;;;:28;;;82675:111;;82752:9;:14;;;82732:34;;82675:111;82829:5;82808:26;;:17;:26;;;82804:195;;82878:5;82863:11;:20;82859:85;;82919:1;82912:8;;;;;;;;;82859:85;82966:13;;;;;;;82804:195;82589:425;82584:3;;;;;;;82548:466;;;;83037:56;;;;;;;;;;:::i;:::-;;;;;;;;82215:886;;;;;:::o;113781:39::-;;;;:::o;119100:186::-;102711:13;:11;:13::i;:::-;76983:1:::1;77133:7;;:19:::0;77125:63:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;76983:1;77201:7;:18;;;;119164:12:::2;119182:10;:15;;119205:21;119182:49;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;119163:68;;;119250:7;119242:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;119152:134;76939:1:::1;77246:7;:22;;;;119100:186::o:0;116501:120::-;102711:13;:11;:13::i;:::-;116591:22:::1;;;;;;;;;;;116590:23;116565:22;;:48;;;;;;;;;;;;;;;;;;116501:120::o:0;40348:143::-;40448:42;40348:143;:::o;118685:171::-;118790:4;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;118807:41:::1;118830:4;118836:2;118840:7;118807:22;:41::i;:::-;118685:171:::0;;;;:::o;117652:85::-;102711:13;:11;:13::i;:::-;117723:6:::1;117715:5;:14;;;;117652:85:::0;:::o;113594:35::-;;;;:::o;83109:187::-;83176:7;83212:13;:11;:13::i;:::-;83204:5;:21;83196:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;83283:5;83276:12;;83109:187;;;:::o;117932:111::-;102711:13;:11;:13::i;:::-;118022::::1;118010:9;:25;;;;117932:111:::0;:::o;86734:125::-;86798:7;86825:21;86838:7;86825:12;:21::i;:::-;:26;;;86818:33;;86734:125;;;:::o;84182:206::-;84246:7;84287:1;84270:19;;:5;:19;;;84266:60;;84298:28;;;;;;;;;;;;;;84266:60;84352:12;:19;84365:5;84352:19;;;;;;;;;;;;;;;:27;;;;;;;;;;;;84344:36;;84337:43;;84182:206;;;:::o;103473:103::-;102711:13;:11;:13::i;:::-;103538:30:::1;103565:1;103538:18;:30::i;:::-;103473:103::o:0;113507:33::-;;;;:::o;113913:46::-;;;;;;;;;;;;;;;;;:::o;116306:87::-;102711:13;:11;:13::i;:::-;116374:11:::1;;;;;;;;;;;116373:12;116359:11;;:26;;;;;;;;;;;;;;;;;;116306:87::o:0;113827:24::-;;;;:::o;115902:396::-;102711:13;:11;:13::i;:::-;115975:17:::1;115995:14;;115975:34;;116056:9;;116046:6;116030:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:35;;116022:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;116129:6;116116:9;:19;;116108:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;116208:6;116196:9;:18;;;;:::i;:::-;116179:14;:35;;;;116225:29;116235:10;116247:6;116225:9;:29::i;:::-;115964:334;115902:396:::0;:::o;102825:87::-;102871:7;102898:6;;;;;;;;;;;102891:13;;102825:87;:::o;116633:282::-;116732:10;116711:31;;:17;116719:8;116711:7;:17::i;:::-;:31;;;116703:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;116805:9;;116792;:22;;116784:90;;;;;;;;;;;;:::i;:::-;;;;;;;;;116887:15;116893:8;116887:5;:15::i;:::-;116633:282;:::o;117305:231::-;102711:13;:11;:13::i;:::-;117392:6:::1;117387:142;117408:8;;:15;;117404:1;:19;117387:142;;;117447:20;117455:8;;117464:1;117455:11;;;;;;;:::i;:::-;;;;;;;;117447:7;:20::i;:::-;117439:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;117501:18;117507:8;;117516:1;117507:11;;;;;;;:::i;:::-;;;;;;;;117501:5;:18::i;:::-;117425:3;;;;;:::i;:::-;;;;117387:142;;;;117305:231:::0;;:::o;87095:104::-;87151:13;87184:7;87177:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87095:104;:::o;116401:88::-;102711:13;:11;:13::i;:::-;116477:4:::1;116465:9;:16;;;;116401:88:::0;:::o;113454:46::-;;;;:::o;114547:1347::-;114614:16;114653:9;;114635:15;;:27;114634:84;;;;;114707:10;;114681:11;:23;114693:10;114681:23;;;;;;;;;;;;;;;;:36;114634:84;114614:105;;114736:11;114732:1114;;;114773:11;;;;;;;;;;;114765:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;114857:9;;114848:5;114832:13;:11;:13::i;:::-;:21;;;;:::i;:::-;:34;;114824:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;114910:5;;114901;:14;;114893:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;114980:11;:23;114992:10;114980:23;;;;;;;;;;;;;;;;114967:10;;:36;;;;:::i;:::-;114957:5;:47;114954:580;;115116:5;;115089:11;:23;115101:10;115089:23;;;;;;;;;;;;;;;;115076:10;;:36;;;;:::i;:::-;115075:46;;;;:::i;:::-;115065:5;;115057;:13;;;;:::i;:::-;115056:66;;;;:::i;:::-;115043:9;:79;;115035:124;;;;;;;;;;;;:::i;:::-;;;;;;;;;115201:10;;115175:11;:23;115187:10;115175:23;;;;;;;;;;;;;;;:36;;;;115246:10;;115227:15;;:29;;;;;;;:::i;:::-;;;;;;;;114954:580;;;115316:11;:23;115328:10;115316:23;;;;;;;;;;;;;;;;115303:10;;:36;;;;:::i;:::-;115294:5;:46;115291:243;;;115392:1;115379:9;:14;;115371:59;;;;;;;;;;;;:::i;:::-;;;;;;;;;115473:5;115446:11;:23;115458:10;115446:23;;;;;;;;;;;;;;;;:32;;;;;;;:::i;:::-;;;;;;;;115513:5;115494:15;;:24;;;;;;;:::i;:::-;;;;;;;;115291:243;114954:580;114732:1114;;;115582:11;;;;;;;;;;;115574:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;115662:5;;115654;:13;;;;:::i;:::-;115641:9;:26;;115633:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;115752:9;;115743:5;115727:13;:11;:13::i;:::-;:21;;;;:::i;:::-;:34;;115719:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;115805:5;;115796;:14;;115788:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;114732:1114;115858:28;115868:10;115880:5;115858:9;:28::i;:::-;114593:1301;114547:1347;:::o;117546:98::-;102711:13;:11;:13::i;:::-;117628:8:::1;117618:7;:18;;;;;;:::i;:::-;;117546:98:::0;:::o;118165:176::-;118269:8;41869:30;41890:8;41869:20;:30::i;:::-;118290:43:::1;118314:8;118324;118290:23;:43::i;:::-;118165:176:::0;;;:::o;117838:86::-;102711:13;:11;:13::i;:::-;117910:6:::1;117902:5;:14;;;;117838:86:::0;:::o;118864:228::-;119015:4;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;119037:47:::1;119060:4;119066:2;119070:7;119079:4;119037:22;:47::i;:::-;118864:228:::0;;;;;:::o;117745:84::-;117789:7;117816:5;;117809:12;;117745:84;:::o;113699:35::-;;;;:::o;114028:395::-;114102:13;114136:17;114144:8;114136:7;:17::i;:::-;114128:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;114215:28;114246:10;:8;:10::i;:::-;114215:41;;114305:1;114280:14;114274:28;:32;:141;;;;;;;;;;;;;;;;;114346:14;114361:26;114378:8;114361:16;:26::i;:::-;114329:67;;;;;;;;;:::i;:::-;;;;;;;;;;;;;114274:141;114267:148;;;114028:395;;;:::o;113665:25::-;;;;;;;;;;;;;:::o;113547:40::-;;;;:::o;113741:33::-;;;;:::o;118051:106::-;102711:13;:11;:13::i;:::-;118138:11:::1;118125:10;:24;;;;118051:106:::0;:::o;89176:164::-;89273:4;89297:18;:25;89316:5;89297:25;;;;;;;;;;;;;;;:35;89323:8;89297:35;;;;;;;;;;;;;;;;;;;;;;;;;89290:42;;89176:164;;;;:::o;116923:374::-;117045:9;;117027:8;;:15;;:27;;;;:::i;:::-;117013:9;:42;;117005:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;117130:6;117125:165;117146:8;;:15;;117142:1;:19;117125:165;;;117209:10;117185:34;;:20;117193:8;;117202:1;117193:11;;;;;;;:::i;:::-;;;;;;;;117185:7;:20::i;:::-;:34;;;117177:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;117261:18;117267:8;;117276:1;117267:11;;;;;;;:::i;:::-;;;;;;;;117261:5;:18::i;:::-;117163:3;;;;;:::i;:::-;;;;117125:165;;;;116923:374;;:::o;103731:201::-;102711:13;:11;:13::i;:::-;103840:1:::1;103820:22;;:8;:22;;::::0;103812:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;103896:28;103915:8;103896:18;:28::i;:::-;103731:201:::0;:::o;70370:157::-;70455:4;70494:25;70479:40;;;:11;:40;;;;70472:47;;70370:157;;;:::o;90603:174::-;90660:4;90703:7;90684:15;:13;:15::i;:::-;:26;;:53;;;;;90724:13;;90714:7;:23;90684:53;:85;;;;;90742:11;:20;90754:7;90742:20;;;;;;;;;;;:27;;;;;;;;;;;;90741:28;90684:85;90677:92;;90603:174;;;:::o;41927:419::-;42166:1;40448:42;42118:45;;;:49;42114:225;;;40448:42;42189;;;42240:4;42247:8;42189:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42184:144;;42303:8;42284:28;;;;;;;;;;;:::i;:::-;;;;;;;;42184:144;42114:225;41927:419;:::o;87992:445::-;88082:2;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;88097:13:::1;88113:24;88129:7;88113:15;:24::i;:::-;88097:40;;88162:5;88156:11;;:2;:11;;::::0;88148:58:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;88257:5;88241:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;88266:37;88283:5;88290:12;:10;:12::i;:::-;88266:16;:37::i;:::-;88241:62;88219:169;;;;;;;;;;;;:::i;:::-;;;;;;;;;88401:28;88410:2;88414:7;88423:5;88401:8;:28::i;:::-;88086:351;87992:445:::0;;;:::o;81678:92::-;81734:7;81678:92;:::o;89406:195::-;89549:4;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;89565:28:::1;89575:4;89581:2;89585:7;89565:9;:28::i;:::-;89406:195:::0;;;;:::o;102990:132::-;103065:12;:10;:12::i;:::-;103054:23;;:7;:5;:7::i;:::-;:23;;;103046:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;102990:132::o;89672:211::-;89819:4;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;89836:39:::1;89853:4;89859:2;89863:7;89836:39;;;;;;;;;;;::::0;:16:::1;:39::i;:::-;89672:211:::0;;;;:::o;85563:1109::-;85625:21;;:::i;:::-;85659:12;85674:7;85659:22;;85742:4;85723:15;:13;:15::i;:::-;:23;;:47;;;;;85757:13;;85750:4;:20;85723:47;85719:886;;;85791:31;85825:11;:17;85837:4;85825:17;;;;;;;;;;;85791:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85866:9;:16;;;85861:729;;85937:1;85911:28;;:9;:14;;;:28;;;85907:101;;85975:9;85968:16;;;;;;85907:101;86310:261;86317:4;86310:261;;;86350:6;;;;;;;;86395:11;:17;86407:4;86395:17;;;;;;;;;;;86383:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86469:1;86443:28;;:9;:14;;;:28;;;86439:109;;86511:9;86504:16;;;;;;86439:109;86310:261;;;85861:729;85772:833;85719:886;86633:31;;;;;;;;;;;;;;85563:1109;;;;:::o;104092:191::-;104166:16;104185:6;;;;;;;;;;;104166:25;;104211:8;104202:6;;:17;;;;;;;;;;;;;;;;;;104266:8;104235:40;;104256:8;104235:40;;;;;;;;;;;;104155:128;104092:191;:::o;90785:104::-;90854:27;90864:2;90868:8;90854:27;;;;;;;;;;;;:9;:27::i;:::-;90785:104;;:::o;95916:89::-;95976:21;95982:7;95991:5;95976;:21::i;:::-;95916:89;:::o;88779:326::-;88883:8;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;88924:12:::1;:10;:12::i;:::-;88912:24;;:8;:24;;::::0;88904:63:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;89025:8;88980:18;:32;88999:12;:10;:12::i;:::-;88980:32;;;;;;;;;;;;;;;:42;89013:8;88980:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;89078:8;89049:48;;89064:12;:10;:12::i;:::-;89049:48;;;89088:8;89049:48;;;;;;:::i;:::-;;;;;;;;88779:326:::0;;;:::o;89954:394::-;90130:4;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;90146:28:::1;90156:4;90162:2;90166:7;90146:9;:28::i;:::-;90189:15;:2;:13;;;:15::i;:::-;:76;;;;;90209:56;90240:4;90246:2;90250:7;90259:5;90209:30;:56::i;:::-;90208:57;90189:76;90185:156;;;90289:40;;;;;;;;;;;;;;90185:156;89954:394:::0;;;;;:::o;114431:108::-;114491:13;114524:7;114517:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;114431:108;:::o;56132:716::-;56188:13;56239:14;56276:1;56256:17;56267:5;56256:10;:17::i;:::-;:21;56239:38;;56292:20;56326:6;56315:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56292:41;;56348:11;56477:6;56473:2;56469:15;56461:6;56457:28;56450:35;;56514:288;56521:4;56514:288;;;56546:5;;;;;;;;56688:8;56683:2;56676:5;56672:14;56667:30;56662:3;56654:44;56744:2;56735:11;;;;;;:::i;:::-;;;;;56778:1;56769:5;:10;56514:288;56765:21;56514:288;56823:6;56816:13;;;;;56132:716;;;:::o;77908:98::-;77961:7;77988:10;77981:17;;77908:98;:::o;98760:196::-;98902:2;98875:15;:24;98891:7;98875:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;98940:7;98936:2;98920:28;;98929:5;98920:28;;;;;;;;;;;;98760:196;;;:::o;93703:2130::-;93818:35;93856:21;93869:7;93856:12;:21::i;:::-;93818:59;;93916:4;93894:26;;:13;:18;;;:26;;;93890:67;;93929:28;;;;;;;;;;;;;;93890:67;93970:22;94012:4;93996:20;;:12;:10;:12::i;:::-;:20;;;:73;;;;94033:36;94050:4;94056:12;:10;:12::i;:::-;94033:16;:36::i;:::-;93996:73;:126;;;;94110:12;:10;:12::i;:::-;94086:36;;:20;94098:7;94086:11;:20::i;:::-;:36;;;93996:126;93970:153;;94141:17;94136:66;;94167:35;;;;;;;;;;;;;;94136:66;94231:1;94217:16;;:2;:16;;;94213:52;;94242:23;;;;;;;;;;;;;;94213:52;94278:43;94300:4;94306:2;94310:7;94319:1;94278:21;:43::i;:::-;94386:35;94403:1;94407:7;94416:4;94386:8;:35::i;:::-;94747:1;94717:12;:18;94730:4;94717:18;;;;;;;;;;;;;;;:26;;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94791:1;94763:12;:16;94776:2;94763:16;;;;;;;;;;;;;;;:24;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94809:31;94843:11;:20;94855:7;94843:20;;;;;;;;;;;94809:54;;94894:2;94878:8;:13;;;:18;;;;;;;;;;;;;;;;;;94944:15;94911:8;:23;;;:49;;;;;;;;;;;;;;;;;;95212:19;95244:1;95234:7;:11;95212:33;;95260:31;95294:11;:24;95306:11;95294:24;;;;;;;;;;;95260:58;;95362:1;95337:27;;:8;:13;;;;;;;;;;;;:27;;;95333:384;;95547:13;;95532:11;:28;95528:174;;95601:4;95585:8;:13;;;:20;;;;;;;;;;;;;;;;;;95654:13;:28;;;95628:8;:23;;;:54;;;;;;;;;;;;;;;;;;95528:174;95333:384;94692:1036;;;95764:7;95760:2;95745:27;;95754:4;95745:27;;;;;;;;;;;;95783:42;95804:4;95810:2;95814:7;95823:1;95783:20;:42::i;:::-;93807:2026;;93703:2130;;;:::o;91252:163::-;91375:32;91381:2;91385:8;91395:5;91402:4;91375:5;:32::i;:::-;91252:163;;;:::o;96234:2408::-;96314:35;96352:21;96365:7;96352:12;:21::i;:::-;96314:59;;96386:12;96401:13;:18;;;96386:33;;96436:13;96432:290;;;96466:22;96508:4;96492:20;;:12;:10;:12::i;:::-;:20;;;:77;;;;96533:36;96550:4;96556:12;:10;:12::i;:::-;96533:16;:36::i;:::-;96492:77;:134;;;;96614:12;:10;:12::i;:::-;96590:36;;:20;96602:7;96590:11;:20::i;:::-;:36;;;96492:134;96466:161;;96649:17;96644:66;;96675:35;;;;;;;;;;;;;;96644:66;96451:271;96432:290;96734:51;96756:4;96770:1;96774:7;96783:1;96734:21;:51::i;:::-;96850:35;96867:1;96871:7;96880:4;96850:8;:35::i;:::-;97181:31;97215:12;:18;97228:4;97215:18;;;;;;;;;;;;;;;97181:52;;97271:1;97248:11;:19;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97315:1;97287:11;:24;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97415:31;97449:11;:20;97461:7;97449:20;;;;;;;;;;;97415:54;;97500:4;97484:8;:13;;;:20;;;;;;;;;;;;;;;;;;97552:15;97519:8;:23;;;:49;;;;;;;;;;;;;;;;;;97601:4;97583:8;:15;;;:22;;;;;;;;;;;;;;;;;;97853:19;97885:1;97875:7;:11;97853:33;;97901:31;97935:11;:24;97947:11;97935:24;;;;;;;;;;;97901:58;;98003:1;97978:27;;:8;:13;;;;;;;;;;;;:27;;;97974:384;;98188:13;;98173:11;:28;98169:174;;98242:4;98226:8;:13;;;:20;;;;;;;;;;;;;;;;;;98295:13;:28;;;98269:8;:23;;;:54;;;;;;;;;;;;;;;;;;98169:174;97974:384;97156:1213;;;;98413:7;98409:1;98386:35;;98395:4;98386:35;;;;;;;;;;;;98432:50;98453:4;98467:1;98471:7;98480:1;98432:20;:50::i;:::-;98609:12;;:14;;;;;;;;;;;;;96303:2339;;96234:2408;;:::o;59259:326::-;59319:4;59576:1;59554:7;:19;;;:23;59547:30;;59259:326;;;:::o;99448:667::-;99611:4;99648:2;99632:36;;;99669:12;:10;:12::i;:::-;99683:4;99689:7;99698:5;99632:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;99628:480;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99883:1;99866:6;:13;:18;99862:235;;99912:40;;;;;;;;;;;;;;99862:235;100055:6;100049:13;100040:6;100036:2;100032:15;100025:38;99628:480;99761:45;;;99751:55;;;:6;:55;;;;99744:62;;;99448:667;;;;;;:::o;52998:922::-;53051:7;53071:14;53088:1;53071:18;;53138:6;53129:5;:15;53125:102;;53174:6;53165:15;;;;;;:::i;:::-;;;;;53209:2;53199:12;;;;53125:102;53254:6;53245:5;:15;53241:102;;53290:6;53281:15;;;;;;:::i;:::-;;;;;53325:2;53315:12;;;;53241:102;53370:6;53361:5;:15;53357:102;;53406:6;53397:15;;;;;;:::i;:::-;;;;;53441:2;53431:12;;;;53357:102;53486:5;53477;:14;53473:99;;53521:5;53512:14;;;;;;:::i;:::-;;;;;53555:1;53545:11;;;;53473:99;53599:5;53590;:14;53586:99;;53634:5;53625:14;;;;;;:::i;:::-;;;;;53668:1;53658:11;;;;53586:99;53712:5;53703;:14;53699:99;;53747:5;53738:14;;;;;;:::i;:::-;;;;;53781:1;53771:11;;;;53699:99;53825:5;53816;:14;53812:66;;53861:1;53851:11;;;;53812:66;53906:6;53899:13;;;52998:922;;;:::o;100763:159::-;;;;;:::o;101581:158::-;;;;;:::o;91674:1775::-;91813:20;91836:13;;91813:36;;91878:1;91864:16;;:2;:16;;;91860:48;;91889:19;;;;;;;;;;;;;;91860:48;91935:1;91923:8;:13;91919:44;;91945:18;;;;;;;;;;;;;;91919:44;91976:61;92006:1;92010:2;92014:12;92028:8;91976:21;:61::i;:::-;92349:8;92314:12;:16;92327:2;92314:16;;;;;;;;;;;;;;;:24;;;:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92413:8;92373:12;:16;92386:2;92373:16;;;;;;;;;;;;;;;:29;;;:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92472:2;92439:11;:25;92451:12;92439:25;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;92539:15;92489:11;:25;92501:12;92489:25;;;;;;;;;;;:40;;;:66;;;;;;;;;;;;;;;;;;92572:20;92595:12;92572:35;;92622:11;92651:8;92636:12;:23;92622:37;;92680:4;:23;;;;;92688:15;:2;:13;;;:15::i;:::-;92680:23;92676:641;;;92724:314;92780:12;92776:2;92755:38;;92772:1;92755:38;;;;;;;;;;;;92821:69;92860:1;92864:2;92868:14;;;;;;92884:5;92821:30;:69::i;:::-;92816:174;;92926:40;;;;;;;;;;;;;;92816:174;93033:3;93017:12;:19;92724:314;;93119:12;93102:13;;:29;93098:43;;93133:8;;;93098:43;92676:641;;;93182:120;93238:14;;;;;;93234:2;93213:40;;93230:1;93213:40;;;;;;;;;;;;93297:3;93281:12;:19;93182:120;;92676:641;93347:12;93331:13;:28;;;;92289:1082;;93381:60;93410:1;93414:2;93418:12;93432:8;93381:20;:60::i;:::-;91802:1647;91674:1775;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:77::-;2897:7;2926:5;2915:16;;2860:77;;;:::o;2943:122::-;3016:24;3034:5;3016:24;:::i;:::-;3009:5;3006:35;2996:63;;3055:1;3052;3045:12;2996:63;2943:122;:::o;3071:139::-;3117:5;3155:6;3142:20;3133:29;;3171:33;3198:5;3171:33;:::i;:::-;3071:139;;;;:::o;3216:329::-;3275:6;3324:2;3312:9;3303:7;3299:23;3295:32;3292:119;;;3330:79;;:::i;:::-;3292:119;3450:1;3475:53;3520:7;3511:6;3500:9;3496:22;3475:53;:::i;:::-;3465:63;;3421:117;3216:329;;;;:::o;3551:126::-;3588:7;3628:42;3621:5;3617:54;3606:65;;3551:126;;;:::o;3683:96::-;3720:7;3749:24;3767:5;3749:24;:::i;:::-;3738:35;;3683:96;;;:::o;3785:118::-;3872:24;3890:5;3872:24;:::i;:::-;3867:3;3860:37;3785:118;;:::o;3909:222::-;4002:4;4040:2;4029:9;4025:18;4017:26;;4053:71;4121:1;4110:9;4106:17;4097:6;4053:71;:::i;:::-;3909:222;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:474::-;4478:6;4486;4535:2;4523:9;4514:7;4510:23;4506:32;4503:119;;;4541:79;;:::i;:::-;4503:119;4661:1;4686:53;4731:7;4722:6;4711:9;4707:22;4686:53;:::i;:::-;4676:63;;4632:117;4788:2;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4759:118;4410:474;;;;;:::o;4890:118::-;4977:24;4995:5;4977:24;:::i;:::-;4972:3;4965:37;4890:118;;:::o;5014:222::-;5107:4;5145:2;5134:9;5130:18;5122:26;;5158:71;5226:1;5215:9;5211:17;5202:6;5158:71;:::i;:::-;5014:222;;;;:::o;5242:619::-;5319:6;5327;5335;5384:2;5372:9;5363:7;5359:23;5355:32;5352:119;;;5390:79;;:::i;:::-;5352:119;5510:1;5535:53;5580:7;5571:6;5560:9;5556:22;5535:53;:::i;:::-;5525:63;;5481:117;5637:2;5663:53;5708:7;5699:6;5688:9;5684:22;5663:53;:::i;:::-;5653:63;;5608:118;5765:2;5791:53;5836:7;5827:6;5816:9;5812:22;5791:53;:::i;:::-;5781:63;;5736:118;5242:619;;;;;:::o;5867:60::-;5895:3;5916:5;5909:12;;5867:60;;;:::o;5933:142::-;5983:9;6016:53;6034:34;6043:24;6061:5;6043:24;:::i;:::-;6034:34;:::i;:::-;6016:53;:::i;:::-;6003:66;;5933:142;;;:::o;6081:126::-;6131:9;6164:37;6195:5;6164:37;:::i;:::-;6151:50;;6081:126;;;:::o;6213:157::-;6294:9;6327:37;6358:5;6327:37;:::i;:::-;6314:50;;6213:157;;;:::o;6376:193::-;6494:68;6556:5;6494:68;:::i;:::-;6489:3;6482:81;6376:193;;:::o;6575:284::-;6699:4;6737:2;6726:9;6722:18;6714:26;;6750:102;6849:1;6838:9;6834:17;6825:6;6750:102;:::i;:::-;6575:284;;;;:::o;6865:329::-;6924:6;6973:2;6961:9;6952:7;6948:23;6944:32;6941:119;;;6979:79;;:::i;:::-;6941:119;7099:1;7124:53;7169:7;7160:6;7149:9;7145:22;7124:53;:::i;:::-;7114:63;;7070:117;6865:329;;;;:::o;7200:117::-;7309:1;7306;7299:12;7323:117;7432:1;7429;7422:12;7446:117;7555:1;7552;7545:12;7586:568;7659:8;7669:6;7719:3;7712:4;7704:6;7700:17;7696:27;7686:122;;7727:79;;:::i;:::-;7686:122;7840:6;7827:20;7817:30;;7870:18;7862:6;7859:30;7856:117;;;7892:79;;:::i;:::-;7856:117;8006:4;7998:6;7994:17;7982:29;;8060:3;8052:4;8044:6;8040:17;8030:8;8026:32;8023:41;8020:128;;;8067:79;;:::i;:::-;8020:128;7586:568;;;;;:::o;8160:559::-;8246:6;8254;8303:2;8291:9;8282:7;8278:23;8274:32;8271:119;;;8309:79;;:::i;:::-;8271:119;8457:1;8446:9;8442:17;8429:31;8487:18;8479:6;8476:30;8473:117;;;8509:79;;:::i;:::-;8473:117;8622:80;8694:7;8685:6;8674:9;8670:22;8622:80;:::i;:::-;8604:98;;;;8400:312;8160:559;;;;;:::o;8725:117::-;8834:1;8831;8824:12;8848:180;8896:77;8893:1;8886:88;8993:4;8990:1;8983:15;9017:4;9014:1;9007:15;9034:281;9117:27;9139:4;9117:27;:::i;:::-;9109:6;9105:40;9247:6;9235:10;9232:22;9211:18;9199:10;9196:34;9193:62;9190:88;;;9258:18;;:::i;:::-;9190:88;9298:10;9294:2;9287:22;9077:238;9034:281;;:::o;9321:129::-;9355:6;9382:20;;:::i;:::-;9372:30;;9411:33;9439:4;9431:6;9411:33;:::i;:::-;9321:129;;;:::o;9456:308::-;9518:4;9608:18;9600:6;9597:30;9594:56;;;9630:18;;:::i;:::-;9594:56;9668:29;9690:6;9668:29;:::i;:::-;9660:37;;9752:4;9746;9742:15;9734:23;;9456:308;;;:::o;9770:146::-;9867:6;9862:3;9857;9844:30;9908:1;9899:6;9894:3;9890:16;9883:27;9770:146;;;:::o;9922:425::-;10000:5;10025:66;10041:49;10083:6;10041:49;:::i;:::-;10025:66;:::i;:::-;10016:75;;10114:6;10107:5;10100:21;10152:4;10145:5;10141:16;10190:3;10181:6;10176:3;10172:16;10169:25;10166:112;;;10197:79;;:::i;:::-;10166:112;10287:54;10334:6;10329:3;10324;10287:54;:::i;:::-;10006:341;9922:425;;;;;:::o;10367:340::-;10423:5;10472:3;10465:4;10457:6;10453:17;10449:27;10439:122;;10480:79;;:::i;:::-;10439:122;10597:6;10584:20;10622:79;10697:3;10689:6;10682:4;10674:6;10670:17;10622:79;:::i;:::-;10613:88;;10429:278;10367:340;;;;:::o;10713:509::-;10782:6;10831:2;10819:9;10810:7;10806:23;10802:32;10799:119;;;10837:79;;:::i;:::-;10799:119;10985:1;10974:9;10970:17;10957:31;11015:18;11007:6;11004:30;11001:117;;;11037:79;;:::i;:::-;11001:117;11142:63;11197:7;11188:6;11177:9;11173:22;11142:63;:::i;:::-;11132:73;;10928:287;10713:509;;;;:::o;11228:116::-;11298:21;11313:5;11298:21;:::i;:::-;11291:5;11288:32;11278:60;;11334:1;11331;11324:12;11278:60;11228:116;:::o;11350:133::-;11393:5;11431:6;11418:20;11409:29;;11447:30;11471:5;11447:30;:::i;:::-;11350:133;;;;:::o;11489:468::-;11554:6;11562;11611:2;11599:9;11590:7;11586:23;11582:32;11579:119;;;11617:79;;:::i;:::-;11579:119;11737:1;11762:53;11807:7;11798:6;11787:9;11783:22;11762:53;:::i;:::-;11752:63;;11708:117;11864:2;11890:50;11932:7;11923:6;11912:9;11908:22;11890:50;:::i;:::-;11880:60;;11835:115;11489:468;;;;;:::o;11963:307::-;12024:4;12114:18;12106:6;12103:30;12100:56;;;12136:18;;:::i;:::-;12100:56;12174:29;12196:6;12174:29;:::i;:::-;12166:37;;12258:4;12252;12248:15;12240:23;;11963:307;;;:::o;12276:423::-;12353:5;12378:65;12394:48;12435:6;12394:48;:::i;:::-;12378:65;:::i;:::-;12369:74;;12466:6;12459:5;12452:21;12504:4;12497:5;12493:16;12542:3;12533:6;12528:3;12524:16;12521:25;12518:112;;;12549:79;;:::i;:::-;12518:112;12639:54;12686:6;12681:3;12676;12639:54;:::i;:::-;12359:340;12276:423;;;;;:::o;12718:338::-;12773:5;12822:3;12815:4;12807:6;12803:17;12799:27;12789:122;;12830:79;;:::i;:::-;12789:122;12947:6;12934:20;12972:78;13046:3;13038:6;13031:4;13023:6;13019:17;12972:78;:::i;:::-;12963:87;;12779:277;12718:338;;;;:::o;13062:943::-;13157:6;13165;13173;13181;13230:3;13218:9;13209:7;13205:23;13201:33;13198:120;;;13237:79;;:::i;:::-;13198:120;13357:1;13382:53;13427:7;13418:6;13407:9;13403:22;13382:53;:::i;:::-;13372:63;;13328:117;13484:2;13510:53;13555:7;13546:6;13535:9;13531:22;13510:53;:::i;:::-;13500:63;;13455:118;13612:2;13638:53;13683:7;13674:6;13663:9;13659:22;13638:53;:::i;:::-;13628:63;;13583:118;13768:2;13757:9;13753:18;13740:32;13799:18;13791:6;13788:30;13785:117;;;13821:79;;:::i;:::-;13785:117;13926:62;13980:7;13971:6;13960:9;13956:22;13926:62;:::i;:::-;13916:72;;13711:287;13062:943;;;;;;;:::o;14011:474::-;14079:6;14087;14136:2;14124:9;14115:7;14111:23;14107:32;14104:119;;;14142:79;;:::i;:::-;14104:119;14262:1;14287:53;14332:7;14323:6;14312:9;14308:22;14287:53;:::i;:::-;14277:63;;14233:117;14389:2;14415:53;14460:7;14451:6;14440:9;14436:22;14415:53;:::i;:::-;14405:63;;14360:118;14011:474;;;;;:::o;14491:180::-;14539:77;14536:1;14529:88;14636:4;14633:1;14626:15;14660:4;14657:1;14650:15;14677:320;14721:6;14758:1;14752:4;14748:12;14738:22;;14805:1;14799:4;14795:12;14826:18;14816:81;;14882:4;14874:6;14870:17;14860:27;;14816:81;14944:2;14936:6;14933:14;14913:18;14910:38;14907:84;;14963:18;;:::i;:::-;14907:84;14728:269;14677:320;;;:::o;15003:221::-;15143:34;15139:1;15131:6;15127:14;15120:58;15212:4;15207:2;15199:6;15195:15;15188:29;15003:221;:::o;15230:366::-;15372:3;15393:67;15457:2;15452:3;15393:67;:::i;:::-;15386:74;;15469:93;15558:3;15469:93;:::i;:::-;15587:2;15582:3;15578:12;15571:19;;15230:366;;;:::o;15602:419::-;15768:4;15806:2;15795:9;15791:18;15783:26;;15855:9;15849:4;15845:20;15841:1;15830:9;15826:17;15819:47;15883:131;16009:4;15883:131;:::i;:::-;15875:139;;15602:419;;;:::o;16027:233::-;16167:34;16163:1;16155:6;16151:14;16144:58;16236:16;16231:2;16223:6;16219:15;16212:41;16027:233;:::o;16266:366::-;16408:3;16429:67;16493:2;16488:3;16429:67;:::i;:::-;16422:74;;16505:93;16594:3;16505:93;:::i;:::-;16623:2;16618:3;16614:12;16607:19;;16266:366;;;:::o;16638:419::-;16804:4;16842:2;16831:9;16827:18;16819:26;;16891:9;16885:4;16881:20;16877:1;16866:9;16862:17;16855:47;16919:131;17045:4;16919:131;:::i;:::-;16911:139;;16638:419;;;:::o;17063:181::-;17203:33;17199:1;17191:6;17187:14;17180:57;17063:181;:::o;17250:366::-;17392:3;17413:67;17477:2;17472:3;17413:67;:::i;:::-;17406:74;;17489:93;17578:3;17489:93;:::i;:::-;17607:2;17602:3;17598:12;17591:19;;17250:366;;;:::o;17622:419::-;17788:4;17826:2;17815:9;17811:18;17803:26;;17875:9;17869:4;17865:20;17861:1;17850:9;17846:17;17839:47;17903:131;18029:4;17903:131;:::i;:::-;17895:139;;17622:419;;;:::o;18047:147::-;18148:11;18185:3;18170:18;;18047:147;;;;:::o;18200:114::-;;:::o;18320:398::-;18479:3;18500:83;18581:1;18576:3;18500:83;:::i;:::-;18493:90;;18592:93;18681:3;18592:93;:::i;:::-;18710:1;18705:3;18701:11;18694:18;;18320:398;;;:::o;18724:379::-;18908:3;18930:147;19073:3;18930:147;:::i;:::-;18923:154;;19094:3;19087:10;;18724:379;;;:::o;19109:166::-;19249:18;19245:1;19237:6;19233:14;19226:42;19109:166;:::o;19281:366::-;19423:3;19444:67;19508:2;19503:3;19444:67;:::i;:::-;19437:74;;19520:93;19609:3;19520:93;:::i;:::-;19638:2;19633:3;19629:12;19622:19;;19281:366;;;:::o;19653:419::-;19819:4;19857:2;19846:9;19842:18;19834:26;;19906:9;19900:4;19896:20;19892:1;19881:9;19877:17;19870:47;19934:131;20060:4;19934:131;:::i;:::-;19926:139;;19653:419;;;:::o;20078:222::-;20218:34;20214:1;20206:6;20202:14;20195:58;20287:5;20282:2;20274:6;20270:15;20263:30;20078:222;:::o;20306:366::-;20448:3;20469:67;20533:2;20528:3;20469:67;:::i;:::-;20462:74;;20545:93;20634:3;20545:93;:::i;:::-;20663:2;20658:3;20654:12;20647:19;;20306:366;;;:::o;20678:419::-;20844:4;20882:2;20871:9;20867:18;20859:26;;20931:9;20925:4;20921:20;20917:1;20906:9;20902:17;20895:47;20959:131;21085:4;20959:131;:::i;:::-;20951:139;;20678:419;;;:::o;21103:180::-;21151:77;21148:1;21141:88;21248:4;21245:1;21238:15;21272:4;21269:1;21262:15;21289:191;21329:3;21348:20;21366:1;21348:20;:::i;:::-;21343:25;;21382:20;21400:1;21382:20;:::i;:::-;21377:25;;21425:1;21422;21418:9;21411:16;;21446:3;21443:1;21440:10;21437:36;;;21453:18;;:::i;:::-;21437:36;21289:191;;;;:::o;21486:177::-;21626:29;21622:1;21614:6;21610:14;21603:53;21486:177;:::o;21669:366::-;21811:3;21832:67;21896:2;21891:3;21832:67;:::i;:::-;21825:74;;21908:93;21997:3;21908:93;:::i;:::-;22026:2;22021:3;22017:12;22010:19;;21669:366;;;:::o;22041:419::-;22207:4;22245:2;22234:9;22230:18;22222:26;;22294:9;22288:4;22284:20;22280:1;22269:9;22265:17;22258:47;22322:131;22448:4;22322:131;:::i;:::-;22314:139;;22041:419;;;:::o;22466:172::-;22606:24;22602:1;22594:6;22590:14;22583:48;22466:172;:::o;22644:366::-;22786:3;22807:67;22871:2;22866:3;22807:67;:::i;:::-;22800:74;;22883:93;22972:3;22883:93;:::i;:::-;23001:2;22996:3;22992:12;22985:19;;22644:366;;;:::o;23016:419::-;23182:4;23220:2;23209:9;23205:18;23197:26;;23269:9;23263:4;23259:20;23255:1;23244:9;23240:17;23233:47;23297:131;23423:4;23297:131;:::i;:::-;23289:139;;23016:419;;;:::o;23441:194::-;23481:4;23501:20;23519:1;23501:20;:::i;:::-;23496:25;;23535:20;23553:1;23535:20;:::i;:::-;23530:25;;23579:1;23576;23572:9;23564:17;;23603:1;23597:4;23594:11;23591:37;;;23608:18;;:::i;:::-;23591:37;23441:194;;;;:::o;23641:176::-;23781:28;23777:1;23769:6;23765:14;23758:52;23641:176;:::o;23823:366::-;23965:3;23986:67;24050:2;24045:3;23986:67;:::i;:::-;23979:74;;24062:93;24151:3;24062:93;:::i;:::-;24180:2;24175:3;24171:12;24164:19;;23823:366;;;:::o;24195:419::-;24361:4;24399:2;24388:9;24384:18;24376:26;;24448:9;24442:4;24438:20;24434:1;24423:9;24419:17;24412:47;24476:131;24602:4;24476:131;:::i;:::-;24468:139;;24195:419;;;:::o;24620:242::-;24760:34;24756:1;24748:6;24744:14;24737:58;24829:25;24824:2;24816:6;24812:15;24805:50;24620:242;:::o;24868:366::-;25010:3;25031:67;25095:2;25090:3;25031:67;:::i;:::-;25024:74;;25107:93;25196:3;25107:93;:::i;:::-;25225:2;25220:3;25216:12;25209:19;;24868:366;;;:::o;25240:419::-;25406:4;25444:2;25433:9;25429:18;25421:26;;25493:9;25487:4;25483:20;25479:1;25468:9;25464:17;25457:47;25521:131;25647:4;25521:131;:::i;:::-;25513:139;;25240:419;;;:::o;25665:180::-;25713:77;25710:1;25703:88;25810:4;25807:1;25800:15;25834:4;25831:1;25824:15;25851:170;25991:22;25987:1;25979:6;25975:14;25968:46;25851:170;:::o;26027:366::-;26169:3;26190:67;26254:2;26249:3;26190:67;:::i;:::-;26183:74;;26266:93;26355:3;26266:93;:::i;:::-;26384:2;26379:3;26375:12;26368:19;;26027:366;;;:::o;26399:419::-;26565:4;26603:2;26592:9;26588:18;26580:26;;26652:9;26646:4;26642:20;26638:1;26627:9;26623:17;26616:47;26680:131;26806:4;26680:131;:::i;:::-;26672:139;;26399:419;;;:::o;26824:233::-;26863:3;26886:24;26904:5;26886:24;:::i;:::-;26877:33;;26932:66;26925:5;26922:77;26919:103;;27002:18;;:::i;:::-;26919:103;27049:1;27042:5;27038:13;27031:20;;26824:233;;;:::o;27063:170::-;27203:22;27199:1;27191:6;27187:14;27180:46;27063:170;:::o;27239:366::-;27381:3;27402:67;27466:2;27461:3;27402:67;:::i;:::-;27395:74;;27478:93;27567:3;27478:93;:::i;:::-;27596:2;27591:3;27587:12;27580:19;;27239:366;;;:::o;27611:419::-;27777:4;27815:2;27804:9;27800:18;27792:26;;27864:9;27858:4;27854:20;27850:1;27839:9;27835:17;27828:47;27892:131;28018:4;27892:131;:::i;:::-;27884:139;;27611:419;;;:::o;28036:157::-;28176:9;28172:1;28164:6;28160:14;28153:33;28036:157;:::o;28199:365::-;28341:3;28362:66;28426:1;28421:3;28362:66;:::i;:::-;28355:73;;28437:93;28526:3;28437:93;:::i;:::-;28555:2;28550:3;28546:12;28539:19;;28199:365;;;:::o;28570:419::-;28736:4;28774:2;28763:9;28759:18;28751:26;;28823:9;28817:4;28813:20;28809:1;28798:9;28794:17;28787:47;28851:131;28977:4;28851:131;:::i;:::-;28843:139;;28570:419;;;:::o;28995:169::-;29135:21;29131:1;29123:6;29119:14;29112:45;28995:169;:::o;29170:366::-;29312:3;29333:67;29397:2;29392:3;29333:67;:::i;:::-;29326:74;;29409:93;29498:3;29409:93;:::i;:::-;29527:2;29522:3;29518:12;29511:19;;29170:366;;;:::o;29542:419::-;29708:4;29746:2;29735:9;29731:18;29723:26;;29795:9;29789:4;29785:20;29781:1;29770:9;29766:17;29759:47;29823:131;29949:4;29823:131;:::i;:::-;29815:139;;29542:419;;;:::o;29967:410::-;30007:7;30030:20;30048:1;30030:20;:::i;:::-;30025:25;;30064:20;30082:1;30064:20;:::i;:::-;30059:25;;30119:1;30116;30112:9;30141:30;30159:11;30141:30;:::i;:::-;30130:41;;30320:1;30311:7;30307:15;30304:1;30301:22;30281:1;30274:9;30254:83;30231:139;;30350:18;;:::i;:::-;30231:139;30015:362;29967:410;;;;:::o;30383:182::-;30523:34;30519:1;30511:6;30507:14;30500:58;30383:182;:::o;30571:366::-;30713:3;30734:67;30798:2;30793:3;30734:67;:::i;:::-;30727:74;;30810:93;30899:3;30810:93;:::i;:::-;30928:2;30923:3;30919:12;30912:19;;30571:366;;;:::o;30943:419::-;31109:4;31147:2;31136:9;31132:18;31124:26;;31196:9;31190:4;31186:20;31182:1;31171:9;31167:17;31160:47;31224:131;31350:4;31224:131;:::i;:::-;31216:139;;30943:419;;;:::o;31368:141::-;31417:4;31440:3;31432:11;;31463:3;31460:1;31453:14;31497:4;31494:1;31484:18;31476:26;;31368:141;;;:::o;31515:93::-;31552:6;31599:2;31594;31587:5;31583:14;31579:23;31569:33;;31515:93;;;:::o;31614:107::-;31658:8;31708:5;31702:4;31698:16;31677:37;;31614:107;;;;:::o;31727:393::-;31796:6;31846:1;31834:10;31830:18;31869:97;31899:66;31888:9;31869:97;:::i;:::-;31987:39;32017:8;32006:9;31987:39;:::i;:::-;31975:51;;32059:4;32055:9;32048:5;32044:21;32035:30;;32108:4;32098:8;32094:19;32087:5;32084:30;32074:40;;31803:317;;31727:393;;;;;:::o;32126:142::-;32176:9;32209:53;32227:34;32236:24;32254:5;32236:24;:::i;:::-;32227:34;:::i;:::-;32209:53;:::i;:::-;32196:66;;32126:142;;;:::o;32274:75::-;32317:3;32338:5;32331:12;;32274:75;;;:::o;32355:269::-;32465:39;32496:7;32465:39;:::i;:::-;32526:91;32575:41;32599:16;32575:41;:::i;:::-;32567:6;32560:4;32554:11;32526:91;:::i;:::-;32520:4;32513:105;32431:193;32355:269;;;:::o;32630:73::-;32675:3;32630:73;:::o;32709:189::-;32786:32;;:::i;:::-;32827:65;32885:6;32877;32871:4;32827:65;:::i;:::-;32762:136;32709:189;;:::o;32904:186::-;32964:120;32981:3;32974:5;32971:14;32964:120;;;33035:39;33072:1;33065:5;33035:39;:::i;:::-;33008:1;33001:5;32997:13;32988:22;;32964:120;;;32904:186;;:::o;33096:543::-;33197:2;33192:3;33189:11;33186:446;;;33231:38;33263:5;33231:38;:::i;:::-;33315:29;33333:10;33315:29;:::i;:::-;33305:8;33301:44;33498:2;33486:10;33483:18;33480:49;;;33519:8;33504:23;;33480:49;33542:80;33598:22;33616:3;33598:22;:::i;:::-;33588:8;33584:37;33571:11;33542:80;:::i;:::-;33201:431;;33186:446;33096:543;;;:::o;33645:117::-;33699:8;33749:5;33743:4;33739:16;33718:37;;33645:117;;;;:::o;33768:169::-;33812:6;33845:51;33893:1;33889:6;33881:5;33878:1;33874:13;33845:51;:::i;:::-;33841:56;33926:4;33920;33916:15;33906:25;;33819:118;33768:169;;;;:::o;33942:295::-;34018:4;34164:29;34189:3;34183:4;34164:29;:::i;:::-;34156:37;;34226:3;34223:1;34219:11;34213:4;34210:21;34202:29;;33942:295;;;;:::o;34242:1395::-;34359:37;34392:3;34359:37;:::i;:::-;34461:18;34453:6;34450:30;34447:56;;;34483:18;;:::i;:::-;34447:56;34527:38;34559:4;34553:11;34527:38;:::i;:::-;34612:67;34672:6;34664;34658:4;34612:67;:::i;:::-;34706:1;34730:4;34717:17;;34762:2;34754:6;34751:14;34779:1;34774:618;;;;35436:1;35453:6;35450:77;;;35502:9;35497:3;35493:19;35487:26;35478:35;;35450:77;35553:67;35613:6;35606:5;35553:67;:::i;:::-;35547:4;35540:81;35409:222;34744:887;;34774:618;34826:4;34822:9;34814:6;34810:22;34860:37;34892:4;34860:37;:::i;:::-;34919:1;34933:208;34947:7;34944:1;34941:14;34933:208;;;35026:9;35021:3;35017:19;35011:26;35003:6;34996:42;35077:1;35069:6;35065:14;35055:24;;35124:2;35113:9;35109:18;35096:31;;34970:4;34967:1;34963:12;34958:17;;34933:208;;;35169:6;35160:7;35157:19;35154:179;;;35227:9;35222:3;35218:19;35212:26;35270:48;35312:4;35304:6;35300:17;35289:9;35270:48;:::i;:::-;35262:6;35255:64;35177:156;35154:179;35379:1;35375;35367:6;35363:14;35359:22;35353:4;35346:36;34781:611;;;34744:887;;34334:1303;;;34242:1395;;:::o;35643:234::-;35783:34;35779:1;35771:6;35767:14;35760:58;35852:17;35847:2;35839:6;35835:15;35828:42;35643:234;:::o;35883:366::-;36025:3;36046:67;36110:2;36105:3;36046:67;:::i;:::-;36039:74;;36122:93;36211:3;36122:93;:::i;:::-;36240:2;36235:3;36231:12;36224:19;;35883:366;;;:::o;36255:419::-;36421:4;36459:2;36448:9;36444:18;36436:26;;36508:9;36502:4;36498:20;36494:1;36483:9;36479:17;36472:47;36536:131;36662:4;36536:131;:::i;:::-;36528:139;;36255:419;;;:::o;36680:148::-;36782:11;36819:3;36804:18;;36680:148;;;;:::o;36834:390::-;36940:3;36968:39;37001:5;36968:39;:::i;:::-;37023:89;37105:6;37100:3;37023:89;:::i;:::-;37016:96;;37121:65;37179:6;37174:3;37167:4;37160:5;37156:16;37121:65;:::i;:::-;37211:6;37206:3;37202:16;37195:23;;36944:280;36834:390;;;;:::o;37230:155::-;37370:7;37366:1;37358:6;37354:14;37347:31;37230:155;:::o;37391:400::-;37551:3;37572:84;37654:1;37649:3;37572:84;:::i;:::-;37565:91;;37665:93;37754:3;37665:93;:::i;:::-;37783:1;37778:3;37774:11;37767:18;;37391:400;;;:::o;37797:701::-;38078:3;38100:95;38191:3;38182:6;38100:95;:::i;:::-;38093:102;;38212:95;38303:3;38294:6;38212:95;:::i;:::-;38205:102;;38324:148;38468:3;38324:148;:::i;:::-;38317:155;;38489:3;38482:10;;37797:701;;;;;:::o;38504:225::-;38644:34;38640:1;38632:6;38628:14;38621:58;38713:8;38708:2;38700:6;38696:15;38689:33;38504:225;:::o;38735:366::-;38877:3;38898:67;38962:2;38957:3;38898:67;:::i;:::-;38891:74;;38974:93;39063:3;38974:93;:::i;:::-;39092:2;39087:3;39083:12;39076:19;;38735:366;;;:::o;39107:419::-;39273:4;39311:2;39300:9;39296:18;39288:26;;39360:9;39354:4;39350:20;39346:1;39335:9;39331:17;39324:47;39388:131;39514:4;39388:131;:::i;:::-;39380:139;;39107:419;;;:::o;39532:332::-;39653:4;39691:2;39680:9;39676:18;39668:26;;39704:71;39772:1;39761:9;39757:17;39748:6;39704:71;:::i;:::-;39785:72;39853:2;39842:9;39838:18;39829:6;39785:72;:::i;:::-;39532:332;;;;;:::o;39870:137::-;39924:5;39955:6;39949:13;39940:22;;39971:30;39995:5;39971:30;:::i;:::-;39870:137;;;;:::o;40013:345::-;40080:6;40129:2;40117:9;40108:7;40104:23;40100:32;40097:119;;;40135:79;;:::i;:::-;40097:119;40255:1;40280:61;40333:7;40324:6;40313:9;40309:22;40280:61;:::i;:::-;40270:71;;40226:125;40013:345;;;;:::o;40364:221::-;40504:34;40500:1;40492:6;40488:14;40481:58;40573:4;40568:2;40560:6;40556:15;40549:29;40364:221;:::o;40591:366::-;40733:3;40754:67;40818:2;40813:3;40754:67;:::i;:::-;40747:74;;40830:93;40919:3;40830:93;:::i;:::-;40948:2;40943:3;40939:12;40932:19;;40591:366;;;:::o;40963:419::-;41129:4;41167:2;41156:9;41152:18;41144:26;;41216:9;41210:4;41206:20;41202:1;41191:9;41187:17;41180:47;41244:131;41370:4;41244:131;:::i;:::-;41236:139;;40963:419;;;:::o;41388:244::-;41528:34;41524:1;41516:6;41512:14;41505:58;41597:27;41592:2;41584:6;41580:15;41573:52;41388:244;:::o;41638:366::-;41780:3;41801:67;41865:2;41860:3;41801:67;:::i;:::-;41794:74;;41877:93;41966:3;41877:93;:::i;:::-;41995:2;41990:3;41986:12;41979:19;;41638:366;;;:::o;42010:419::-;42176:4;42214:2;42203:9;42199:18;42191:26;;42263:9;42257:4;42253:20;42249:1;42238:9;42234:17;42227:47;42291:131;42417:4;42291:131;:::i;:::-;42283:139;;42010:419;;;:::o;42435:182::-;42575:34;42571:1;42563:6;42559:14;42552:58;42435:182;:::o;42623:366::-;42765:3;42786:67;42850:2;42845:3;42786:67;:::i;:::-;42779:74;;42862:93;42951:3;42862:93;:::i;:::-;42980:2;42975:3;42971:12;42964:19;;42623:366;;;:::o;42995:419::-;43161:4;43199:2;43188:9;43184:18;43176:26;;43248:9;43242:4;43238:20;43234:1;43223:9;43219:17;43212:47;43276:131;43402:4;43276:131;:::i;:::-;43268:139;;42995:419;;;:::o;43420:176::-;43560:28;43556:1;43548:6;43544:14;43537:52;43420:176;:::o;43602:366::-;43744:3;43765:67;43829:2;43824:3;43765:67;:::i;:::-;43758:74;;43841:93;43930:3;43841:93;:::i;:::-;43959:2;43954:3;43950:12;43943:19;;43602:366;;;:::o;43974:419::-;44140:4;44178:2;44167:9;44163:18;44155:26;;44227:9;44221:4;44217:20;44213:1;44202:9;44198:17;44191:47;44255:131;44381:4;44255:131;:::i;:::-;44247:139;;43974:419;;;:::o;44399:180::-;44447:77;44444:1;44437:88;44544:4;44541:1;44534:15;44568:4;44565:1;44558:15;44585:98;44636:6;44670:5;44664:12;44654:22;;44585:98;;;:::o;44689:168::-;44772:11;44806:6;44801:3;44794:19;44846:4;44841:3;44837:14;44822:29;;44689:168;;;;:::o;44863:373::-;44949:3;44977:38;45009:5;44977:38;:::i;:::-;45031:70;45094:6;45089:3;45031:70;:::i;:::-;45024:77;;45110:65;45168:6;45163:3;45156:4;45149:5;45145:16;45110:65;:::i;:::-;45200:29;45222:6;45200:29;:::i;:::-;45195:3;45191:39;45184:46;;44953:283;44863:373;;;;:::o;45242:640::-;45437:4;45475:3;45464:9;45460:19;45452:27;;45489:71;45557:1;45546:9;45542:17;45533:6;45489:71;:::i;:::-;45570:72;45638:2;45627:9;45623:18;45614:6;45570:72;:::i;:::-;45652;45720:2;45709:9;45705:18;45696:6;45652:72;:::i;:::-;45771:9;45765:4;45761:20;45756:2;45745:9;45741:18;45734:48;45799:76;45870:4;45861:6;45799:76;:::i;:::-;45791:84;;45242:640;;;;;;;:::o;45888:141::-;45944:5;45975:6;45969:13;45960:22;;45991:32;46017:5;45991:32;:::i;:::-;45888:141;;;;:::o;46035:349::-;46104:6;46153:2;46141:9;46132:7;46128:23;46124:32;46121:119;;;46159:79;;:::i;:::-;46121:119;46279:1;46304:63;46359:7;46350:6;46339:9;46335:22;46304:63;:::i;:::-;46294:73;;46250:127;46035:349;;;;:::o
Swarm Source
ipfs://88a2040ffbac4cbf7c04cb5e67b8f5bed4d7e46ac6874c233249ab0473778906
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.