More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 216 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Claim Print | 64524964 | 12 days ago | IN | 0 POL | 0.00256449 | ||||
Set Approval For... | 63672173 | 33 days ago | IN | 0 POL | 0.00968877 | ||||
Set Approval For... | 63437264 | 39 days ago | IN | 0 POL | 0.00773279 | ||||
Claim Print | 62990534 | 50 days ago | IN | 0 POL | 0.00208278 | ||||
Claim Print | 62545531 | 61 days ago | IN | 0 POL | 0.00193878 | ||||
Transfer From | 62545472 | 61 days ago | IN | 0 POL | 0.001653 | ||||
Set Approval For... | 60792471 | 105 days ago | IN | 0 POL | 0.00138411 | ||||
Set Approval For... | 60346010 | 116 days ago | IN | 0 POL | 0.00383914 | ||||
Set Approval For... | 60345992 | 116 days ago | IN | 0 POL | 0.004827 | ||||
Set Approval For... | 60345992 | 116 days ago | IN | 0 POL | 0.00374366 | ||||
Set Approval For... | 60345992 | 116 days ago | IN | 0 POL | 0.00497544 | ||||
Set Approval For... | 58787977 | 155 days ago | IN | 0 POL | 0.00147638 | ||||
Claim Print | 58749684 | 156 days ago | IN | 0 POL | 0.00208314 | ||||
Claim Print | 58602559 | 160 days ago | IN | 0 POL | 0.0019395 | ||||
Set Approval For... | 58505947 | 162 days ago | IN | 0 POL | 0.00079942 | ||||
Claim Print | 58179795 | 170 days ago | IN | 0 POL | 0.00193914 | ||||
Claim Print | 57887466 | 178 days ago | IN | 0 POL | 0.00208314 | ||||
Claim Print | 57614711 | 185 days ago | IN | 0 POL | 0.00143823 | ||||
Claim Print | 57599413 | 185 days ago | IN | 0 POL | 0.00157014 | ||||
Claim Print | 57596423 | 185 days ago | IN | 0 POL | 0.00208314 | ||||
Claim Print | 57457639 | 189 days ago | IN | 0 POL | 0.00213147 | ||||
Safe Transfer Fr... | 57451807 | 189 days ago | IN | 0 POL | 0.00188337 | ||||
Safe Transfer Fr... | 57451775 | 189 days ago | IN | 0 POL | 0.0018874 | ||||
Claim Print | 57264921 | 194 days ago | IN | 0 POL | 0.00240699 | ||||
Claim Print | 57264755 | 194 days ago | IN | 0 POL | 0.0040267 |
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
55784127 | 233 days ago | 700 POL |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
TicketsPrintByCM
Compiler Version
v0.8.25+commit.b61c2a91
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.25; // █▀ █▀▀ █▄▄ █▄█ █▀█ █▀█ █▀▀ █▀▄▀█ ▄▀█ ▀▄▀ // ▄█ █▄▄ █▄█ ░█░ █▀▄ █▀▀ █▄█ █░▀░█ █▀█ █░█ import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol"; import "@openzeppelin/contracts/token/common/ERC2981.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; import "@openzeppelin/contracts/utils/Base64.sol"; contract TicketsPrintByCM is ERC721, ERC721Burnable, ERC2981, ReentrancyGuard, Ownable { using Strings for uint256; address _aristoWallet = 0x220639868D2947E8e336A109b7531ed87662b276; uint8 public currentPhase; uint8 public constant MAX_PHASES = 4; // Pré-mint / FM / WL / Public / Sold Out uint16 public maxSupply = 500; uint16[] private _availableTokenIds; bool _isInitDone; uint16 public mintedTicketsPrint = 0; uint16 public claimedPrints; string public baseURI; bool _isURILocked; bool public isClaimOpen; // Mint tracking mapping(uint8 => mintPhase) public mintPhases; mapping(address => mintTracker) _mintTrackers; // Claim tracking mapping(address => AllowedContract) private _allowedcontracts; address[] private _allowedContractAddresses; mapping(address => bool) private _operators; // STRUCTS // Settings for all mint phases struct mintPhase { string name; uint256 price; bytes32 merkleTreeRoot; bool exists; } // Mint tracker for all mint phases struct mintTracker { uint16[5] phaseTracker; } // Structure for allowed smart contracts struct AllowedContract { bool allowed; uint8 maxClaimPerToken; uint24 chainId; mapping(uint256 => uint256) tokenIdsClaimed; } // Same without mapping, used in getAllowedContracts struct PublicAllowedContract { address contractAddress; uint8 maxClaimPerToken; uint24 chainId; } // EVENTS event MetadataUpdate(uint16 tokenId); event BatchMetadataUpdate(uint16 fromTokenId, uint16 toTokenId); event PhaseUpdate(uint8 phaseID); event ClaimPrint( uint16 tokenId, address claimedScAddress, uint16 claimedTokenId ); // MODIFIERS modifier onlyAllowedContract(address scAddress) { require( _allowedcontracts[scAddress].allowed, "Smart contract is not allowed." ); _; } modifier onlyOperator() { require(_operators[msg.sender], "Authorized operator only !"); _; } constructor() ERC721("Tickets Print ByCM", "TICKETSPRINTBYCM") Ownable(msg.sender) { baseURI = "ipfs://bafybeib4jcpqsyovzjp42etmbcgiqb74dyxltghpuudyrb7muofn6s6aai/"; // Default URI _setDefaultRoyalty(_aristoWallet, 500); // Default royalties set to 5.0% _operators[msg.sender] = true; // Deployer is an operator // Set phases mintPhases[1] = mintPhase({ name: "FM", price: 0 ether, merkleTreeRoot: bytes32( 0xe4b07109ce1e52f3757a4368801ad9cf9e1f21bedfee12cc0868731b23f6dca2 ), exists: true }); mintPhases[2] = mintPhase({ name: "WL", price: 1 ether, merkleTreeRoot: bytes32(0x0), exists: true }); mintPhases[3] = mintPhase({ name: "Public", price: 1 ether, merkleTreeRoot: bytes32(0x0), exists: true }); } // [External] Mint for 3 phases function mint( uint16 amount, uint16 maxMints, bytes32[] calldata proof ) external payable nonReentrant { require(msg.sender == tx.origin, "No !"); // Extra security about RNG require(mintedTicketsPrint < maxSupply, "Sold out !"); require( currentPhase >= 1 && currentPhase <= 3, "Wait for mint phase please !" ); require(amount >= 1, "Really ?"); require( mintedTicketsPrint + amount <= maxSupply, "Oh no, supply overrun :/" ); require( msg.value == (mintPhases[currentPhase].price * amount), "Invalid mint price !" ); if (currentPhase >= 1 && currentPhase <= 2) { require( _verify( msg.sender, maxMints, proof, mintPhases[currentPhase].merkleTreeRoot ), "Hey, you aren't on the current phase allowlist :/" ); // Allowlist check require( _mintTrackers[msg.sender].phaseTracker[currentPhase] + amount <= maxMints, "Hey, no more mint allowed for the current phase !" ); // Tracker check } _mintProcess(amount); // Mint trackings _mintTrackers[msg.sender].phaseTracker[currentPhase] += amount; mintedTicketsPrint += amount; // Transfert des fonds (bool sent, bytes memory data) = _aristoWallet.call{value: msg.value}( "" ); require(sent, "Error during transfer"); } // [External] Claim a print for specific SC & token ID then burn the TP token ID function claimPrint( uint16 tokenId, address claimScAddress, uint16 claimTokenId ) external nonReentrant onlyAllowedContract(claimScAddress) { require(isClaimOpen, "Hey, claim isn't open !"); require(_ownerOf(tokenId) != address(0), "Inexistent token"); require(_ownerOf(tokenId) == msg.sender, "No !"); require( _allowedcontracts[claimScAddress].tokenIdsClaimed[claimTokenId] < _allowedcontracts[claimScAddress].maxClaimPerToken, "No more claim allowed for that token" ); _allowedcontracts[claimScAddress].tokenIdsClaimed[claimTokenId]++; _burn(tokenId); claimedPrints++; emit ClaimPrint(tokenId, claimScAddress, claimTokenId); } // [External] Get details of all allowed contracts function getAllowedContracts() external view returns (PublicAllowedContract[] memory) { PublicAllowedContract[] memory allowedContracts = new PublicAllowedContract[]( _allowedContractAddresses.length ); for (uint256 i = 0; i < _allowedContractAddresses.length; i++) { allowedContracts[i].contractAddress = _allowedContractAddresses[i]; allowedContracts[i].maxClaimPerToken = _allowedcontracts[ _allowedContractAddresses[i] ].maxClaimPerToken; allowedContracts[i].chainId = _allowedcontracts[ _allowedContractAddresses[i] ].chainId; } return allowedContracts; } // [External] Get details for a specific phase function getMintPhase(uint8 phaseID) external view returns (mintPhase memory) { require(mintPhases[phaseID].exists, "Invalid phase"); return mintPhases[phaseID]; } // [External] Get mint tracking for a specific phase & wallet function getMintTracker(uint256 phaseID, address wallet) external view returns (uint16) { return _mintTrackers[wallet].phaseTracker[phaseID]; } // [External] Get claim count for specific token ID function getClaimTracker(address scAddress, uint256 tokenId) external view returns (uint256) { return _allowedcontracts[scAddress].tokenIdsClaimed[tokenId]; } // [External] Check if a token has reached or exceeded its maximum claim limit function checkTokenClaimStatus(address scAddress, uint256 tokenId) external view returns (bool) { return _allowedcontracts[scAddress].tokenIdsClaimed[tokenId] == _allowedcontracts[scAddress].maxClaimPerToken; } // [External] All-in-one function ;) function jackOfAllTrades() external view returns ( uint8 phase, uint16 ticketsMinted, uint16 supplyLimit, mintPhase memory currentMintPhase, uint16 callerMintTracker ) { phase = currentPhase; ticketsMinted = mintedTicketsPrint; supplyLimit = maxSupply; currentMintPhase = mintPhases[currentPhase]; callerMintTracker = _mintTrackers[msg.sender].phaseTracker[ currentPhase ]; } // [External] Batch refresh of all NFTs metadata function batchMetadataRefresh() external { emit BatchMetadataUpdate(1, maxSupply); } // [Public] Return the URI of a specific token ID function tokenURI(uint256 tokenId) public view override returns (string memory) { require(_ownerOf(tokenId) != address(0), "Inexistent token"); return string(abi.encodePacked(baseURI, tokenId.toString(), ".json")); } // [Internal] Check if specified wallet address is whitelisted function _verify( address userAddress, uint256 mints, bytes32[] memory proof, bytes32 root ) internal pure returns (bool) { return MerkleProof.verify( proof, root, keccak256(abi.encodePacked(userAddress, mints)) ); } // [Internal] Base mint process for both mints functions function _mintProcess(uint16 amount) internal { for (uint256 i = 0; i < amount; i++) { require(_availableTokenIds.length > 0, "No more tokens available"); uint256 randomIndex = _rand() % _availableTokenIds.length; uint16 tokenId = _availableTokenIds[randomIndex]; // EZPZ removal by simple swapping + pop _availableTokenIds[randomIndex] = _availableTokenIds[ _availableTokenIds.length - 1 ]; _availableTokenIds.pop(); // Mint the token _safeMint(msg.sender, tokenId); emit MetadataUpdate(tokenId); // Compliance } } // [Internal] Randomize function function _rand() internal view returns (uint256) { return uint256( keccak256( abi.encodePacked( block.timestamp, msg.sender, _availableTokenIds.length, block.prevrandao ) ) ); } // [Operator] Change baseURI function setURI(string memory uri) external onlyOperator { require(!_isURILocked, "Hey, URI is locked !"); baseURI = uri; } // [Operator] Toggle claim status function toggleClaimStatus() external onlyOperator { isClaimOpen = !isClaimOpen; } // [Operator] Update mint price for a specified phase function updatemintPhasePrice(uint8 phaseID, uint256 price) external onlyOperator { require(mintPhases[phaseID].exists, "Invalid phase"); mintPhases[phaseID].price = price; } // [Operator] Update mint MTR for a specific phase function updatemintPhaseMerkleTreeRoot( uint8 phaseID, bytes32 merkleTreeRoot ) external onlyOperator { require(mintPhases[phaseID].exists, "Invalid phase"); mintPhases[phaseID].merkleTreeRoot = merkleTreeRoot; } // [Operator] Add an allowed smart contract function addAllowedContract( address scAddress, uint8 maxClaimPerToken, uint24 chainId ) public onlyOperator { require(scAddress != address(0), "Invalid address"); require( !_allowedcontracts[scAddress].allowed, "Contract already added" ); _allowedcontracts[scAddress].allowed = true; _allowedcontracts[scAddress].maxClaimPerToken = maxClaimPerToken; _allowedcontracts[scAddress].chainId = chainId; _allowedContractAddresses.push(scAddress); } // [Operator] Remove an allowed smart contract function removeAllowedContract(address scAddress) public onlyOperator onlyAllowedContract(scAddress) { require(scAddress != address(0), "Invalid address"); _allowedcontracts[scAddress].allowed = false; for (uint256 i = 0; i < _allowedContractAddresses.length; i++) { if (_allowedContractAddresses[i] == scAddress) { _allowedContractAddresses[i] = _allowedContractAddresses[ _allowedContractAddresses.length - 1 ]; _allowedContractAddresses.pop(); break; } } } // [Operator] Add a claimed token for a specific contract, if possible (one claim is added) function addClaimedToken(address scAddress, uint256 tokenId) external onlyOperator onlyAllowedContract(scAddress) { require(scAddress != address(0), "Invalid address"); require( _allowedcontracts[scAddress].tokenIdsClaimed[tokenId] < _allowedcontracts[scAddress].maxClaimPerToken, "No more claim allowed for that token" ); _allowedcontracts[scAddress].tokenIdsClaimed[tokenId]++; } // [Operator] Remove a claimed token for a specific contract (one claim is removed) function removeClaimedToken(address scAddress, uint256 tokenId) external onlyOperator onlyAllowedContract(scAddress) { require(scAddress != address(0), "Invalid address"); require( _allowedcontracts[scAddress].tokenIdsClaimed[tokenId] > 0, "Token not claimed" ); _allowedcontracts[scAddress].tokenIdsClaimed[tokenId]--; } // [Operator] Go to previous phase function previousPhase() external onlyOperator { require(currentPhase > 0, "Can't go back !"); currentPhase--; emit PhaseUpdate(currentPhase); } // [Operator] Go to next phase function nextPhase() external onlyOperator { require(currentPhase < MAX_PHASES, "No more phase !"); currentPhase++; emit PhaseUpdate(currentPhase); } // [Operator] Go to specific phase function updatePhase(uint8 _phaseID) external onlyOperator { require(_phaseID >= 0 && _phaseID <= MAX_PHASES, "Inexistent phase !"); currentPhase = _phaseID; emit PhaseUpdate(currentPhase); } // [Operator] Init the array required for random mint function initAvailableTokenIds() external onlyOperator { require(!_isInitDone, "Hey, init is already done !"); for (uint16 i = 1; i <= maxSupply; i++) { _availableTokenIds.push(i); } _isInitDone = true; // Lock } // [Operator] Team Mint (if required) function teamMint(uint16 amount) external nonReentrant onlyOperator { require(msg.sender == tx.origin, "No !"); // Extra security about RNG require(mintedTicketsPrint < maxSupply, "Sold out !"); _mintProcess(amount); mintedTicketsPrint += amount; } // [Owner] Adds an authorized operator address function addAuthorizedOperator(address operator) external onlyOwner { _operators[operator] = true; } // [Owner] Removes an authorized operator address function removeAuthorizedOperator(address operator) external onlyOwner { _operators[operator] = false; } // [Owner] Burn override function burn(uint256 tokenId) public override onlyOwner { require(_ownerOf(tokenId) != address(0), "Inexistent token"); _burn(tokenId); } // [Owner] Lock the metadata function lockURI() external onlyOwner { require(!_isURILocked, "Hey, URI is already locked !"); _isURILocked = true; } // [Owner] JIC function withdraw() external onlyOwner { payable(msg.sender).transfer(address(this).balance); } // [Owner] Boost supply (JIC) function supplyBoost(uint16 supplyToAdd) external onlyOwner { for (uint16 i = maxSupply + 1; i <= maxSupply + supplyToAdd; i++) { _availableTokenIds.push(i); } maxSupply = maxSupply + supplyToAdd; } // ROYALTIES via ERC-2981 function setDefaultRoyalty(address receiver, uint96 feeNumerator) external onlyOwner { _setDefaultRoyalty(receiver, feeNumerator); } // Required override function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC2981) returns (bool) { return ERC721.supportsInterface(interfaceId) || ERC2981.supportsInterface(interfaceId); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.2) (utils/Base64.sol) pragma solidity ^0.8.20; /** * @dev Provides a set of functions to operate with Base64 strings. */ library Base64 { /** * @dev Base64 Encoding/Decoding Table */ string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /** * @dev Converts a `bytes` to its Bytes64 `string` representation. */ function encode(bytes memory data) internal pure returns (string memory) { /** * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol */ if (data.length == 0) return ""; // Loads the table into memory string memory table = _TABLE; // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter // and split into 4 numbers of 6 bits. // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up // - `data.length + 2` -> Round up // - `/ 3` -> Number of 3-bytes chunks // - `4 *` -> 4 characters for each chunk string memory result = new string(4 * ((data.length + 2) / 3)); /// @solidity memory-safe-assembly assembly { // Prepare the lookup table (skip the first "length" byte) let tablePtr := add(table, 1) // Prepare result pointer, jump over length let resultPtr := add(result, 0x20) let dataPtr := data let endPtr := add(data, mload(data)) // In some cases, the last iteration will read bytes after the end of the data. We cache the value, and // set it to zero to make sure no dirty bytes are read in that section. let afterPtr := add(endPtr, 0x20) let afterCache := mload(afterPtr) mstore(afterPtr, 0x00) // Run over the input, 3 bytes at a time for { } lt(dataPtr, endPtr) { } { // Advance 3 bytes dataPtr := add(dataPtr, 3) let input := mload(dataPtr) // To write each character, shift the 3 byte (24 bits) chunk // 4 times in blocks of 6 bits for each character (18, 12, 6, 0) // and apply logical AND with 0x3F to bitmask the least significant 6 bits. // Use this as an index into the lookup table, mload an entire word // so the desired character is in the least significant byte, and // mstore8 this least significant byte into the result and continue. mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F)))) resultPtr := add(resultPtr, 1) // Advance } // Reset the value that was cached mstore(afterPtr, afterCache) // When data `bytes` is not exactly 3 bytes long // it is padded with `=` characters at the end switch mod(mload(data), 3) case 1 { mstore8(sub(resultPtr, 1), 0x3d) mstore8(sub(resultPtr, 2), 0x3d) } case 2 { mstore8(sub(resultPtr, 1), 0x3d) } } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol) pragma solidity ^0.8.20; import {Math} from "./math/Math.sol"; import {SignedMath} from "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @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), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); } /** * @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) { uint256 localValue = value; bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = HEX_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal * representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.20; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The tree and the proofs can be generated using our * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. * You will find a quickstart guide in the readme. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the Merkle tree could be reinterpreted as a leaf value. * OpenZeppelin's JavaScript library generates Merkle trees that are safe * against this attack out of the box. */ library MerkleProof { /** *@dev The multiproof provided is not valid. */ error MerkleProofInvalidMultiproof(); /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} */ function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the Merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. if (leavesLen + proofLen != totalHashes + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { if (proofPos != proofLen) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the Merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. if (leavesLen + proofLen != totalHashes + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { if (proofPos != proofLen) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Sorts the pair (a, b) and hashes the result. */ function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } /** * @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory. */ function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/common/ERC2981.sol) pragma solidity ^0.8.20; import {IERC2981} from "../../interfaces/IERC2981.sol"; import {IERC165, ERC165} from "../../utils/introspection/ERC165.sol"; /** * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information. * * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first. * * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the * fee is specified in basis points by default. * * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. */ abstract contract ERC2981 is IERC2981, ERC165 { struct RoyaltyInfo { address receiver; uint96 royaltyFraction; } RoyaltyInfo private _defaultRoyaltyInfo; mapping(uint256 tokenId => RoyaltyInfo) private _tokenRoyaltyInfo; /** * @dev The default royalty set is invalid (eg. (numerator / denominator) >= 1). */ error ERC2981InvalidDefaultRoyalty(uint256 numerator, uint256 denominator); /** * @dev The default royalty receiver is invalid. */ error ERC2981InvalidDefaultRoyaltyReceiver(address receiver); /** * @dev The royalty set for an specific `tokenId` is invalid (eg. (numerator / denominator) >= 1). */ error ERC2981InvalidTokenRoyalty(uint256 tokenId, uint256 numerator, uint256 denominator); /** * @dev The royalty receiver for `tokenId` is invalid. */ error ERC2981InvalidTokenRoyaltyReceiver(uint256 tokenId, address receiver); /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId); } /** * @inheritdoc IERC2981 */ function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual returns (address, uint256) { RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId]; if (royalty.receiver == address(0)) { royalty = _defaultRoyaltyInfo; } uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator(); return (royalty.receiver, royaltyAmount); } /** * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an * override. */ function _feeDenominator() internal pure virtual returns (uint96) { return 10000; } /** * @dev Sets the royalty information that all ids in this contract will default to. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual { uint256 denominator = _feeDenominator(); if (feeNumerator > denominator) { // Royalty fee will exceed the sale price revert ERC2981InvalidDefaultRoyalty(feeNumerator, denominator); } if (receiver == address(0)) { revert ERC2981InvalidDefaultRoyaltyReceiver(address(0)); } _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Removes default royalty information. */ function _deleteDefaultRoyalty() internal virtual { delete _defaultRoyaltyInfo; } /** * @dev Sets the royalty information for a specific token id, overriding the global default. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual { uint256 denominator = _feeDenominator(); if (feeNumerator > denominator) { // Royalty fee will exceed the sale price revert ERC2981InvalidTokenRoyalty(tokenId, feeNumerator, denominator); } if (receiver == address(0)) { revert ERC2981InvalidTokenRoyaltyReceiver(tokenId, address(0)); } _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Resets royalty information for the token id back to the global default. */ function _resetTokenRoyalty(uint256 tokenId) internal virtual { delete _tokenRoyaltyInfo[tokenId]; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/ERC721Burnable.sol) pragma solidity ^0.8.20; import {ERC721} from "../ERC721.sol"; import {Context} from "../../../utils/Context.sol"; /** * @title ERC721 Burnable Token * @dev ERC721 Token that can be burned (destroyed). */ abstract contract ERC721Burnable is Context, ERC721 { /** * @dev Burns `tokenId`. See {ERC721-_burn}. * * Requirements: * * - The caller must own `tokenId` or be an approved operator. */ function burn(uint256 tokenId) public virtual { // Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here. _update(address(0), tokenId, _msgSender()); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.20; import {IERC721} from "./IERC721.sol"; import {IERC721Receiver} from "./IERC721Receiver.sol"; import {IERC721Metadata} from "./extensions/IERC721Metadata.sol"; import {Context} from "../../utils/Context.sol"; import {Strings} from "../../utils/Strings.sol"; import {IERC165, ERC165} from "../../utils/introspection/ERC165.sol"; import {IERC721Errors} from "../../interfaces/draft-IERC6093.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ abstract contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Errors { using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; mapping(uint256 tokenId => address) private _owners; mapping(address owner => uint256) private _balances; mapping(uint256 tokenId => address) private _tokenApprovals; mapping(address owner => mapping(address operator => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual returns (uint256) { if (owner == address(0)) { revert ERC721InvalidOwner(address(0)); } return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual returns (address) { return _requireOwned(tokenId); } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual returns (string memory) { _requireOwned(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string.concat(baseURI, tokenId.toString()) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual { _approve(to, tokenId, _msgSender()); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual returns (address) { _requireOwned(tokenId); return _getApproved(tokenId); } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } // Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here. address previousOwner = _update(to, tokenId, _msgSender()); if (previousOwner != from) { revert ERC721IncorrectOwner(from, tokenId, previousOwner); } } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual { transferFrom(from, to, tokenId); _checkOnERC721Received(from, to, tokenId, data); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist * * IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the * core ERC721 logic MUST be matched with the use of {_increaseBalance} to keep balances * consistent with ownership. The invariant to preserve is that for any address `a` the value returned by * `balanceOf(a)` must be equal to the number of tokens such that `_ownerOf(tokenId)` is `a`. */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted. */ function _getApproved(uint256 tokenId) internal view virtual returns (address) { return _tokenApprovals[tokenId]; } /** * @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in * particular (ignoring whether it is owned by `owner`). * * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this * assumption. */ function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) { return spender != address(0) && (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender); } /** * @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner. * Reverts if `spender` does not have approval from the provided `owner` for the given token or for all its assets * the `spender` for the specific `tokenId`. * * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this * assumption. */ function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual { if (!_isAuthorized(owner, spender, tokenId)) { if (owner == address(0)) { revert ERC721NonexistentToken(tokenId); } else { revert ERC721InsufficientApproval(spender, tokenId); } } } /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that * a uint256 would ever overflow from increments when these increments are bounded to uint128 values. * * WARNING: Increasing an account's balance using this function tends to be paired with an override of the * {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership * remain consistent with one another. */ function _increaseBalance(address account, uint128 value) internal virtual { unchecked { _balances[account] += value; } } /** * @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner * (or `to`) is the zero address. Returns the owner of the `tokenId` before the update. * * The `auth` argument is optional. If the value passed is non 0, then this function will check that * `auth` is either the owner of the token, or approved to operate on the token (by the owner). * * Emits a {Transfer} event. * * NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}. */ function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) { address from = _ownerOf(tokenId); // Perform (optional) operator check if (auth != address(0)) { _checkAuthorized(from, auth, tokenId); } // Execute the update if (from != address(0)) { // Clear approval. No need to re-authorize or emit the Approval event _approve(address(0), tokenId, address(0), false); unchecked { _balances[from] -= 1; } } if (to != address(0)) { unchecked { _balances[to] += 1; } } _owners[tokenId] = to; emit Transfer(from, to, tokenId); return from; } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } address previousOwner = _update(to, tokenId, address(0)); if (previousOwner != address(0)) { revert ERC721InvalidSender(address(0)); } } /** * @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual { _mint(to, tokenId); _checkOnERC721Received(address(0), to, tokenId, data); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal { address previousOwner = _update(address(0), tokenId, address(0)); if (previousOwner == address(0)) { revert ERC721NonexistentToken(tokenId); } } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } address previousOwner = _update(to, tokenId, address(0)); if (previousOwner == address(0)) { revert ERC721NonexistentToken(tokenId); } else if (previousOwner != from) { revert ERC721IncorrectOwner(from, tokenId, previousOwner); } } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients * are aware of the ERC721 standard to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is like {safeTransferFrom} in the sense that it invokes * {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `tokenId` token must exist and be owned by `from`. * - `to` cannot be the zero address. * - `from` cannot be the zero address. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId) internal { _safeTransfer(from, to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { _transfer(from, to, tokenId); _checkOnERC721Received(from, to, tokenId, data); } /** * @dev Approve `to` to operate on `tokenId` * * The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is * either the owner of the token, or approved to operate on all tokens held by this owner. * * Emits an {Approval} event. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address to, uint256 tokenId, address auth) internal { _approve(to, tokenId, auth, true); } /** * @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not * emitted in the context of transfers. */ function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual { // Avoid reading the owner unless necessary if (emitEvent || auth != address(0)) { address owner = _requireOwned(tokenId); // We do not use _isAuthorized because single-token approvals should not be able to call approve if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) { revert ERC721InvalidApprover(auth); } if (emitEvent) { emit Approval(owner, to, tokenId); } } _tokenApprovals[tokenId] = to; } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Requirements: * - operator can't be the address zero. * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { if (operator == address(0)) { revert ERC721InvalidOperator(operator); } _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned). * Returns the owner. * * Overrides to ownership logic should be done to {_ownerOf}. */ function _requireOwned(uint256 tokenId) internal view returns (address) { address owner = _ownerOf(tokenId); if (owner == address(0)) { revert ERC721NonexistentToken(tokenId); } return owner; } /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target address. This will revert if the * recipient doesn't accept the token transfer. The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call */ function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory data) private { if (to.code.length > 0) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { if (retval != IERC721Receiver.onERC721Received.selector) { revert ERC721InvalidReceiver(to); } } catch (bytes memory reason) { if (reason.length == 0) { revert ERC721InvalidReceiver(to); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.20; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol) pragma solidity ^0.8.20; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Muldiv operation overflow. */ error MathOverflowedMulDiv(); enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an overflow flag. */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the 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 towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. return a / b; } // (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 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. if (denominator <= prod1) { revert MathOverflowedMulDiv(); } /////////////////////////////////////////////// // 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. uint256 twos = denominator & (0 - denominator); 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 (unsignedRoundsUp(rounding) && 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 * towards zero. * * 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 + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * 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 + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * 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 + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * 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 256, 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 + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.20; import {IERC165} from "../utils/introspection/IERC165.sol"; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. */ interface IERC2981 is IERC165 { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. */ function royaltyInfo( uint256 tokenId, uint256 salePrice ) external view returns (address receiver, uint256 royaltyAmount); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.20; import {IERC721} from "../IERC721.sol"; /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.20; /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.20; import {IERC165} from "../../utils/introspection/IERC165.sol"; /** * @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 address zero. * * 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "remappings": [], "evmVersion": "paris" }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidDefaultRoyalty","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidDefaultRoyaltyReceiver","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidTokenRoyalty","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidTokenRoyaltyReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721IncorrectOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721InsufficientApproval","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC721InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC721InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721InvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC721InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC721InvalidSender","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721NonexistentToken","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","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":false,"internalType":"uint16","name":"fromTokenId","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"toTokenId","type":"uint16"}],"name":"BatchMetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"tokenId","type":"uint16"},{"indexed":false,"internalType":"address","name":"claimedScAddress","type":"address"},{"indexed":false,"internalType":"uint16","name":"claimedTokenId","type":"uint16"}],"name":"ClaimPrint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"tokenId","type":"uint16"}],"name":"MetadataUpdate","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":false,"internalType":"uint8","name":"phaseID","type":"uint8"}],"name":"PhaseUpdate","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":"MAX_PHASES","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"scAddress","type":"address"},{"internalType":"uint8","name":"maxClaimPerToken","type":"uint8"},{"internalType":"uint24","name":"chainId","type":"uint24"}],"name":"addAllowedContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"addAuthorizedOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"scAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"addClaimedToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"batchMetadataRefresh","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"scAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"checkTokenClaimStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"tokenId","type":"uint16"},{"internalType":"address","name":"claimScAddress","type":"address"},{"internalType":"uint16","name":"claimTokenId","type":"uint16"}],"name":"claimPrint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimedPrints","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentPhase","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllowedContracts","outputs":[{"components":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint8","name":"maxClaimPerToken","type":"uint8"},{"internalType":"uint24","name":"chainId","type":"uint24"}],"internalType":"struct TicketsPrintByCM.PublicAllowedContract[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"scAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getClaimTracker","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"phaseID","type":"uint8"}],"name":"getMintPhase","outputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"bytes32","name":"merkleTreeRoot","type":"bytes32"},{"internalType":"bool","name":"exists","type":"bool"}],"internalType":"struct TicketsPrintByCM.mintPhase","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"phaseID","type":"uint256"},{"internalType":"address","name":"wallet","type":"address"}],"name":"getMintTracker","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initAvailableTokenIds","outputs":[],"stateMutability":"nonpayable","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":"isClaimOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"jackOfAllTrades","outputs":[{"internalType":"uint8","name":"phase","type":"uint8"},{"internalType":"uint16","name":"ticketsMinted","type":"uint16"},{"internalType":"uint16","name":"supplyLimit","type":"uint16"},{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"bytes32","name":"merkleTreeRoot","type":"bytes32"},{"internalType":"bool","name":"exists","type":"bool"}],"internalType":"struct TicketsPrintByCM.mintPhase","name":"currentMintPhase","type":"tuple"},{"internalType":"uint16","name":"callerMintTracker","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"amount","type":"uint16"},{"internalType":"uint16","name":"maxMints","type":"uint16"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"mintPhases","outputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"bytes32","name":"merkleTreeRoot","type":"bytes32"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintedTicketsPrint","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextPhase","outputs":[],"stateMutability":"nonpayable","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":"previousPhase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"scAddress","type":"address"}],"name":"removeAllowedContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"removeAuthorizedOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"scAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"removeClaimedToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"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":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"setURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"supplyToAdd","type":"uint16"}],"name":"supplyBoost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"amount","type":"uint16"}],"name":"teamMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleClaimStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_phaseID","type":"uint8"}],"name":"updatePhase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"phaseID","type":"uint8"},{"internalType":"bytes32","name":"merkleTreeRoot","type":"bytes32"}],"name":"updatemintPhaseMerkleTreeRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"phaseID","type":"uint8"},{"internalType":"uint256","name":"price","type":"uint256"}],"name":"updatemintPhasePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052600a8054600162ffff0160a01b0319167601f400220639868d2947e8e336a109b7531ed87662b276179055600c805462ffff001916905534801561004757600080fd5b5033604051806040016040528060128152602001715469636b657473205072696e74204279434d60701b8152506040518060400160405280601081526020016f5449434b4554535052494e544259434d60801b81525081600090816100ac9190610502565b5060016100b98282610502565b50506001600855506001600160a01b0381166100f057604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b6100f98161036c565b506040518060800160405280604381526020016146dc60439139600d906101209082610502565b50600a54610139906001600160a01b03166101f46103be565b336000908152601360209081526040808320805460ff19166001908117909155815160c08101835260026080820190815261464d60f01b60a083015281528084018590527fe4b07109ce1e52f3757a4368801ad9cf9e1f21bedfee12cc0868731b23f6dca29281019290925260608201819052909252600f905280517f169f97de0d9a84d840042b17d3c6b9638b3d6fd9024c9eb0c7a306a17b49f88f9081906101e39082610502565b506020828101516001838101919091556040808501516002808601919091556060958601516003909501805460ff191695151595909517909455805160c081018252608081018581526115d360f21b60a08301528152670de0b6b3a76400008185015260009181018290529485019190915291909152600f905280517fa74ba3945261e09fde15ba3db55005b205e61eeb4ad811ac0faa2b315bffeead90819061028d9082610502565b5060208281015160018381019190915560408085015160028501556060948501516003948501805460ff1916911515919091179055805160c081018252600660808201908152655075626c696360d01b60a08301528152670de0b6b3a76400008185015260009181018290529485019190915291909152600f905280517f45f76dafbbad695564362934e24d72eedc57f9fc1a65f39bca62176cc82968289081906103389082610502565b5060208201516001820155604082015160028201556060909101516003909101805460ff19169115159190911790556105c1565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6127106001600160601b0382168110156103fd57604051636f483d0960e01b81526001600160601b0383166004820152602481018290526044016100e7565b6001600160a01b03831661042757604051635b6cc80560e11b8152600060048201526024016100e7565b50604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600655565b634e487b7160e01b600052604160045260246000fd5b600181811c9082168061048b57607f821691505b6020821081036104ab57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156104fd576000816000526020600020601f850160051c810160208610156104da5750805b601f850160051c820191505b818110156104f9578281556001016104e6565b5050505b505050565b81516001600160401b0381111561051b5761051b610461565b61052f816105298454610477565b846104b1565b602080601f831160018114610564576000841561054c5750858301515b600019600386901b1c1916600185901b1785556104f9565b600085815260208120601f198616915b8281101561059357888601518255948401946001909101908401610574565b50858210156105b15787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61410c806105d06000396000f3fe6080604052600436106103355760003560e01c8063742c1374116101ab578063c3a25fef116100f7578063e3f8a79c11610095578063e985e9c51161006f578063e985e9c5146109f8578063ea44f33014610a18578063f2fde38b14610a38578063fedbc0a214610a5857600080fd5b8063e3f8a79c146109a3578063e55c73bc146109c3578063e88b7737146109e357600080fd5b8063cf3d8e53116100d1578063cf3d8e5314610914578063d0fb050414610934578063d5abeb0114610954578063d6d43cc01461097657600080fd5b8063c3a25fef146108ca578063c690d5ad146108df578063c87b56dd146108f457600080fd5b80639800fc1611610164578063b2169fcd1161013e578063b2169fcd1461081e578063b3fa00381461084e578063b88d4fde14610895578063bf480315146108b557600080fd5b80639800fc16146107be578063a22cb465146107de578063a2ad86e0146107fe57600080fd5b8063742c1374146106e357806381f7f0a1146107035780638da5cb5b146107565780638e021c061461077457806393cfc0741461078957806395d89b41146107a957600080fd5b80633ccfd60b11610285578063538741c5116102235780636352211e116101fd5780636352211e1461066b5780636c0360eb1461068b57806370a08231146106a0578063715018a6146106ce57600080fd5b8063538741c5146106095780635aa3101c1461062b5780635b752ed21461064b57600080fd5b806342842e0e1161025f57806342842e0e1461058e57806342966c68146105ae578063477e3c73146105ce57806349f196bf146105e357600080fd5b80633ccfd60b146105445780633eadb6db14610559578063404d2cf81461056e57600080fd5b8063081812fc116102f257806323b872dd116102cc57806323b872dd1461049157806324fd2652146104b15780632a55205a146104d05780632bea1f5b1461050f57600080fd5b8063081812fc14610426578063089567e81461045e578063095ea7b31461047157600080fd5b806301ffc9a71461033a57806302fe53051461036f57806304634d8d1461039157806304b3e58d146103b1578063055ad42e146103d157806306fdde0314610404575b600080fd5b34801561034657600080fd5b5061035a6103553660046135c0565b610a78565b60405190151581526020015b60405180910390f35b34801561037b57600080fd5b5061038f61038a366004613669565b610a98565b005b34801561039d57600080fd5b5061038f6103ac3660046136ce565b610b2a565b3480156103bd57600080fd5b5061038f6103cc366004613711565b610b3c565b3480156103dd57600080fd5b50600a546103f290600160a01b900460ff1681565b60405160ff9091168152602001610366565b34801561041057600080fd5b50610419610c59565b604051610366919061378b565b34801561043257600080fd5b5061044661044136600461379e565b610ceb565b6040516001600160a01b039091168152602001610366565b61038f61046c3660046137c9565b610d14565b34801561047d57600080fd5b5061038f61048c366004613711565b611262565b34801561049d57600080fd5b5061038f6104ac36600461385a565b61126d565b3480156104bd57600080fd5b50600e5461035a90610100900460ff1681565b3480156104dc57600080fd5b506104f06104eb366004613896565b6112f2565b604080516001600160a01b039093168352602083019190915201610366565b34801561051b57600080fd5b50600c54610531906301000000900461ffff1681565b60405161ffff9091168152602001610366565b34801561055057600080fd5b5061038f61139e565b34801561056557600080fd5b5061038f6113d5565b34801561057a57600080fd5b5061038f6105893660046138b8565b6114cb565b34801561059a57600080fd5b5061038f6105a936600461385a565b6114f7565b3480156105ba57600080fd5b5061038f6105c936600461379e565b611517565b3480156105da57600080fd5b5061038f61155c565b3480156105ef57600080fd5b506105f86115f0565b604051610366959493929190613914565b34801561061557600080fd5b5061061e611767565b6040516103669190613958565b34801561063757600080fd5b5061038f6106463660046139c2565b611941565b34801561065757600080fd5b5061038f610666366004613a05565b611b89565b34801561067757600080fd5b5061044661068636600461379e565b611c80565b34801561069757600080fd5b50610419611c8b565b3480156106ac57600080fd5b506106c06106bb3660046138b8565b611d19565b604051908152602001610366565b3480156106da57600080fd5b5061038f611d61565b3480156106ef57600080fd5b5061038f6106fe366004613711565b611d75565b34801561070f57600080fd5b5061035a61071e366004613711565b6001600160a01b03919091166000908152601160209081526040808320805494845260010190915290205461010090910460ff161490565b34801561076257600080fd5b506009546001600160a01b0316610446565b34801561078057600080fd5b5061038f611e9d565b34801561079557600080fd5b506105316107a4366004613a20565b611f07565b3480156107b557600080fd5b50610419611f52565b3480156107ca57600080fd5b5061038f6107d93660046138b8565b611f61565b3480156107ea57600080fd5b5061038f6107f9366004613a4c565b61210c565b34801561080a57600080fd5b5061038f610819366004613a8e565b612117565b34801561082a57600080fd5b5061083e610839366004613aaa565b612193565b6040516103669493929190613ac5565b34801561085a57600080fd5b506106c0610869366004613711565b6001600160a01b0391909116600090815260116020908152604080832093835260019093019052205490565b3480156108a157600080fd5b5061038f6108b0366004613af6565b612248565b3480156108c157600080fd5b5061038f61225f565b3480156108d657600080fd5b5061038f6122a3565b3480156108eb57600080fd5b5061038f6122ef565b34801561090057600080fd5b5061041961090f36600461379e565b612406565b34801561092057600080fd5b5061038f61092f366004613aaa565b61246f565b34801561094057600080fd5b5061038f61094f366004613b72565b61253e565b34801561096057600080fd5b50600a5461053190600160a81b900461ffff1681565b34801561098257600080fd5b50610996610991366004613aaa565b612689565b6040516103669190613bc1565b3480156109af57600080fd5b5061038f6109be3660046138b8565b6127b9565b3480156109cf57600080fd5b5061038f6109de366004613a05565b6127e2565b3480156109ef57600080fd5b506103f2600481565b348015610a0457600080fd5b5061035a610a13366004613bd4565b6128d3565b348015610a2457600080fd5b50600c5461053190610100900461ffff1681565b348015610a4457600080fd5b5061038f610a533660046138b8565b612901565b348015610a6457600080fd5b5061038f610a73366004613a8e565b61293c565b6000610a83826129b8565b80610a925750610a9282612a08565b92915050565b3360009081526013602052604090205460ff16610ad05760405162461bcd60e51b8152600401610ac790613bfe565b60405180910390fd5b600e5460ff1615610b1a5760405162461bcd60e51b81526020600482015260146024820152734865792c20555249206973206c6f636b6564202160601b6044820152606401610ac7565b600d610b268282613cb9565b5050565b610b32612a2d565b610b268282612a5a565b3360009081526013602052604090205460ff16610b6b5760405162461bcd60e51b8152600401610ac790613bfe565b6001600160a01b038216600090815260116020526040902054829060ff16610ba55760405162461bcd60e51b8152600401610ac790613d79565b6001600160a01b038316610bcb5760405162461bcd60e51b8152600401610ac790613db0565b6001600160a01b0383166000908152601160209081526040808320805486855260019091019092529091205461010090910460ff1611610c1d5760405162461bcd60e51b8152600401610ac790613dd9565b6001600160a01b03831660009081526011602090815260408083208584526001019091528120805491610c4f83613e33565b9190505550505050565b606060008054610c6890613c35565b80601f0160208091040260200160405190810160405280929190818152602001828054610c9490613c35565b8015610ce15780601f10610cb657610100808354040283529160200191610ce1565b820191906000526020600020905b815481529060010190602001808311610cc457829003601f168201915b5050505050905090565b6000610cf682612afd565b506000828152600460205260409020546001600160a01b0316610a92565b610d1c612b36565b333214610d3b5760405162461bcd60e51b8152600401610ac790613e4c565b600a54600c54600160a81b90910461ffff9081166101009092041610610d905760405162461bcd60e51b815260206004820152600a602482015269536f6c64206f7574202160b01b6044820152606401610ac7565b600a546001600160a01b90910460ff1610801590610dbc5750600a546003600160a01b90910460ff1611155b610e085760405162461bcd60e51b815260206004820152601c60248201527f5761697420666f72206d696e7420706861736520706c656173652021000000006044820152606401610ac7565b60018461ffff161015610e485760405162461bcd60e51b81526020600482015260086024820152675265616c6c79203f60c01b6044820152606401610ac7565b600a54600c5461ffff600160a81b909204821691610e6e91879161010090910416613e6a565b61ffff161115610ec05760405162461bcd60e51b815260206004820152601860248201527f4f68206e6f2c20737570706c79206f76657272756e203a2f00000000000000006044820152606401610ac7565b600a54600160a01b900460ff166000908152600f6020526040902060010154610eee9061ffff861690613e8c565b3414610f335760405162461bcd60e51b8152602060048201526014602482015273496e76616c6964206d696e74207072696365202160601b6044820152606401610ac7565b600a546001600160a01b90910460ff1610801590610f5f5750600a546002600160a01b90910460ff1611155b156110ec57610fc2338461ffff168484808060200260200160405190810160405280939291908181526020018383602002808284376000920182905250600a54600160a01b900460ff168152600f60205260409020600201549250612b8f915050565b6110285760405162461bcd60e51b815260206004820152603160248201527f4865792c20796f75206172656e2774206f6e207468652063757272656e7420706044820152706861736520616c6c6f776c697374203a2f60781b6064820152608401610ac7565b336000908152601060205260409020600a5461ffff8516918691600160a01b900460ff166005811061105c5761105c613ea3565b601091828204019190066002029054906101000a900461ffff166110809190613e6a565b61ffff1611156110ec5760405162461bcd60e51b815260206004820152603160248201527f4865792c206e6f206d6f7265206d696e7420616c6c6f77656420666f72207468604482015270652063757272656e74207068617365202160781b6064820152608401610ac7565b6110f584612be4565b336000908152601060205260409020600a54859190600160a01b900460ff166005811061112457611124613ea3565b601091828204019190066002028282829054906101000a900461ffff1661114b9190613e6a565b92506101000a81548161ffff021916908361ffff16021790555083600c60018282829054906101000a900461ffff166111849190613e6a565b92506101000a81548161ffff021916908361ffff160217905550600080600a60009054906101000a90046001600160a01b03166001600160a01b03163460405160006040518083038185875af1925050503d8060008114611201576040519150601f19603f3d011682016040523d82523d6000602084013e611206565b606091505b5091509150816112505760405162461bcd60e51b815260206004820152601560248201527422b93937b910323ab934b733903a3930b739b332b960591b6044820152606401610ac7565b505061125c6001600855565b50505050565b610b26828233612df3565b6001600160a01b03821661129757604051633250574960e11b815260006004820152602401610ac7565b60006112a4838333612e00565b9050836001600160a01b0316816001600160a01b03161461125c576040516364283d7b60e01b81526001600160a01b0380861660048301526024820184905282166044820152606401610ac7565b60008281526007602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b03169282019290925282916113675750604080518082019091526006546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090611386906001600160601b031687613e8c565b6113909190613ecf565b915196919550909350505050565b6113a6612a2d565b60405133904780156108fc02916000818181858888f193505050501580156113d2573d6000803e3d6000fd5b50565b3360009081526013602052604090205460ff166114045760405162461bcd60e51b8152600401610ac790613bfe565b600a546004600160a01b90910460ff16106114535760405162461bcd60e51b815260206004820152600f60248201526e4e6f206d6f7265207068617365202160881b6044820152606401610ac7565b600a8054600160a01b900460ff1690601461146d83613ee3565b82546101009290920a60ff818102199093169183160217909155600a54604051600160a01b90910490911681527f10bc0bd01d0d03ea0d8ad12c1ca751400418c5c6df1233e0342956179371b3b591506020015b60405180910390a1565b6114d3612a2d565b6001600160a01b03166000908152601360205260409020805460ff19166001179055565b61151283838360405180602001604052806000815250612248565b505050565b61151f612a2d565b6000818152600260205260409020546001600160a01b03166115535760405162461bcd60e51b8152600401610ac790613f02565b6113d281612ef9565b3360009081526013602052604090205460ff1661158b5760405162461bcd60e51b8152600401610ac790613bfe565b600a54600160a01b900460ff166115d65760405162461bcd60e51b815260206004820152600f60248201526e43616e277420676f206261636b202160881b6044820152606401610ac7565b600a8054600160a01b900460ff1690601461146d83613f2c565b6040805160808082018352606080835260006020808501829052848601829052918401819052600a54600c54600160a01b820460ff16808452600f90945286832087519586019097528654939661010090910461ffff90811696600160a81b909304169491938290829061166390613c35565b80601f016020809104026020016040519081016040528092919081815260200182805461168f90613c35565b80156116dc5780601f106116b1576101008083540402835291602001916116dc565b820191906000526020600020905b8154815290600101906020018083116116bf57829003601f168201915b50505091835250506001820154602080830191909152600283015460408084019190915260039093015460ff9081161515606090930192909252336000908152601090915291909120600a5492945091600160a01b9004166005811061174457611744613ea3565b601091828204019190066002029054906101000a900461ffff1690509091929394565b60125460609060009067ffffffffffffffff811115611788576117886135dd565b6040519080825280602002602001820160405280156117d357816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816117a65790505b50905060005b60125481101561193b57601281815481106117f6576117f6613ea3565b9060005260206000200160009054906101000a90046001600160a01b031682828151811061182657611826613ea3565b6020026020010151600001906001600160a01b031690816001600160a01b031681525050601160006012838154811061186157611861613ea3565b6000918252602080832091909101546001600160a01b03168352820192909252604001902054825161010090910460ff16908390839081106118a5576118a5613ea3565b60200260200101516020019060ff16908160ff168152505060116000601283815481106118d4576118d4613ea3565b6000918252602080832091909101546001600160a01b0316835282019290925260400190205482516201000090910462ffffff169083908390811061191b5761191b613ea3565b602090810291909101015162ffffff9091166040909101526001016117d9565b50919050565b611949612b36565b6001600160a01b038216600090815260116020526040902054829060ff166119835760405162461bcd60e51b8152600401610ac790613d79565b600e54610100900460ff166119da5760405162461bcd60e51b815260206004820152601760248201527f4865792c20636c61696d2069736e2774206f70656e20210000000000000000006044820152606401610ac7565b61ffff84166000908152600260205260409020546001600160a01b0316611a135760405162461bcd60e51b8152600401610ac790613f02565b33611a3761ffff86166000908152600260205260409020546001600160a01b031690565b6001600160a01b031614611a5d5760405162461bcd60e51b8152600401610ac790613e4c565b6001600160a01b0383166000908152601160209081526040808320805461ffff8716855260019091019092529091205461010090910460ff1611611ab35760405162461bcd60e51b8152600401610ac790613dd9565b6001600160a01b038316600090815260116020908152604080832061ffff861684526001019091528120805491611ae983613e33565b9190505550611afb8461ffff16612ef9565b600c80546301000000900461ffff16906003611b1683613f49565b82546101009290920a61ffff8181021990931691831602179091556040805187831681526001600160a01b0387166020820152918516908201527fc487af9b0d8a4e07855abb211b72cf7af982fb65b1cf91159c53d14488c0d399915060600160405180910390a1506115126001600855565b611b91612b36565b3360009081526013602052604090205460ff16611bc05760405162461bcd60e51b8152600401610ac790613bfe565b333214611bdf5760405162461bcd60e51b8152600401610ac790613e4c565b600a54600c54600160a81b90910461ffff9081166101009092041610611c345760405162461bcd60e51b815260206004820152600a602482015269536f6c64206f7574202160b01b6044820152606401610ac7565b611c3d81612be4565b80600c60018282829054906101000a900461ffff16611c5c9190613e6a565b92506101000a81548161ffff021916908361ffff1602179055506113d26001600855565b6000610a9282612afd565b600d8054611c9890613c35565b80601f0160208091040260200160405190810160405280929190818152602001828054611cc490613c35565b8015611d115780601f10611ce657610100808354040283529160200191611d11565b820191906000526020600020905b815481529060010190602001808311611cf457829003601f168201915b505050505081565b60006001600160a01b038216611d45576040516322718ad960e21b815260006004820152602401610ac7565b506001600160a01b031660009081526003602052604090205490565b611d69612a2d565b611d736000612f34565b565b3360009081526013602052604090205460ff16611da45760405162461bcd60e51b8152600401610ac790613bfe565b6001600160a01b038216600090815260116020526040902054829060ff16611dde5760405162461bcd60e51b8152600401610ac790613d79565b6001600160a01b038316611e045760405162461bcd60e51b8152600401610ac790613db0565b6001600160a01b0383166000908152601160209081526040808320858452600101909152902054611e6b5760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd0818db185a5b5959607a1b6044820152606401610ac7565b6001600160a01b03831660009081526011602090815260408083208584526001019091528120805491610c4f83613f6a565b611ea5612a2d565b600e5460ff1615611ef85760405162461bcd60e51b815260206004820152601c60248201527f4865792c2055524920697320616c7265616479206c6f636b65642021000000006044820152606401610ac7565b600e805460ff19166001179055565b6001600160a01b03811660009081526010602052604081208360058110611f3057611f30613ea3565b601091828204019190066002029054906101000a900461ffff16905092915050565b606060018054610c6890613c35565b3360009081526013602052604090205460ff16611f905760405162461bcd60e51b8152600401610ac790613bfe565b6001600160a01b038116600090815260116020526040902054819060ff16611fca5760405162461bcd60e51b8152600401610ac790613d79565b6001600160a01b038216611ff05760405162461bcd60e51b8152600401610ac790613db0565b6001600160a01b0382166000908152601160205260408120805460ff191690555b60125481101561151257826001600160a01b03166012828154811061203857612038613ea3565b6000918252602090912001546001600160a01b031603612104576012805461206290600190613f81565b8154811061207257612072613ea3565b600091825260209091200154601280546001600160a01b03909216918390811061209e5761209e613ea3565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060128054806120dd576120dd613f94565b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b600101612011565b610b26338383612f86565b3360009081526013602052604090205460ff166121465760405162461bcd60e51b8152600401610ac790613bfe565b60ff8083166000908152600f60205260409020600301541661217a5760405162461bcd60e51b8152600401610ac790613faa565b60ff9091166000908152600f6020526040902060020155565b600f602052600090815260409020805481906121ae90613c35565b80601f01602080910402602001604051908101604052809291908181526020018280546121da90613c35565b80156122275780601f106121fc57610100808354040283529160200191612227565b820191906000526020600020905b81548152906001019060200180831161220a57829003601f168201915b50505050600183015460028401546003909401549293909290915060ff1684565b61225384848461126d565b61125c84848484613025565b600a546040805160018152600160a81b90920461ffff1660208301527fb6db0ec50b3439ba914fe3808b3474f803b068e77847a8cfbe0358453a5d83c191016114c1565b3360009081526013602052604090205460ff166122d25760405162461bcd60e51b8152600401610ac790613bfe565b600e805461ff001981166101009182900460ff1615909102179055565b3360009081526013602052604090205460ff1661231e5760405162461bcd60e51b8152600401610ac790613bfe565b600c5460ff16156123715760405162461bcd60e51b815260206004820152601b60248201527f4865792c20696e697420697320616c726561647920646f6e65202100000000006044820152606401610ac7565b60015b600a5461ffff600160a81b9091048116908216116123f657600b80546001810182556000919091527f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db960108204018054600f9092166002026101000a61ffff8181021990931692841602919091179055806123ee81613f49565b915050612374565b50600c805460ff19166001179055565b6000818152600260205260409020546060906001600160a01b031661243d5760405162461bcd60e51b8152600401610ac790613f02565b600d6124488361314e565b604051602001612459929190613fd1565b6040516020818303038152906040529050919050565b3360009081526013602052604090205460ff1661249e5760405162461bcd60e51b8152600401610ac790613bfe565b600460ff821611156124e75760405162461bcd60e51b8152602060048201526012602482015271496e6578697374656e74207068617365202160701b6044820152606401610ac7565b600a805460ff60a01b1916600160a01b60ff8481168202929092179283905560405192041681527f10bc0bd01d0d03ea0d8ad12c1ca751400418c5c6df1233e0342956179371b3b59060200160405180910390a150565b3360009081526013602052604090205460ff1661256d5760405162461bcd60e51b8152600401610ac790613bfe565b6001600160a01b0383166125935760405162461bcd60e51b8152600401610ac790613db0565b6001600160a01b03831660009081526011602052604090205460ff16156125f55760405162461bcd60e51b815260206004820152601660248201527510dbdb9d1c9858dd08185b1c9958591e48185919195960521b6044820152606401610ac7565b6001600160a01b039092166000818152601160205260408120805462ffffff909516620100000264ffffff00001960ff959095166101000261ffff1990961695909517600190811794909416949094179093556012805492830181559092527fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34440180546001600160a01b0319169091179055565b60408051608081018252606080825260006020830181905292820183905281019190915260ff8083166000908152600f6020526040902060030154166126e15760405162461bcd60e51b8152600401610ac790613faa565b60ff82166000908152600f60205260409081902081516080810190925280548290829061270d90613c35565b80601f016020809104026020016040519081016040528092919081815260200182805461273990613c35565b80156127865780601f1061275b57610100808354040283529160200191612786565b820191906000526020600020905b81548152906001019060200180831161276957829003601f168201915b5050509183525050600182015460208201526002820154604082015260039091015460ff16151560609091015292915050565b6127c1612a2d565b6001600160a01b03166000908152601360205260409020805460ff19169055565b6127ea612a2d565b600a5460009061280690600160a81b900461ffff166001613e6a565b90505b600a54612822908390600160a81b900461ffff16613e6a565b61ffff168161ffff161161289a57600b80546001810182556000919091527f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db960108204018054600f9092166002026101000a61ffff81810219909316928416029190911790558061289281613f49565b915050612809565b50600a546128b4908290600160a81b900461ffff16613e6a565b600a60156101000a81548161ffff021916908361ffff16021790555050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b612909612a2d565b6001600160a01b03811661293357604051631e4fbdf760e01b815260006004820152602401610ac7565b6113d281612f34565b3360009081526013602052604090205460ff1661296b5760405162461bcd60e51b8152600401610ac790613bfe565b60ff8083166000908152600f60205260409020600301541661299f5760405162461bcd60e51b8152600401610ac790613faa565b60ff9091166000908152600f6020526040902060010155565b60006001600160e01b031982166380ac58cd60e01b14806129e957506001600160e01b03198216635b5e139f60e01b145b80610a9257506301ffc9a760e01b6001600160e01b0319831614610a92565b60006001600160e01b0319821663152a902d60e11b1480610a925750610a92826129b8565b6009546001600160a01b03163314611d735760405163118cdaa760e01b8152336004820152602401610ac7565b6127106001600160601b038216811015612a9957604051636f483d0960e01b81526001600160601b038316600482015260248101829052604401610ac7565b6001600160a01b038316612ac357604051635b6cc80560e11b815260006004820152602401610ac7565b50604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600655565b6000818152600260205260408120546001600160a01b031680610a9257604051637e27328960e01b815260048101849052602401610ac7565b600260085403612b885760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ac7565b6002600855565b6040516bffffffffffffffffffffffff19606086901b16602082015260348101849052600090612bdb9084908490605401604051602081830303815290604052805190602001206131e1565b95945050505050565b60005b8161ffff16811015610b2657600b54612c425760405162461bcd60e51b815260206004820152601860248201527f4e6f206d6f726520746f6b656e7320617661696c61626c6500000000000000006044820152606401610ac7565b600b5460408051426020808301919091526bffffffffffffffffffffffff193360601b168284015260548201849052446074808401919091528351808403909101815260949092019092528051910120600091612c9e91614068565b90506000600b8281548110612cb557612cb5613ea3565b90600052602060002090601091828204019190066002029054906101000a900461ffff169050600b6001600b80549050612cef9190613f81565b81548110612cff57612cff613ea3565b90600052602060002090601091828204019190066002029054906101000a900461ffff16600b8381548110612d3657612d36613ea3565b90600052602060002090601091828204019190066002026101000a81548161ffff021916908361ffff160217905550600b805480612d7657612d76613f94565b60019003818190600052602060002090601091828204019190066002026101000a81549061ffff02191690559055612db2338261ffff166131f7565b60405161ffff821681527f6f66a386e4e9ee859979d0f3ed24b43daff5d5ac7f429c1f6b6e5d79140800909060200160405180910390a15050600101612be7565b6115128383836001613211565b6000828152600260205260408120546001600160a01b0390811690831615612e2d57612e2d818486613317565b6001600160a01b03811615612e6b57612e4a600085600080613211565b6001600160a01b038116600090815260036020526040902080546000190190555b6001600160a01b03851615612e9a576001600160a01b0385166000908152600360205260409020805460010190555b60008481526002602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b6000612f086000836000612e00565b90506001600160a01b038116610b2657604051637e27328960e01b815260048101839052602401610ac7565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b038216612fb857604051630b61174360e31b81526001600160a01b0383166004820152602401610ac7565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b1561125c57604051630a85bd0160e11b81526001600160a01b0384169063150b7a029061306790339088908790879060040161407c565b6020604051808303816000875af19250505080156130a2575060408051601f3d908101601f1916820190925261309f918101906140b9565b60015b61310b573d8080156130d0576040519150601f19603f3d011682016040523d82523d6000602084013e6130d5565b606091505b50805160000361310357604051633250574960e11b81526001600160a01b0385166004820152602401610ac7565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b1461314757604051633250574960e11b81526001600160a01b0385166004820152602401610ac7565b5050505050565b6060600061315b8361337b565b600101905060008167ffffffffffffffff81111561317b5761317b6135dd565b6040519080825280601f01601f1916602001820160405280156131a5576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846131af57509392505050565b6000826131ee8584613453565b14949350505050565b610b26828260405180602001604052806000815250613496565b808061322557506001600160a01b03821615155b156132e757600061323584612afd565b90506001600160a01b038316158015906132615750826001600160a01b0316816001600160a01b031614155b8015613274575061327281846128d3565b155b1561329d5760405163a9fbf51f60e01b81526001600160a01b0384166004820152602401610ac7565b81156132e55783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260046020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b6133228383836134ad565b611512576001600160a01b03831661335057604051637e27328960e01b815260048101829052602401610ac7565b60405163177e802f60e01b81526001600160a01b038316600482015260248101829052604401610ac7565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106133ba5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106133e6576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061340457662386f26fc10000830492506010015b6305f5e100831061341c576305f5e100830492506008015b612710831061343057612710830492506004015b60648310613442576064830492506002015b600a8310610a925760010192915050565b600081815b845181101561348e576134848286838151811061347757613477613ea3565b6020026020010151613513565b9150600101613458565b509392505050565b6134a08383613545565b6115126000848484613025565b60006001600160a01b0383161580159061350b5750826001600160a01b0316846001600160a01b031614806134e757506134e784846128d3565b8061350b57506000828152600460205260409020546001600160a01b038481169116145b949350505050565b600081831061352f57600082815260208490526040902061353e565b60008381526020839052604090205b9392505050565b6001600160a01b03821661356f57604051633250574960e11b815260006004820152602401610ac7565b600061357d83836000612e00565b90506001600160a01b03811615611512576040516339e3563760e11b815260006004820152602401610ac7565b6001600160e01b0319811681146113d257600080fd5b6000602082840312156135d257600080fd5b813561353e816135aa565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff8084111561360e5761360e6135dd565b604051601f8501601f19908116603f01168101908282118183101715613636576136366135dd565b8160405280935085815286868601111561364f57600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561367b57600080fd5b813567ffffffffffffffff81111561369257600080fd5b8201601f810184136136a357600080fd5b61350b848235602084016135f3565b80356001600160a01b03811681146136c957600080fd5b919050565b600080604083850312156136e157600080fd5b6136ea836136b2565b915060208301356001600160601b038116811461370657600080fd5b809150509250929050565b6000806040838503121561372457600080fd5b61372d836136b2565b946020939093013593505050565b60005b8381101561375657818101518382015260200161373e565b50506000910152565b6000815180845261377781602086016020860161373b565b601f01601f19169290920160200192915050565b60208152600061353e602083018461375f565b6000602082840312156137b057600080fd5b5035919050565b803561ffff811681146136c957600080fd5b600080600080606085870312156137df57600080fd5b6137e8856137b7565b93506137f6602086016137b7565b9250604085013567ffffffffffffffff8082111561381357600080fd5b818701915087601f83011261382757600080fd5b81358181111561383657600080fd5b8860208260051b850101111561384b57600080fd5b95989497505060200194505050565b60008060006060848603121561386f57600080fd5b613878846136b2565b9250613886602085016136b2565b9150604084013590509250925092565b600080604083850312156138a957600080fd5b50508035926020909101359150565b6000602082840312156138ca57600080fd5b61353e826136b2565b60008151608084526138e8608085018261375f565b905060208301516020850152604083015160408501526060830151151560608501528091505092915050565b60ff86168152600061ffff8087166020840152808616604084015260a0606084015261394360a08401866138d3565b91508084166080840152509695505050505050565b602080825282518282018190526000919060409081850190868401855b828110156139b557815180516001600160a01b031685528681015160ff168786015285015162ffffff168585015260609093019290850190600101613975565b5091979650505050505050565b6000806000606084860312156139d757600080fd5b6139e0846137b7565b92506139ee602085016136b2565b91506139fc604085016137b7565b90509250925092565b600060208284031215613a1757600080fd5b61353e826137b7565b60008060408385031215613a3357600080fd5b82359150613a43602084016136b2565b90509250929050565b60008060408385031215613a5f57600080fd5b613a68836136b2565b91506020830135801515811461370657600080fd5b803560ff811681146136c957600080fd5b60008060408385031215613aa157600080fd5b61372d83613a7d565b600060208284031215613abc57600080fd5b61353e82613a7d565b608081526000613ad8608083018761375f565b60208301959095525060408101929092521515606090910152919050565b60008060008060808587031215613b0c57600080fd5b613b15856136b2565b9350613b23602086016136b2565b925060408501359150606085013567ffffffffffffffff811115613b4657600080fd5b8501601f81018713613b5757600080fd5b613b66878235602084016135f3565b91505092959194509250565b600080600060608486031215613b8757600080fd5b613b90846136b2565b9250613b9e60208501613a7d565b9150604084013562ffffff81168114613bb657600080fd5b809150509250925092565b60208152600061353e60208301846138d3565b60008060408385031215613be757600080fd5b613bf0836136b2565b9150613a43602084016136b2565b6020808252601a908201527f417574686f72697a6564206f70657261746f72206f6e6c792021000000000000604082015260600190565b600181811c90821680613c4957607f821691505b60208210810361193b57634e487b7160e01b600052602260045260246000fd5b601f821115611512576000816000526020600020601f850160051c81016020861015613c925750805b601f850160051c820191505b81811015613cb157828155600101613c9e565b505050505050565b815167ffffffffffffffff811115613cd357613cd36135dd565b613ce781613ce18454613c35565b84613c69565b602080601f831160018114613d1c5760008415613d045750858301515b600019600386901b1c1916600185901b178555613cb1565b600085815260208120601f198616915b82811015613d4b57888601518255948401946001909101908401613d2c565b5085821015613d695787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252601e908201527f536d61727420636f6e7472616374206973206e6f7420616c6c6f7765642e0000604082015260600190565b6020808252600f908201526e496e76616c6964206164647265737360881b604082015260600190565b60208082526024908201527f4e6f206d6f726520636c61696d20616c6c6f77656420666f722074686174207460408201526337b5b2b760e11b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600060018201613e4557613e45613e1d565b5060010190565b6020808252600490820152634e6f202160e01b604082015260600190565b61ffff818116838216019080821115613e8557613e85613e1d565b5092915050565b8082028115828204841417610a9257610a92613e1d565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601260045260246000fd5b600082613ede57613ede613eb9565b500490565b600060ff821660ff8103613ef957613ef9613e1d565b60010192915050565b60208082526010908201526f24b732bc34b9ba32b73a103a37b5b2b760811b604082015260600190565b600060ff821680613f3f57613f3f613e1d565b6000190192915050565b600061ffff808316818103613f6057613f60613e1d565b6001019392505050565b600081613f7957613f79613e1d565b506000190190565b81810381811115610a9257610a92613e1d565b634e487b7160e01b600052603160045260246000fd5b6020808252600d908201526c496e76616c696420706861736560981b604082015260600190565b6000808454613fdf81613c35565b60018281168015613ff7576001811461400c5761403b565b60ff198416875282151583028701945061403b565b8860005260208060002060005b858110156140325781548a820152908401908201614019565b50505082870194505b50505050835161404f81836020880161373b565b64173539b7b760d91b9101908152600501949350505050565b60008261407757614077613eb9565b500690565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906140af9083018461375f565b9695505050505050565b6000602082840312156140cb57600080fd5b815161353e816135aa56fea264697066735822122012c9f0c909fa3b14f0c214bd790fd2d85216f014083b211d450ebd55865ca4f564736f6c63430008190033697066733a2f2f6261667962656962346a63707173796f767a6a70343265746d62636769716237346479786c74676870757564797262376d756f666e3673366161692f
Deployed Bytecode
0x6080604052600436106103355760003560e01c8063742c1374116101ab578063c3a25fef116100f7578063e3f8a79c11610095578063e985e9c51161006f578063e985e9c5146109f8578063ea44f33014610a18578063f2fde38b14610a38578063fedbc0a214610a5857600080fd5b8063e3f8a79c146109a3578063e55c73bc146109c3578063e88b7737146109e357600080fd5b8063cf3d8e53116100d1578063cf3d8e5314610914578063d0fb050414610934578063d5abeb0114610954578063d6d43cc01461097657600080fd5b8063c3a25fef146108ca578063c690d5ad146108df578063c87b56dd146108f457600080fd5b80639800fc1611610164578063b2169fcd1161013e578063b2169fcd1461081e578063b3fa00381461084e578063b88d4fde14610895578063bf480315146108b557600080fd5b80639800fc16146107be578063a22cb465146107de578063a2ad86e0146107fe57600080fd5b8063742c1374146106e357806381f7f0a1146107035780638da5cb5b146107565780638e021c061461077457806393cfc0741461078957806395d89b41146107a957600080fd5b80633ccfd60b11610285578063538741c5116102235780636352211e116101fd5780636352211e1461066b5780636c0360eb1461068b57806370a08231146106a0578063715018a6146106ce57600080fd5b8063538741c5146106095780635aa3101c1461062b5780635b752ed21461064b57600080fd5b806342842e0e1161025f57806342842e0e1461058e57806342966c68146105ae578063477e3c73146105ce57806349f196bf146105e357600080fd5b80633ccfd60b146105445780633eadb6db14610559578063404d2cf81461056e57600080fd5b8063081812fc116102f257806323b872dd116102cc57806323b872dd1461049157806324fd2652146104b15780632a55205a146104d05780632bea1f5b1461050f57600080fd5b8063081812fc14610426578063089567e81461045e578063095ea7b31461047157600080fd5b806301ffc9a71461033a57806302fe53051461036f57806304634d8d1461039157806304b3e58d146103b1578063055ad42e146103d157806306fdde0314610404575b600080fd5b34801561034657600080fd5b5061035a6103553660046135c0565b610a78565b60405190151581526020015b60405180910390f35b34801561037b57600080fd5b5061038f61038a366004613669565b610a98565b005b34801561039d57600080fd5b5061038f6103ac3660046136ce565b610b2a565b3480156103bd57600080fd5b5061038f6103cc366004613711565b610b3c565b3480156103dd57600080fd5b50600a546103f290600160a01b900460ff1681565b60405160ff9091168152602001610366565b34801561041057600080fd5b50610419610c59565b604051610366919061378b565b34801561043257600080fd5b5061044661044136600461379e565b610ceb565b6040516001600160a01b039091168152602001610366565b61038f61046c3660046137c9565b610d14565b34801561047d57600080fd5b5061038f61048c366004613711565b611262565b34801561049d57600080fd5b5061038f6104ac36600461385a565b61126d565b3480156104bd57600080fd5b50600e5461035a90610100900460ff1681565b3480156104dc57600080fd5b506104f06104eb366004613896565b6112f2565b604080516001600160a01b039093168352602083019190915201610366565b34801561051b57600080fd5b50600c54610531906301000000900461ffff1681565b60405161ffff9091168152602001610366565b34801561055057600080fd5b5061038f61139e565b34801561056557600080fd5b5061038f6113d5565b34801561057a57600080fd5b5061038f6105893660046138b8565b6114cb565b34801561059a57600080fd5b5061038f6105a936600461385a565b6114f7565b3480156105ba57600080fd5b5061038f6105c936600461379e565b611517565b3480156105da57600080fd5b5061038f61155c565b3480156105ef57600080fd5b506105f86115f0565b604051610366959493929190613914565b34801561061557600080fd5b5061061e611767565b6040516103669190613958565b34801561063757600080fd5b5061038f6106463660046139c2565b611941565b34801561065757600080fd5b5061038f610666366004613a05565b611b89565b34801561067757600080fd5b5061044661068636600461379e565b611c80565b34801561069757600080fd5b50610419611c8b565b3480156106ac57600080fd5b506106c06106bb3660046138b8565b611d19565b604051908152602001610366565b3480156106da57600080fd5b5061038f611d61565b3480156106ef57600080fd5b5061038f6106fe366004613711565b611d75565b34801561070f57600080fd5b5061035a61071e366004613711565b6001600160a01b03919091166000908152601160209081526040808320805494845260010190915290205461010090910460ff161490565b34801561076257600080fd5b506009546001600160a01b0316610446565b34801561078057600080fd5b5061038f611e9d565b34801561079557600080fd5b506105316107a4366004613a20565b611f07565b3480156107b557600080fd5b50610419611f52565b3480156107ca57600080fd5b5061038f6107d93660046138b8565b611f61565b3480156107ea57600080fd5b5061038f6107f9366004613a4c565b61210c565b34801561080a57600080fd5b5061038f610819366004613a8e565b612117565b34801561082a57600080fd5b5061083e610839366004613aaa565b612193565b6040516103669493929190613ac5565b34801561085a57600080fd5b506106c0610869366004613711565b6001600160a01b0391909116600090815260116020908152604080832093835260019093019052205490565b3480156108a157600080fd5b5061038f6108b0366004613af6565b612248565b3480156108c157600080fd5b5061038f61225f565b3480156108d657600080fd5b5061038f6122a3565b3480156108eb57600080fd5b5061038f6122ef565b34801561090057600080fd5b5061041961090f36600461379e565b612406565b34801561092057600080fd5b5061038f61092f366004613aaa565b61246f565b34801561094057600080fd5b5061038f61094f366004613b72565b61253e565b34801561096057600080fd5b50600a5461053190600160a81b900461ffff1681565b34801561098257600080fd5b50610996610991366004613aaa565b612689565b6040516103669190613bc1565b3480156109af57600080fd5b5061038f6109be3660046138b8565b6127b9565b3480156109cf57600080fd5b5061038f6109de366004613a05565b6127e2565b3480156109ef57600080fd5b506103f2600481565b348015610a0457600080fd5b5061035a610a13366004613bd4565b6128d3565b348015610a2457600080fd5b50600c5461053190610100900461ffff1681565b348015610a4457600080fd5b5061038f610a533660046138b8565b612901565b348015610a6457600080fd5b5061038f610a73366004613a8e565b61293c565b6000610a83826129b8565b80610a925750610a9282612a08565b92915050565b3360009081526013602052604090205460ff16610ad05760405162461bcd60e51b8152600401610ac790613bfe565b60405180910390fd5b600e5460ff1615610b1a5760405162461bcd60e51b81526020600482015260146024820152734865792c20555249206973206c6f636b6564202160601b6044820152606401610ac7565b600d610b268282613cb9565b5050565b610b32612a2d565b610b268282612a5a565b3360009081526013602052604090205460ff16610b6b5760405162461bcd60e51b8152600401610ac790613bfe565b6001600160a01b038216600090815260116020526040902054829060ff16610ba55760405162461bcd60e51b8152600401610ac790613d79565b6001600160a01b038316610bcb5760405162461bcd60e51b8152600401610ac790613db0565b6001600160a01b0383166000908152601160209081526040808320805486855260019091019092529091205461010090910460ff1611610c1d5760405162461bcd60e51b8152600401610ac790613dd9565b6001600160a01b03831660009081526011602090815260408083208584526001019091528120805491610c4f83613e33565b9190505550505050565b606060008054610c6890613c35565b80601f0160208091040260200160405190810160405280929190818152602001828054610c9490613c35565b8015610ce15780601f10610cb657610100808354040283529160200191610ce1565b820191906000526020600020905b815481529060010190602001808311610cc457829003601f168201915b5050505050905090565b6000610cf682612afd565b506000828152600460205260409020546001600160a01b0316610a92565b610d1c612b36565b333214610d3b5760405162461bcd60e51b8152600401610ac790613e4c565b600a54600c54600160a81b90910461ffff9081166101009092041610610d905760405162461bcd60e51b815260206004820152600a602482015269536f6c64206f7574202160b01b6044820152606401610ac7565b600a546001600160a01b90910460ff1610801590610dbc5750600a546003600160a01b90910460ff1611155b610e085760405162461bcd60e51b815260206004820152601c60248201527f5761697420666f72206d696e7420706861736520706c656173652021000000006044820152606401610ac7565b60018461ffff161015610e485760405162461bcd60e51b81526020600482015260086024820152675265616c6c79203f60c01b6044820152606401610ac7565b600a54600c5461ffff600160a81b909204821691610e6e91879161010090910416613e6a565b61ffff161115610ec05760405162461bcd60e51b815260206004820152601860248201527f4f68206e6f2c20737570706c79206f76657272756e203a2f00000000000000006044820152606401610ac7565b600a54600160a01b900460ff166000908152600f6020526040902060010154610eee9061ffff861690613e8c565b3414610f335760405162461bcd60e51b8152602060048201526014602482015273496e76616c6964206d696e74207072696365202160601b6044820152606401610ac7565b600a546001600160a01b90910460ff1610801590610f5f5750600a546002600160a01b90910460ff1611155b156110ec57610fc2338461ffff168484808060200260200160405190810160405280939291908181526020018383602002808284376000920182905250600a54600160a01b900460ff168152600f60205260409020600201549250612b8f915050565b6110285760405162461bcd60e51b815260206004820152603160248201527f4865792c20796f75206172656e2774206f6e207468652063757272656e7420706044820152706861736520616c6c6f776c697374203a2f60781b6064820152608401610ac7565b336000908152601060205260409020600a5461ffff8516918691600160a01b900460ff166005811061105c5761105c613ea3565b601091828204019190066002029054906101000a900461ffff166110809190613e6a565b61ffff1611156110ec5760405162461bcd60e51b815260206004820152603160248201527f4865792c206e6f206d6f7265206d696e7420616c6c6f77656420666f72207468604482015270652063757272656e74207068617365202160781b6064820152608401610ac7565b6110f584612be4565b336000908152601060205260409020600a54859190600160a01b900460ff166005811061112457611124613ea3565b601091828204019190066002028282829054906101000a900461ffff1661114b9190613e6a565b92506101000a81548161ffff021916908361ffff16021790555083600c60018282829054906101000a900461ffff166111849190613e6a565b92506101000a81548161ffff021916908361ffff160217905550600080600a60009054906101000a90046001600160a01b03166001600160a01b03163460405160006040518083038185875af1925050503d8060008114611201576040519150601f19603f3d011682016040523d82523d6000602084013e611206565b606091505b5091509150816112505760405162461bcd60e51b815260206004820152601560248201527422b93937b910323ab934b733903a3930b739b332b960591b6044820152606401610ac7565b505061125c6001600855565b50505050565b610b26828233612df3565b6001600160a01b03821661129757604051633250574960e11b815260006004820152602401610ac7565b60006112a4838333612e00565b9050836001600160a01b0316816001600160a01b03161461125c576040516364283d7b60e01b81526001600160a01b0380861660048301526024820184905282166044820152606401610ac7565b60008281526007602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b03169282019290925282916113675750604080518082019091526006546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090611386906001600160601b031687613e8c565b6113909190613ecf565b915196919550909350505050565b6113a6612a2d565b60405133904780156108fc02916000818181858888f193505050501580156113d2573d6000803e3d6000fd5b50565b3360009081526013602052604090205460ff166114045760405162461bcd60e51b8152600401610ac790613bfe565b600a546004600160a01b90910460ff16106114535760405162461bcd60e51b815260206004820152600f60248201526e4e6f206d6f7265207068617365202160881b6044820152606401610ac7565b600a8054600160a01b900460ff1690601461146d83613ee3565b82546101009290920a60ff818102199093169183160217909155600a54604051600160a01b90910490911681527f10bc0bd01d0d03ea0d8ad12c1ca751400418c5c6df1233e0342956179371b3b591506020015b60405180910390a1565b6114d3612a2d565b6001600160a01b03166000908152601360205260409020805460ff19166001179055565b61151283838360405180602001604052806000815250612248565b505050565b61151f612a2d565b6000818152600260205260409020546001600160a01b03166115535760405162461bcd60e51b8152600401610ac790613f02565b6113d281612ef9565b3360009081526013602052604090205460ff1661158b5760405162461bcd60e51b8152600401610ac790613bfe565b600a54600160a01b900460ff166115d65760405162461bcd60e51b815260206004820152600f60248201526e43616e277420676f206261636b202160881b6044820152606401610ac7565b600a8054600160a01b900460ff1690601461146d83613f2c565b6040805160808082018352606080835260006020808501829052848601829052918401819052600a54600c54600160a01b820460ff16808452600f90945286832087519586019097528654939661010090910461ffff90811696600160a81b909304169491938290829061166390613c35565b80601f016020809104026020016040519081016040528092919081815260200182805461168f90613c35565b80156116dc5780601f106116b1576101008083540402835291602001916116dc565b820191906000526020600020905b8154815290600101906020018083116116bf57829003601f168201915b50505091835250506001820154602080830191909152600283015460408084019190915260039093015460ff9081161515606090930192909252336000908152601090915291909120600a5492945091600160a01b9004166005811061174457611744613ea3565b601091828204019190066002029054906101000a900461ffff1690509091929394565b60125460609060009067ffffffffffffffff811115611788576117886135dd565b6040519080825280602002602001820160405280156117d357816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816117a65790505b50905060005b60125481101561193b57601281815481106117f6576117f6613ea3565b9060005260206000200160009054906101000a90046001600160a01b031682828151811061182657611826613ea3565b6020026020010151600001906001600160a01b031690816001600160a01b031681525050601160006012838154811061186157611861613ea3565b6000918252602080832091909101546001600160a01b03168352820192909252604001902054825161010090910460ff16908390839081106118a5576118a5613ea3565b60200260200101516020019060ff16908160ff168152505060116000601283815481106118d4576118d4613ea3565b6000918252602080832091909101546001600160a01b0316835282019290925260400190205482516201000090910462ffffff169083908390811061191b5761191b613ea3565b602090810291909101015162ffffff9091166040909101526001016117d9565b50919050565b611949612b36565b6001600160a01b038216600090815260116020526040902054829060ff166119835760405162461bcd60e51b8152600401610ac790613d79565b600e54610100900460ff166119da5760405162461bcd60e51b815260206004820152601760248201527f4865792c20636c61696d2069736e2774206f70656e20210000000000000000006044820152606401610ac7565b61ffff84166000908152600260205260409020546001600160a01b0316611a135760405162461bcd60e51b8152600401610ac790613f02565b33611a3761ffff86166000908152600260205260409020546001600160a01b031690565b6001600160a01b031614611a5d5760405162461bcd60e51b8152600401610ac790613e4c565b6001600160a01b0383166000908152601160209081526040808320805461ffff8716855260019091019092529091205461010090910460ff1611611ab35760405162461bcd60e51b8152600401610ac790613dd9565b6001600160a01b038316600090815260116020908152604080832061ffff861684526001019091528120805491611ae983613e33565b9190505550611afb8461ffff16612ef9565b600c80546301000000900461ffff16906003611b1683613f49565b82546101009290920a61ffff8181021990931691831602179091556040805187831681526001600160a01b0387166020820152918516908201527fc487af9b0d8a4e07855abb211b72cf7af982fb65b1cf91159c53d14488c0d399915060600160405180910390a1506115126001600855565b611b91612b36565b3360009081526013602052604090205460ff16611bc05760405162461bcd60e51b8152600401610ac790613bfe565b333214611bdf5760405162461bcd60e51b8152600401610ac790613e4c565b600a54600c54600160a81b90910461ffff9081166101009092041610611c345760405162461bcd60e51b815260206004820152600a602482015269536f6c64206f7574202160b01b6044820152606401610ac7565b611c3d81612be4565b80600c60018282829054906101000a900461ffff16611c5c9190613e6a565b92506101000a81548161ffff021916908361ffff1602179055506113d26001600855565b6000610a9282612afd565b600d8054611c9890613c35565b80601f0160208091040260200160405190810160405280929190818152602001828054611cc490613c35565b8015611d115780601f10611ce657610100808354040283529160200191611d11565b820191906000526020600020905b815481529060010190602001808311611cf457829003601f168201915b505050505081565b60006001600160a01b038216611d45576040516322718ad960e21b815260006004820152602401610ac7565b506001600160a01b031660009081526003602052604090205490565b611d69612a2d565b611d736000612f34565b565b3360009081526013602052604090205460ff16611da45760405162461bcd60e51b8152600401610ac790613bfe565b6001600160a01b038216600090815260116020526040902054829060ff16611dde5760405162461bcd60e51b8152600401610ac790613d79565b6001600160a01b038316611e045760405162461bcd60e51b8152600401610ac790613db0565b6001600160a01b0383166000908152601160209081526040808320858452600101909152902054611e6b5760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd0818db185a5b5959607a1b6044820152606401610ac7565b6001600160a01b03831660009081526011602090815260408083208584526001019091528120805491610c4f83613f6a565b611ea5612a2d565b600e5460ff1615611ef85760405162461bcd60e51b815260206004820152601c60248201527f4865792c2055524920697320616c7265616479206c6f636b65642021000000006044820152606401610ac7565b600e805460ff19166001179055565b6001600160a01b03811660009081526010602052604081208360058110611f3057611f30613ea3565b601091828204019190066002029054906101000a900461ffff16905092915050565b606060018054610c6890613c35565b3360009081526013602052604090205460ff16611f905760405162461bcd60e51b8152600401610ac790613bfe565b6001600160a01b038116600090815260116020526040902054819060ff16611fca5760405162461bcd60e51b8152600401610ac790613d79565b6001600160a01b038216611ff05760405162461bcd60e51b8152600401610ac790613db0565b6001600160a01b0382166000908152601160205260408120805460ff191690555b60125481101561151257826001600160a01b03166012828154811061203857612038613ea3565b6000918252602090912001546001600160a01b031603612104576012805461206290600190613f81565b8154811061207257612072613ea3565b600091825260209091200154601280546001600160a01b03909216918390811061209e5761209e613ea3565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060128054806120dd576120dd613f94565b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b600101612011565b610b26338383612f86565b3360009081526013602052604090205460ff166121465760405162461bcd60e51b8152600401610ac790613bfe565b60ff8083166000908152600f60205260409020600301541661217a5760405162461bcd60e51b8152600401610ac790613faa565b60ff9091166000908152600f6020526040902060020155565b600f602052600090815260409020805481906121ae90613c35565b80601f01602080910402602001604051908101604052809291908181526020018280546121da90613c35565b80156122275780601f106121fc57610100808354040283529160200191612227565b820191906000526020600020905b81548152906001019060200180831161220a57829003601f168201915b50505050600183015460028401546003909401549293909290915060ff1684565b61225384848461126d565b61125c84848484613025565b600a546040805160018152600160a81b90920461ffff1660208301527fb6db0ec50b3439ba914fe3808b3474f803b068e77847a8cfbe0358453a5d83c191016114c1565b3360009081526013602052604090205460ff166122d25760405162461bcd60e51b8152600401610ac790613bfe565b600e805461ff001981166101009182900460ff1615909102179055565b3360009081526013602052604090205460ff1661231e5760405162461bcd60e51b8152600401610ac790613bfe565b600c5460ff16156123715760405162461bcd60e51b815260206004820152601b60248201527f4865792c20696e697420697320616c726561647920646f6e65202100000000006044820152606401610ac7565b60015b600a5461ffff600160a81b9091048116908216116123f657600b80546001810182556000919091527f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db960108204018054600f9092166002026101000a61ffff8181021990931692841602919091179055806123ee81613f49565b915050612374565b50600c805460ff19166001179055565b6000818152600260205260409020546060906001600160a01b031661243d5760405162461bcd60e51b8152600401610ac790613f02565b600d6124488361314e565b604051602001612459929190613fd1565b6040516020818303038152906040529050919050565b3360009081526013602052604090205460ff1661249e5760405162461bcd60e51b8152600401610ac790613bfe565b600460ff821611156124e75760405162461bcd60e51b8152602060048201526012602482015271496e6578697374656e74207068617365202160701b6044820152606401610ac7565b600a805460ff60a01b1916600160a01b60ff8481168202929092179283905560405192041681527f10bc0bd01d0d03ea0d8ad12c1ca751400418c5c6df1233e0342956179371b3b59060200160405180910390a150565b3360009081526013602052604090205460ff1661256d5760405162461bcd60e51b8152600401610ac790613bfe565b6001600160a01b0383166125935760405162461bcd60e51b8152600401610ac790613db0565b6001600160a01b03831660009081526011602052604090205460ff16156125f55760405162461bcd60e51b815260206004820152601660248201527510dbdb9d1c9858dd08185b1c9958591e48185919195960521b6044820152606401610ac7565b6001600160a01b039092166000818152601160205260408120805462ffffff909516620100000264ffffff00001960ff959095166101000261ffff1990961695909517600190811794909416949094179093556012805492830181559092527fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34440180546001600160a01b0319169091179055565b60408051608081018252606080825260006020830181905292820183905281019190915260ff8083166000908152600f6020526040902060030154166126e15760405162461bcd60e51b8152600401610ac790613faa565b60ff82166000908152600f60205260409081902081516080810190925280548290829061270d90613c35565b80601f016020809104026020016040519081016040528092919081815260200182805461273990613c35565b80156127865780601f1061275b57610100808354040283529160200191612786565b820191906000526020600020905b81548152906001019060200180831161276957829003601f168201915b5050509183525050600182015460208201526002820154604082015260039091015460ff16151560609091015292915050565b6127c1612a2d565b6001600160a01b03166000908152601360205260409020805460ff19169055565b6127ea612a2d565b600a5460009061280690600160a81b900461ffff166001613e6a565b90505b600a54612822908390600160a81b900461ffff16613e6a565b61ffff168161ffff161161289a57600b80546001810182556000919091527f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db960108204018054600f9092166002026101000a61ffff81810219909316928416029190911790558061289281613f49565b915050612809565b50600a546128b4908290600160a81b900461ffff16613e6a565b600a60156101000a81548161ffff021916908361ffff16021790555050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b612909612a2d565b6001600160a01b03811661293357604051631e4fbdf760e01b815260006004820152602401610ac7565b6113d281612f34565b3360009081526013602052604090205460ff1661296b5760405162461bcd60e51b8152600401610ac790613bfe565b60ff8083166000908152600f60205260409020600301541661299f5760405162461bcd60e51b8152600401610ac790613faa565b60ff9091166000908152600f6020526040902060010155565b60006001600160e01b031982166380ac58cd60e01b14806129e957506001600160e01b03198216635b5e139f60e01b145b80610a9257506301ffc9a760e01b6001600160e01b0319831614610a92565b60006001600160e01b0319821663152a902d60e11b1480610a925750610a92826129b8565b6009546001600160a01b03163314611d735760405163118cdaa760e01b8152336004820152602401610ac7565b6127106001600160601b038216811015612a9957604051636f483d0960e01b81526001600160601b038316600482015260248101829052604401610ac7565b6001600160a01b038316612ac357604051635b6cc80560e11b815260006004820152602401610ac7565b50604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600655565b6000818152600260205260408120546001600160a01b031680610a9257604051637e27328960e01b815260048101849052602401610ac7565b600260085403612b885760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ac7565b6002600855565b6040516bffffffffffffffffffffffff19606086901b16602082015260348101849052600090612bdb9084908490605401604051602081830303815290604052805190602001206131e1565b95945050505050565b60005b8161ffff16811015610b2657600b54612c425760405162461bcd60e51b815260206004820152601860248201527f4e6f206d6f726520746f6b656e7320617661696c61626c6500000000000000006044820152606401610ac7565b600b5460408051426020808301919091526bffffffffffffffffffffffff193360601b168284015260548201849052446074808401919091528351808403909101815260949092019092528051910120600091612c9e91614068565b90506000600b8281548110612cb557612cb5613ea3565b90600052602060002090601091828204019190066002029054906101000a900461ffff169050600b6001600b80549050612cef9190613f81565b81548110612cff57612cff613ea3565b90600052602060002090601091828204019190066002029054906101000a900461ffff16600b8381548110612d3657612d36613ea3565b90600052602060002090601091828204019190066002026101000a81548161ffff021916908361ffff160217905550600b805480612d7657612d76613f94565b60019003818190600052602060002090601091828204019190066002026101000a81549061ffff02191690559055612db2338261ffff166131f7565b60405161ffff821681527f6f66a386e4e9ee859979d0f3ed24b43daff5d5ac7f429c1f6b6e5d79140800909060200160405180910390a15050600101612be7565b6115128383836001613211565b6000828152600260205260408120546001600160a01b0390811690831615612e2d57612e2d818486613317565b6001600160a01b03811615612e6b57612e4a600085600080613211565b6001600160a01b038116600090815260036020526040902080546000190190555b6001600160a01b03851615612e9a576001600160a01b0385166000908152600360205260409020805460010190555b60008481526002602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b6000612f086000836000612e00565b90506001600160a01b038116610b2657604051637e27328960e01b815260048101839052602401610ac7565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b038216612fb857604051630b61174360e31b81526001600160a01b0383166004820152602401610ac7565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b1561125c57604051630a85bd0160e11b81526001600160a01b0384169063150b7a029061306790339088908790879060040161407c565b6020604051808303816000875af19250505080156130a2575060408051601f3d908101601f1916820190925261309f918101906140b9565b60015b61310b573d8080156130d0576040519150601f19603f3d011682016040523d82523d6000602084013e6130d5565b606091505b50805160000361310357604051633250574960e11b81526001600160a01b0385166004820152602401610ac7565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b1461314757604051633250574960e11b81526001600160a01b0385166004820152602401610ac7565b5050505050565b6060600061315b8361337b565b600101905060008167ffffffffffffffff81111561317b5761317b6135dd565b6040519080825280601f01601f1916602001820160405280156131a5576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846131af57509392505050565b6000826131ee8584613453565b14949350505050565b610b26828260405180602001604052806000815250613496565b808061322557506001600160a01b03821615155b156132e757600061323584612afd565b90506001600160a01b038316158015906132615750826001600160a01b0316816001600160a01b031614155b8015613274575061327281846128d3565b155b1561329d5760405163a9fbf51f60e01b81526001600160a01b0384166004820152602401610ac7565b81156132e55783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260046020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b6133228383836134ad565b611512576001600160a01b03831661335057604051637e27328960e01b815260048101829052602401610ac7565b60405163177e802f60e01b81526001600160a01b038316600482015260248101829052604401610ac7565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106133ba5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106133e6576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061340457662386f26fc10000830492506010015b6305f5e100831061341c576305f5e100830492506008015b612710831061343057612710830492506004015b60648310613442576064830492506002015b600a8310610a925760010192915050565b600081815b845181101561348e576134848286838151811061347757613477613ea3565b6020026020010151613513565b9150600101613458565b509392505050565b6134a08383613545565b6115126000848484613025565b60006001600160a01b0383161580159061350b5750826001600160a01b0316846001600160a01b031614806134e757506134e784846128d3565b8061350b57506000828152600460205260409020546001600160a01b038481169116145b949350505050565b600081831061352f57600082815260208490526040902061353e565b60008381526020839052604090205b9392505050565b6001600160a01b03821661356f57604051633250574960e11b815260006004820152602401610ac7565b600061357d83836000612e00565b90506001600160a01b03811615611512576040516339e3563760e11b815260006004820152602401610ac7565b6001600160e01b0319811681146113d257600080fd5b6000602082840312156135d257600080fd5b813561353e816135aa565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff8084111561360e5761360e6135dd565b604051601f8501601f19908116603f01168101908282118183101715613636576136366135dd565b8160405280935085815286868601111561364f57600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561367b57600080fd5b813567ffffffffffffffff81111561369257600080fd5b8201601f810184136136a357600080fd5b61350b848235602084016135f3565b80356001600160a01b03811681146136c957600080fd5b919050565b600080604083850312156136e157600080fd5b6136ea836136b2565b915060208301356001600160601b038116811461370657600080fd5b809150509250929050565b6000806040838503121561372457600080fd5b61372d836136b2565b946020939093013593505050565b60005b8381101561375657818101518382015260200161373e565b50506000910152565b6000815180845261377781602086016020860161373b565b601f01601f19169290920160200192915050565b60208152600061353e602083018461375f565b6000602082840312156137b057600080fd5b5035919050565b803561ffff811681146136c957600080fd5b600080600080606085870312156137df57600080fd5b6137e8856137b7565b93506137f6602086016137b7565b9250604085013567ffffffffffffffff8082111561381357600080fd5b818701915087601f83011261382757600080fd5b81358181111561383657600080fd5b8860208260051b850101111561384b57600080fd5b95989497505060200194505050565b60008060006060848603121561386f57600080fd5b613878846136b2565b9250613886602085016136b2565b9150604084013590509250925092565b600080604083850312156138a957600080fd5b50508035926020909101359150565b6000602082840312156138ca57600080fd5b61353e826136b2565b60008151608084526138e8608085018261375f565b905060208301516020850152604083015160408501526060830151151560608501528091505092915050565b60ff86168152600061ffff8087166020840152808616604084015260a0606084015261394360a08401866138d3565b91508084166080840152509695505050505050565b602080825282518282018190526000919060409081850190868401855b828110156139b557815180516001600160a01b031685528681015160ff168786015285015162ffffff168585015260609093019290850190600101613975565b5091979650505050505050565b6000806000606084860312156139d757600080fd5b6139e0846137b7565b92506139ee602085016136b2565b91506139fc604085016137b7565b90509250925092565b600060208284031215613a1757600080fd5b61353e826137b7565b60008060408385031215613a3357600080fd5b82359150613a43602084016136b2565b90509250929050565b60008060408385031215613a5f57600080fd5b613a68836136b2565b91506020830135801515811461370657600080fd5b803560ff811681146136c957600080fd5b60008060408385031215613aa157600080fd5b61372d83613a7d565b600060208284031215613abc57600080fd5b61353e82613a7d565b608081526000613ad8608083018761375f565b60208301959095525060408101929092521515606090910152919050565b60008060008060808587031215613b0c57600080fd5b613b15856136b2565b9350613b23602086016136b2565b925060408501359150606085013567ffffffffffffffff811115613b4657600080fd5b8501601f81018713613b5757600080fd5b613b66878235602084016135f3565b91505092959194509250565b600080600060608486031215613b8757600080fd5b613b90846136b2565b9250613b9e60208501613a7d565b9150604084013562ffffff81168114613bb657600080fd5b809150509250925092565b60208152600061353e60208301846138d3565b60008060408385031215613be757600080fd5b613bf0836136b2565b9150613a43602084016136b2565b6020808252601a908201527f417574686f72697a6564206f70657261746f72206f6e6c792021000000000000604082015260600190565b600181811c90821680613c4957607f821691505b60208210810361193b57634e487b7160e01b600052602260045260246000fd5b601f821115611512576000816000526020600020601f850160051c81016020861015613c925750805b601f850160051c820191505b81811015613cb157828155600101613c9e565b505050505050565b815167ffffffffffffffff811115613cd357613cd36135dd565b613ce781613ce18454613c35565b84613c69565b602080601f831160018114613d1c5760008415613d045750858301515b600019600386901b1c1916600185901b178555613cb1565b600085815260208120601f198616915b82811015613d4b57888601518255948401946001909101908401613d2c565b5085821015613d695787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252601e908201527f536d61727420636f6e7472616374206973206e6f7420616c6c6f7765642e0000604082015260600190565b6020808252600f908201526e496e76616c6964206164647265737360881b604082015260600190565b60208082526024908201527f4e6f206d6f726520636c61696d20616c6c6f77656420666f722074686174207460408201526337b5b2b760e11b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600060018201613e4557613e45613e1d565b5060010190565b6020808252600490820152634e6f202160e01b604082015260600190565b61ffff818116838216019080821115613e8557613e85613e1d565b5092915050565b8082028115828204841417610a9257610a92613e1d565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601260045260246000fd5b600082613ede57613ede613eb9565b500490565b600060ff821660ff8103613ef957613ef9613e1d565b60010192915050565b60208082526010908201526f24b732bc34b9ba32b73a103a37b5b2b760811b604082015260600190565b600060ff821680613f3f57613f3f613e1d565b6000190192915050565b600061ffff808316818103613f6057613f60613e1d565b6001019392505050565b600081613f7957613f79613e1d565b506000190190565b81810381811115610a9257610a92613e1d565b634e487b7160e01b600052603160045260246000fd5b6020808252600d908201526c496e76616c696420706861736560981b604082015260600190565b6000808454613fdf81613c35565b60018281168015613ff7576001811461400c5761403b565b60ff198416875282151583028701945061403b565b8860005260208060002060005b858110156140325781548a820152908401908201614019565b50505082870194505b50505050835161404f81836020880161373b565b64173539b7b760d91b9101908152600501949350505050565b60008261407757614077613eb9565b500690565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906140af9083018461375f565b9695505050505050565b6000602082840312156140cb57600080fd5b815161353e816135aa56fea264697066735822122012c9f0c909fa3b14f0c214bd790fd2d85216f014083b211d450ebd55865ca4f564736f6c63430008190033
Deployed Bytecode Sourcemap
806:16645:18:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17170:279;;;;;;;;;;-1:-1:-1;17170:279:18;;;;;:::i;:::-;;:::i;:::-;;;565:14:19;;558:22;540:41;;528:2;513:18;17170:279:18;;;;;;;;11196:143;;;;;;;;;;-1:-1:-1;11196:143:18;;;;;:::i;:::-;;:::i;:::-;;16975:164;;;;;;;;;;-1:-1:-1;16975:164:18;;;;;:::i;:::-;;:::i;13467:486::-;;;;;;;;;;-1:-1:-1;13467:486:18;;;;;:::i;:::-;;:::i;1024:25::-;;;;;;;;;;-1:-1:-1;1024:25:18;;;;-1:-1:-1;;;1024:25:18;;;;;;;;;2797:4:19;2785:17;;;2767:36;;2755:2;2740:18;1024:25:18;2625:184:19;2365:89:4;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;3497:154::-;;;;;;;;;;-1:-1:-1;3497:154:4;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;3919:32:19;;;3901:51;;3889:2;3874:18;3497:154:4;3755:203:19;4023:1662:18;;;;;;:::i;:::-;;:::i;3323:113:4:-;;;;;;;;;;-1:-1:-1;3323:113:4;;;;;:::i;:::-;;:::i;4143:578::-;;;;;;;;;;-1:-1:-1;4143:578:4;;;;;:::i;:::-;;:::i;1365:23:18:-;;;;;;;;;;-1:-1:-1;1365:23:18;;;;;;;;;;;2379:419:9;;;;;;;;;;-1:-1:-1;2379:419:9;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;5669:32:19;;;5651:51;;5733:2;5718:18;;5711:34;;;;5624:18;2379:419:9;5477:274:19;1281:27:18;;;;;;;;;;-1:-1:-1;1281:27:18;;;;;;;;;;;;;;5930:6:19;5918:19;;;5900:38;;5888:2;5873:18;1281:27:18;5756:188:19;16553:107:18;;;;;;;;;;;;;:::i;14715:177::-;;;;;;;;;;;;;:::i;15870:112::-;;;;;;;;;;-1:-1:-1;15870:112:18;;;;;:::i;:::-;;:::i;4787:132:4:-;;;;;;;;;;-1:-1:-1;4787:132:4;;;;;:::i;:::-;;:::i;16193:158:18:-;;;;;;;;;;-1:-1:-1;16193:158:18;;;;;:::i;:::-;;:::i;14502:172::-;;;;;;;;;;;;;:::i;8561:535::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;:::i;6612:756::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;5776:775::-;;;;;;;;;;-1:-1:-1;5776:775:18;;;;;:::i;:::-;;:::i;15529:284::-;;;;;;;;;;-1:-1:-1;15529:284:18;;;;;:::i;:::-;;:::i;2185:118:4:-;;;;;;;;;;-1:-1:-1;2185:118:4;;;;;:::i;:::-;;:::i;1315:21:18:-;;;;;;;;;;;;;:::i;1920:208:4:-;;;;;;;;;;-1:-1:-1;1920:208:4;;;;;:::i;:::-;;:::i;:::-;;;8758:25:19;;;8746:2;8731:18;1920:208:4;8612:177:19;2293:101:0;;;;;;;;;;;;;:::i;14047:410:18:-;;;;;;;;;;-1:-1:-1;14047:410:18;;;;;:::i;:::-;;:::i;8240:274::-;;;;;;;;;;-1:-1:-1;8240:274:18;;;;;:::i;:::-;-1:-1:-1;;;;;8462:28:18;;;;8354:4;8462:28;;;:17;:28;;;;;;;;:45;;8393:53;;;8462:45;8393:44;:53;;;;;;8462:45;;;;;;8393:114;;8240:274;1638:85:0;;;;;;;;;;-1:-1:-1;1710:6:0;;-1:-1:-1;;;;;1710:6:0;1638:85;;16390:138:18;;;;;;;;;;;;;:::i;7708:183::-;;;;;;;;;;-1:-1:-1;7708:183:18;;;;;:::i;:::-;;:::i;2518:93:4:-;;;;;;;;;;;;;:::i;12734:631:18:-;;;;;;;;;;-1:-1:-1;12734:631:18;;;;;:::i;:::-;;:::i;3718:144:4:-;;;;;;;;;;-1:-1:-1;3718:144:4;;;;;:::i;:::-;;:::i;11816:252:18:-;;;;;;;;;;-1:-1:-1;11816:252:18;;;;;:::i;:::-;;:::i;1416:45::-;;;;;;;;;;-1:-1:-1;1416:45:18;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;7953:198::-;;;;;;;;;;-1:-1:-1;7953:198:18;;;;;:::i;:::-;-1:-1:-1;;;;;8091:28:18;;;;8061:7;8091:28;;;:17;:28;;;;;;;;:53;;;:44;;;;:53;;;;;7953:198;4985:208:4;;;;;;;;;;-1:-1:-1;4985:208:4;;;;;:::i;:::-;;:::i;9155:96:18:-;;;;;;;;;;;;;:::i;11383:94::-;;;;;;;;;;;;;:::i;15220:261::-;;;;;;;;;;;;;:::i;9311:272::-;;;;;;;;;;-1:-1:-1;9311:272:18;;;;;:::i;:::-;;:::i;14937:219::-;;;;;;;;;;-1:-1:-1;14937:219:18;;;;;:::i;:::-;;:::i;12122:555::-;;;;;;;;;;-1:-1:-1;12122:555:18;;;;;:::i;:::-;;:::i;1141:29::-;;;;;;;;;;-1:-1:-1;1141:29:18;;;;-1:-1:-1;;;1141:29:18;;;;;;7425:211;;;;;;;;;;-1:-1:-1;7425:211:18;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;16042:116::-;;;;;;;;;;-1:-1:-1;16042:116:18;;;;;:::i;:::-;;:::i;16700:239::-;;;;;;;;;;-1:-1:-1;16700:239:18;;;;;:::i;:::-;;:::i;1055:36::-;;;;;;;;;;;;1090:1;1055:36;;3928:153:4;;;;;;;;;;-1:-1:-1;3928:153:4;;;;;:::i;:::-;;:::i;1239:36:18:-;;;;;;;;;;-1:-1:-1;1239:36:18;;;;;;;;;;;2543:215:0;;;;;;;;;;-1:-1:-1;2543:215:0;;;;;:::i;:::-;;:::i;11541:214:18:-;;;;;;;;;;-1:-1:-1;11541:214:18;;;;;:::i;:::-;;:::i;17170:279::-;17312:4;17351:37;17376:11;17351:24;:37::i;:::-;:91;;;;17404:38;17430:11;17404:25;:38::i;:::-;17332:110;17170:279;-1:-1:-1;;17170:279:18:o;11196:143::-;2934:10;2923:22;;;;:10;:22;;;;;;;;2915:61;;;;-1:-1:-1;;;2915:61:18;;;;;;;:::i;:::-;;;;;;;;;11272:12:::1;::::0;::::1;;11271:13;11263:46;;;::::0;-1:-1:-1;;;11263:46:18;;12899:2:19;11263:46:18::1;::::0;::::1;12881:21:19::0;12938:2;12918:18;;;12911:30;-1:-1:-1;;;12957:18:19;;;12950:50;13017:18;;11263:46:18::1;12697:344:19::0;11263:46:18::1;11319:7;:13;11329:3:::0;11319:7;:13:::1;:::i;:::-;;11196:143:::0;:::o;16975:164::-;1531:13:0;:11;:13::i;:::-;17090:42:18::1;17109:8;17119:12;17090:18;:42::i;13467:486::-:0;2934:10;2923:22;;;;:10;:22;;;;;;;;2915:61;;;;-1:-1:-1;;;2915:61:18;;;;;;;:::i;:::-;-1:-1:-1;;;;;2766:28:18;::::1;;::::0;;;:17:::1;:28;::::0;;;;:36;13594:9;;2766:36:::1;;2745:113;;;;-1:-1:-1::0;;;2745:113:18::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;13627:23:18;::::2;13619:51;;;;-1:-1:-1::0;;;13619:51:18::2;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;13773:28:18;::::2;;::::0;;;:17:::2;:28;::::0;;;;;;;:45;;13701:53;;;13773:45:::2;13701:44:::0;;::::2;:53:::0;;;;;;;13773:45:::2;::::0;;::::2;;;-1:-1:-1::0;13680:200:18::2;;;;-1:-1:-1::0;;;13680:200:18::2;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;13891:28:18;::::2;;::::0;;;:17:::2;:28;::::0;;;;;;;:53;;;:44:::2;;:53:::0;;;;;:55;;;::::2;::::0;::::2;:::i;:::-;;;;;;2986:1:::1;13467:486:::0;;:::o;2365:89:4:-;2410:13;2442:5;2435:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2365:89;:::o;3497:154::-;3564:7;3583:22;3597:7;3583:13;:22::i;:::-;-1:-1:-1;6008:7:4;6034:24;;;:15;:24;;;;;;-1:-1:-1;;;;;6034:24:4;3623:21;5938:127;4023:1662:18;2261:21:3;:19;:21::i;:::-;4173:10:18::1;4187:9;4173:23;4165:40;;;;-1:-1:-1::0;;;4165:40:18::1;;;;;;;:::i;:::-;4272:9;::::0;4251:18:::1;::::0;-1:-1:-1;;;4272:9:18;;::::1;;::::0;;::::1;;4251:18:::0;;::::1;;:30;4243:53;;;::::0;-1:-1:-1;;;4243:53:18;;17540:2:19;4243:53:18::1;::::0;::::1;17522:21:19::0;17579:2;17559:18;;;17552:30;-1:-1:-1;;;17598:18:19;;;17591:40;17648:18;;4243:53:18::1;17338:334:19::0;4243:53:18::1;4327:12;::::0;4343:1:::1;-1:-1:-1::0;;;4327:12:18;;::::1;;;:17;::::0;::::1;::::0;:38:::1;;-1:-1:-1::0;4348:12:18::1;::::0;4364:1:::1;-1:-1:-1::0;;;4348:12:18;;::::1;;;:17;;4327:38;4306:113;;;::::0;-1:-1:-1;;;4306:113:18;;17879:2:19;4306:113:18::1;::::0;::::1;17861:21:19::0;17918:2;17898:18;;;17891:30;17957;17937:18;;;17930:58;18005:18;;4306:113:18::1;17677:352:19::0;4306:113:18::1;4447:1;4437:6;:11;;;;4429:32;;;::::0;-1:-1:-1;;;4429:32:18;;18236:2:19;4429:32:18::1;::::0;::::1;18218:21:19::0;18275:1;18255:18;;;18248:29;-1:-1:-1;;;18293:18:19;;;18286:38;18341:18;;4429:32:18::1;18034:331:19::0;4429:32:18::1;4523:9;::::0;4492:18:::1;::::0;4523:9:::1;-1:-1:-1::0;;;4523:9:18;;::::1;::::0;::::1;::::0;4492:27:::1;::::0;4513:6;;4523:9:::1;4492:18:::0;;::::1;;:27;:::i;:::-;:40;;;;4471:111;;;::::0;-1:-1:-1;;;4471:111:18;;18745:2:19;4471:111:18::1;::::0;::::1;18727:21:19::0;18784:2;18764:18;;;18757:30;18823:26;18803:18;;;18796:54;18867:18;;4471:111:18::1;18543:348:19::0;4471:111:18::1;4638:12;::::0;-1:-1:-1;;;4638:12:18;::::1;;;4627:24;::::0;;;:10:::1;:24;::::0;;;;:30:::1;;::::0;:39:::1;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;4613:9;:54;4592:121;;;::::0;-1:-1:-1;;;4592:121:18;;19271:2:19;4592:121:18::1;::::0;::::1;19253:21:19::0;19310:2;19290:18;;;19283:30;-1:-1:-1;;;19329:18:19;;;19322:50;19389:18;;4592:121:18::1;19069:344:19::0;4592:121:18::1;4727:12;::::0;4743:1:::1;-1:-1:-1::0;;;4727:12:18;;::::1;;;:17;::::0;::::1;::::0;:38:::1;;-1:-1:-1::0;4748:12:18::1;::::0;4764:1:::1;-1:-1:-1::0;;;4748:12:18;;::::1;;;:17;;4727:38;4723:603;;;4806:175;4835:10;4867:8;4806:175;;4897:5;;4806:175;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;-1:-1:-1;4935:12:18::1;::::0;-1:-1:-1;;;4935:12:18;::::1;;;4924:24:::0;;:10:::1;:24;::::0;;;;:39:::1;;::::0;;-1:-1:-1;4806:7:18::1;::::0;-1:-1:-1;;4806:175:18:i:1;:::-;4781:283;;;::::0;-1:-1:-1;;;4781:283:18;;19620:2:19;4781:283:18::1;::::0;::::1;19602:21:19::0;19659:2;19639:18;;;19632:30;19698:34;19678:18;;;19671:62;-1:-1:-1;;;19749:18:19;;;19742:47;19806:19;;4781:283:18::1;19418:413:19::0;4781:283:18::1;5136:10;5122:25;::::0;;;:13:::1;:25;::::0;;;;5161:12:::1;::::0;5122:93:::1;::::0;::::1;::::0;5177:6;;-1:-1:-1;;;5161:12:18;::::1;;;5122:52;::::0;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;:61;;;;:::i;:::-;:93;;;;5097:201;;;::::0;-1:-1:-1;;;5097:201:18;;20170:2:19;5097:201:18::1;::::0;::::1;20152:21:19::0;20209:2;20189:18;;;20182:30;20248:34;20228:18;;;20221:62;-1:-1:-1;;;20299:18:19;;;20292:47;20356:19;;5097:201:18::1;19968:413:19::0;5097:201:18::1;5336:20;5349:6;5336:12;:20::i;:::-;5407:10;5393:25;::::0;;;:13:::1;:25;::::0;;;;5432:12:::1;::::0;5449:6;;5393:25;-1:-1:-1;;;5432:12:18;::::1;;;5393:52;::::0;::::1;;;;;:::i;:::-;;;;;;;;;;;;:62;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;5487:6;5465:18;;:28;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;5536:9;5547:17:::0;5568:13:::1;;;;;;;;;-1:-1:-1::0;;;;;5568:13:18::1;-1:-1:-1::0;;;;;5568:18:18::1;5594:9;5568:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5535:95;;;;5648:4;5640:38;;;::::0;-1:-1:-1;;;5640:38:18;;20798:2:19;5640:38:18::1;::::0;::::1;20780:21:19::0;20837:2;20817:18;;;20810:30;-1:-1:-1;;;20856:18:19;;;20849:51;20917:18;;5640:38:18::1;20596:345:19::0;5640:38:18::1;4155:1530;;2303:20:3::0;1716:1;2809:7;:22;2629:209;2303:20;4023:1662:18;;;;:::o;3323:113:4:-;3394:35;3403:2;3407:7;735:10:11;3394:8:4;:35::i;4143:578::-;-1:-1:-1;;;;;4237:16:4;;4233:87;;4276:33;;-1:-1:-1;;;4276:33:4;;4306:1;4276:33;;;3901:51:19;3874:18;;4276:33:4;3755:203:19;4233:87:4;4538:21;4562:34;4570:2;4574:7;735:10:11;4562:7:4;:34::i;:::-;4538:58;;4627:4;-1:-1:-1;;;;;4610:21:4;:13;-1:-1:-1;;;;;4610:21:4;;4606:109;;4654:50;;-1:-1:-1;;;4654:50:4;;-1:-1:-1;;;;;21204:15:19;;;4654:50:4;;;21186:34:19;21236:18;;;21229:34;;;21299:15;;21279:18;;;21272:43;21121:18;;4654:50:4;20946:375:19;2379:419:9;2465:7;2522:26;;;:17;:26;;;;;;;;2493:55;;;;;;;;;-1:-1:-1;;;;;2493:55:9;;;;;-1:-1:-1;;;2493:55:9;;;-1:-1:-1;;;;;2493:55:9;;;;;;;;2465:7;;2559:90;;-1:-1:-1;2609:29:9;;;;;;;;;2619:19;2609:29;-1:-1:-1;;;;;2609:29:9;;;;-1:-1:-1;;;2609:29:9;;-1:-1:-1;;;;;2609:29:9;;;;;2559:90;2696:23;;;;2659:21;;3156:5;;2684:35;;-1:-1:-1;;;;;2684:35:9;:9;:35;:::i;:::-;2683:57;;;;:::i;:::-;2759:16;;;;;-1:-1:-1;2379:419:9;;-1:-1:-1;;;;2379:419:9:o;16553:107:18:-;1531:13:0;:11;:13::i;:::-;16602:51:18::1;::::0;16610:10:::1;::::0;16631:21:::1;16602:51:::0;::::1;;;::::0;::::1;::::0;;;16631:21;16610:10;16602:51;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;16553:107::o:0;14715:177::-;2934:10;2923:22;;;;:10;:22;;;;;;;;2915:61;;;;-1:-1:-1;;;2915:61:18;;;;;;;:::i;:::-;14776:12:::1;::::0;1090:1:::1;-1:-1:-1::0;;;14776:12:18;;::::1;:25;:12;:25;14768:53;;;::::0;-1:-1:-1;;;14768:53:18;;21785:2:19;14768:53:18::1;::::0;::::1;21767:21:19::0;21824:2;21804:18;;;21797:30;-1:-1:-1;;;21843:18:19;;;21836:45;21898:18;;14768:53:18::1;21583:339:19::0;14768:53:18::1;14831:12;:14:::0;;-1:-1:-1;;;14831:14:18;::::1;;;::::0;:12:::1;:14;::::0;::::1;:::i;:::-;::::0;;::::1;::::0;;;::::1;;::::0;;::::1;;::::0;;::::1;::::0;;::::1;;;::::0;;;14872:12:::1;::::0;14860:25:::1;::::0;-1:-1:-1;;;14872:12:18;;::::1;::::0;;::::1;2767:36:19::0;;14860:25:18::1;::::0;-1:-1:-1;2755:2:19;2740:18;14860:25:18::1;;;;;;;;14715:177::o:0;15870:112::-;1531:13:0;:11;:13::i;:::-;-1:-1:-1;;;;;15948:20:18::1;;::::0;;;:10:::1;:20;::::0;;;;:27;;-1:-1:-1;;15948:27:18::1;15971:4;15948:27;::::0;;15870:112::o;4787:132:4:-;4873:39;4890:4;4896:2;4900:7;4873:39;;;;;;;;;;;;:16;:39::i;:::-;4787:132;;;:::o;16193:158:18:-;1531:13:0;:11;:13::i;:::-;16297:1:18::1;5799:16:4::0;;;:7;:16;;;;;;-1:-1:-1;;;;;5799:16:4;16260:60:18::1;;;;-1:-1:-1::0;;;16260:60:18::1;;;;;;;:::i;:::-;16330:14;16336:7;16330:5;:14::i;14502:172::-:0;2934:10;2923:22;;;;:10;:22;;;;;;;;2915:61;;;;-1:-1:-1;;;2915:61:18;;;;;;;:::i;:::-;14567:12:::1;::::0;-1:-1:-1;;;14567:12:18;::::1;;;14559:44;;;::::0;-1:-1:-1;;;14559:44:18;;22654:2:19;14559:44:18::1;::::0;::::1;22636:21:19::0;22693:2;22673:18;;;22666:30;-1:-1:-1;;;22712:18:19;;;22705:45;22767:18;;14559:44:18::1;22452:339:19::0;14559:44:18::1;14613:12;:14:::0;;-1:-1:-1;;;14613:14:18;::::1;;;::::0;:12:::1;:14;::::0;::::1;:::i;8561:535::-:0;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8843:12:18;;8881:18;;-1:-1:-1;;;8843:12:18;;;;8961:24;;;:10;:24;;;;;;8942:43;;;;;;;;;;8843:12;;;8881:18;;;;;;;;-1:-1:-1;;;8923:9:18;;;;;-1:-1:-1;;8942:43:18;;8961:24;;8942:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;8942:43:18;;;-1:-1:-1;;8942:43:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9029:10;-1:-1:-1;9015:25:18;;;:13;:25;;;;;;;9067:12;;8942:43;;-1:-1:-1;9015:25:18;-1:-1:-1;;;9067:12:18;;;9015:74;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;8995:94;;8561:535;;;;;:::o;6612:756::-;6843:25;:32;6690:30;;6736:59;;6798:91;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;6798:91:18;;-1:-1:-1;;6798:91:18;;;;;;;;;;;;6736:153;;6904:9;6899:430;6923:25;:32;6919:36;;6899:430;;;7014:25;7040:1;7014:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;7014:28:18;6976:16;6993:1;6976:19;;;;;;;;:::i;:::-;;;;;;;:35;;:66;-1:-1:-1;;;;;6976:66:18;;;-1:-1:-1;;;;;6976:66:18;;;;;7095:17;:77;7130:25;7156:1;7130:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;7130:28:18;7095:77;;;;;;;;;;;;:94;7056:19;;7130:28;7095:94;;;;;;7056:19;;7073:1;;7056:19;;;;;;:::i;:::-;;;;;;;:36;;:133;;;;;;;;;;;7233:17;:77;7268:25;7294:1;7268:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;7268:28:18;7233:77;;;;;;;;;;;;:85;7203:19;;7233:85;;;;;;;7203:19;;7220:1;;7203:19;;;;;;:::i;:::-;;;;;;;;;;;:115;;;;:27;;;;:115;6957:3;;6899:430;;;-1:-1:-1;7345:16:18;6612:756;-1:-1:-1;6612:756:18:o;5776:775::-;2261:21:3;:19;:21::i;:::-;-1:-1:-1;;;;;2766:28:18;::::1;;::::0;;;:17:::1;:28;::::0;;;;:36;5929:14;;2766:36:::1;;2745:113;;;;-1:-1:-1::0;;;2745:113:18::1;;;;;;;:::i;:::-;5963:11:::2;::::0;::::2;::::0;::::2;;;5955:47;;;::::0;-1:-1:-1;;;5955:47:18;;23181:2:19;5955:47:18::2;::::0;::::2;23163:21:19::0;23220:2;23200:18;;;23193:30;23259:25;23239:18;;;23232:53;23302:18;;5955:47:18::2;22979:347:19::0;5955:47:18::2;6020:17;::::0;::::2;6049:1;5799:16:4::0;;;:7;:16;;;;;;-1:-1:-1;;;;;5799:16:4;6012:60:18::2;;;;-1:-1:-1::0;;;6012:60:18::2;;;;;;;:::i;:::-;6111:10;6090:17;;::::0;::::2;5773:7:4::0;5799:16;;;:7;:16;;;;;;-1:-1:-1;;;;;5799:16:4;;5707:115;6090:17:18::2;-1:-1:-1::0;;;;;6090:31:18::2;;6082:48;;;;-1:-1:-1::0;;;6082:48:18::2;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;6243:33:18;::::2;;::::0;;;:17:::2;:33;::::0;;;;;;;:50;;6161:63:::2;::::0;::::2;::::0;;6243:50:::2;6161:49:::0;;::::2;:63:::0;;;;;;;6243:50:::2;::::0;;::::2;;;-1:-1:-1::0;6140:215:18::2;;;;-1:-1:-1::0;;;6140:215:18::2;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;6366:33:18;::::2;;::::0;;;:17:::2;:33;::::0;;;;;;;:63:::2;::::0;::::2;::::0;;:49:::2;;:63:::0;;;;;:65;;;::::2;::::0;::::2;:::i;:::-;;;;;;6441:14;6447:7;6441:14;;:5;:14::i;:::-;6465:13;:15:::0;;;;::::2;;;::::0;:13:::2;:15;::::0;::::2;:::i;:::-;::::0;;::::2;::::0;;;::::2;;::::0;;::::2;;::::0;;::::2;::::0;;::::2;;;::::0;;;6495:49:::2;::::0;;23774:15:19;;;23756:34;;-1:-1:-1;;;;;23826:32:19;;23821:2;23806:18;;23799:60;23895:15;;;23875:18;;;23868:43;6495:49:18::2;::::0;-1:-1:-1;23719:2:19;23704:18;6495:49:18::2;;;;;;;2292:1:3::1;2303:20:::0;1716:1;2809:7;:22;2629:209;15529:284:18;2261:21:3;:19;:21::i;:::-;2934:10:18::1;2923:22;::::0;;;:10:::1;:22;::::0;;;;;::::1;;2915:61;;;;-1:-1:-1::0;;;2915:61:18::1;;;;;;;:::i;:::-;15615:10:::2;15629:9;15615:23;15607:40;;;;-1:-1:-1::0;;;15607:40:18::2;;;;;;;:::i;:::-;15714:9;::::0;15693:18:::2;::::0;-1:-1:-1;;;15714:9:18;;::::2;;::::0;;::::2;;15693:18:::0;;::::2;;:30;15685:53;;;::::0;-1:-1:-1;;;15685:53:18;;17540:2:19;15685:53:18::2;::::0;::::2;17522:21:19::0;17579:2;17559:18;;;17552:30;-1:-1:-1;;;17598:18:19;;;17591:40;17648:18;;15685:53:18::2;17338:334:19::0;15685:53:18::2;15748:20;15761:6;15748:12;:20::i;:::-;15800:6;15778:18;;:28;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;2303:20:3::0;1716:1;2809:7;:22;2629:209;2185:118:4;2248:7;2274:22;2288:7;2274:13;:22::i;1315:21:18:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1920:208:4:-;1983:7;-1:-1:-1;;;;;2006:19:4;;2002:87;;2048:30;;-1:-1:-1;;;2048:30:4;;2075:1;2048:30;;;3901:51:19;3874:18;;2048:30:4;3755:203:19;2002:87:4;-1:-1:-1;;;;;;2105:16:4;;;;;:9;:16;;;;;;;1920:208::o;2293:101:0:-;1531:13;:11;:13::i;:::-;2357:30:::1;2384:1;2357:18;:30::i;:::-;2293:101::o:0;14047:410:18:-;2934:10;2923:22;;;;:10;:22;;;;;;;;2915:61;;;;-1:-1:-1;;;2915:61:18;;;;;;;:::i;:::-;-1:-1:-1;;;;;2766:28:18;::::1;;::::0;;;:17:::1;:28;::::0;;;;:36;14177:9;;2766:36:::1;;2745:113;;;;-1:-1:-1::0;;;2745:113:18::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;14210:23:18;::::2;14202:51;;;;-1:-1:-1::0;;;14202:51:18::2;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;14284:28:18;::::2;14340:1;14284:28:::0;;;:17:::2;:28;::::0;;;;;;;:53;;;:44:::2;;:53:::0;;;;;;14263:121:::2;;;::::0;-1:-1:-1;;;14263:121:18;;24124:2:19;14263:121:18::2;::::0;::::2;24106:21:19::0;24163:2;24143:18;;;24136:30;-1:-1:-1;;;24182:18:19;;;24175:47;24239:18;;14263:121:18::2;23922:341:19::0;14263:121:18::2;-1:-1:-1::0;;;;;14395:28:18;::::2;;::::0;;;:17:::2;:28;::::0;;;;;;;:53;;;:44:::2;;:53:::0;;;;;:55;;;::::2;::::0;::::2;:::i;16390:138::-:0;1531:13:0;:11;:13::i;:::-;16447:12:18::1;::::0;::::1;;16446:13;16438:54;;;::::0;-1:-1:-1;;;16438:54:18;;24611:2:19;16438:54:18::1;::::0;::::1;24593:21:19::0;24650:2;24630:18;;;24623:30;24689;24669:18;;;24662:58;24737:18;;16438:54:18::1;24409:352:19::0;16438:54:18::1;16502:12;:19:::0;;-1:-1:-1;;16502:19:18::1;16517:4;16502:19;::::0;;16390:138::o;7708:183::-;-1:-1:-1;;;;;7841:21:18;;7812:6;7841:21;;;:13;:21;;;;;7876:7;7841:43;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;7834:50;;7708:183;;;;:::o;2518:93:4:-;2565:13;2597:7;2590:14;;;;;:::i;12734:631:18:-;2934:10;2923:22;;;;:10;:22;;;;;;;;2915:61;;;;-1:-1:-1;;;2915:61:18;;;;;;;:::i;:::-;-1:-1:-1;;;;;2766:28:18;::::1;;::::0;;;:17:::1;:28;::::0;;;;:36;12848:9;;2766:36:::1;;2745:113;;;;-1:-1:-1::0;;;2745:113:18::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;12881:23:18;::::2;12873:51;;;;-1:-1:-1::0;;;12873:51:18::2;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;12934:28:18;::::2;12973:5;12934:28:::0;;;:17:::2;:28;::::0;;;;:44;;-1:-1:-1;;12934:44:18::2;::::0;;12988:371:::2;13012:25;:32:::0;13008:36;::::2;12988:371;;;13101:9;-1:-1:-1::0;;;;;13069:41:18::2;:25;13095:1;13069:28;;;;;;;;:::i;:::-;;::::0;;;::::2;::::0;;;::::2;::::0;-1:-1:-1;;;;;13069:28:18::2;:41:::0;13065:284:::2;;13161:25;13208:32:::0;;:36:::2;::::0;13243:1:::2;::::0;13208:36:::2;:::i;:::-;13161:101;;;;;;;;:::i;:::-;;::::0;;;::::2;::::0;;;::::2;::::0;13130:25:::2;:28:::0;;-1:-1:-1;;;;;13161:101:18;;::::2;::::0;13156:1;;13130:28;::::2;;;;;:::i;:::-;;;;;;;;;:132;;;;;-1:-1:-1::0;;;;;13130:132:18::2;;;;;-1:-1:-1::0;;;;;13130:132:18::2;;;;;;13280:25;:31;;;;;;;:::i;:::-;;::::0;;;::::2;::::0;;;;-1:-1:-1;;13280:31:18;;;;;-1:-1:-1;;;;;;13280:31:18::2;::::0;;;;;4787:132:4;;;:::o;13065:284:18:-:2;13046:3;;12988:371;;3718:144:4::0;3803:52;735:10:11;3836:8:4;3846;3803:18;:52::i;11816:252:18:-;2934:10;2923:22;;;;:10;:22;;;;;;;;2915:61;;;;-1:-1:-1;;;2915:61:18;;;;;;;:::i;:::-;11956:19:::1;::::0;;::::1;;::::0;;;:10:::1;:19;::::0;;;;:26:::1;;::::0;::::1;11948:52;;;;-1:-1:-1::0;;;11948:52:18::1;;;;;;;:::i;:::-;12010:19;::::0;;::::1;;::::0;;;:10:::1;:19;::::0;;;;:34:::1;;:51:::0;11816:252::o;1416:45::-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;1416:45:18;;;;;;;;;;;;;;;;;;;-1:-1:-1;1416:45:18;;;:::o;4985:208:4:-;5098:31;5111:4;5117:2;5121:7;5098:12;:31::i;:::-;5139:47;5162:4;5168:2;5172:7;5181:4;5139:22;:47::i;9155:96:18:-;9234:9;;9211:33;;;9231:1;25577:34:19;;-1:-1:-1;;;9234:9:18;;;;;25642:2:19;25627:18;;25620:43;9211:33:18;;25525:18:19;9211:33:18;25373:296:19;11383:94:18;2934:10;2923:22;;;;:10;:22;;;;;;;;2915:61;;;;-1:-1:-1;;;2915:61:18;;;;;;;:::i;:::-;11459:11:::1;::::0;;-1:-1:-1;;11444:26:18;::::1;11459:11;::::0;;;::::1;;;11458:12;11444:26:::0;;::::1;;::::0;;11383:94::o;15220:261::-;2934:10;2923:22;;;;:10;:22;;;;;;;;2915:61;;;;-1:-1:-1;;;2915:61:18;;;;;;;:::i;:::-;15294:11:::1;::::0;::::1;;15293:12;15285:52;;;::::0;-1:-1:-1;;;15285:52:18;;25876:2:19;15285:52:18::1;::::0;::::1;25858:21:19::0;25915:2;25895:18;;;25888:30;25954:29;25934:18;;;25927:57;26001:18;;15285:52:18::1;25674:351:19::0;15285:52:18::1;15364:1;15348:91;15372:9;::::0;::::1;-1:-1:-1::0;;;15372:9:18;;::::1;::::0;::::1;15367:14:::0;;::::1;;15348:91;;15402:18;:26:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;15402:26:18;;;;;::::1;::::0;::::1;;::::0;;;;;;::::1;;;;;::::0;;::::1;;::::0;;::::1;::::0;;::::1;;::::0;;;::::1;::::0;;;15383:3:::1;15402:26:::0;15383:3:::1;:::i;:::-;;;;15348:91;;;-1:-1:-1::0;15448:11:18::1;:18:::0;;-1:-1:-1;;15448:18:18::1;15462:4;15448:18;::::0;;15220:261::o;9311:272::-;9474:1;5799:16:4;;;:7;:16;;;;;;9408:13:18;;-1:-1:-1;;;;;5799:16:4;9437:60:18;;;;-1:-1:-1;;;9437:60:18;;;;;;;:::i;:::-;9538:7;9547:18;:7;:16;:18::i;:::-;9521:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;9507:69;;9311:272;;;:::o;14937:219::-;2934:10;2923:22;;;;:10;:22;;;;;;;;2915:61;;;;-1:-1:-1;;;2915:61:18;;;;;;;:::i;:::-;1090:1:::1;15031:22;::::0;::::1;;;15006:70;;;::::0;-1:-1:-1;;;15006:70:18;;27425:2:19;15006:70:18::1;::::0;::::1;27407:21:19::0;27464:2;27444:18;;;27437:30;-1:-1:-1;;;27483:18:19;;;27476:48;27541:18;;15006:70:18::1;27223:342:19::0;15006:70:18::1;15086:12;:23:::0;;-1:-1:-1;;;;15086:23:18::1;-1:-1:-1::0;;;15086:23:18::1;::::0;;::::1;::::0;::::1;::::0;;;::::1;::::0;;;;15124:25:::1;::::0;15136:12;::::1;;2767:36:19::0;;15124:25:18::1;::::0;2755:2:19;2740:18;15124:25:18::1;;;;;;;14937:219:::0;:::o;12122:555::-;2934:10;2923:22;;;;:10;:22;;;;;;;;2915:61;;;;-1:-1:-1;;;2915:61:18;;;;;;;:::i;:::-;-1:-1:-1;;;;;12277:23:18;::::1;12269:51;;;;-1:-1:-1::0;;;12269:51:18::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;12352:28:18;::::1;;::::0;;;:17:::1;:28;::::0;;;;:36;::::1;;12351:37;12330:106;;;::::0;-1:-1:-1;;;12330:106:18;;27772:2:19;12330:106:18::1;::::0;::::1;27754:21:19::0;27811:2;27791:18;;;27784:30;-1:-1:-1;;;27830:18:19;;;27823:52;27892:18;;12330:106:18::1;27570:346:19::0;12330:106:18::1;-1:-1:-1::0;;;;;12446:28:18;;::::1;;::::0;;;:17:::1;:28;::::0;;;;:43;;12573:46:::1;::::0;;::::1;::::0;::::1;-1:-1:-1::0;;12446:43:18::1;12499:64:::0;;;::::1;12446:43;12499:64;-1:-1:-1::0;;12499:64:18;;;;;;;12485:4:::1;12499:64:::0;;;12573:46;;;::::1;::::0;;;::::1;::::0;;;12629:25:::1;:41:::0;;;;::::1;::::0;;;;;;::::1;::::0;;-1:-1:-1;;;;;;12629:41:18::1;::::0;;::::1;::::0;;12122:555::o;7425:211::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7549:19:18;;;;;;;;:10;:19;;;;;:26;;;;7541:52;;;;-1:-1:-1;;;7541:52:18;;;;;;;:::i;:::-;7610:19;;;;;;;:10;:19;;;;;;;7603:26;;;;;;;;;;;;7610:19;;7603:26;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;7603:26:18;;;-1:-1:-1;;7603:26:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7425:211;-1:-1:-1;;7425:211:18:o;16042:116::-;1531:13:0;:11;:13::i;:::-;-1:-1:-1;;;;;16123:20:18::1;16146:5;16123:20:::0;;;:10:::1;:20;::::0;;;;:28;;-1:-1:-1;;16123:28:18::1;::::0;;16042:116::o;16700:239::-;1531:13:0;:11;:13::i;:::-;16786:9:18::1;::::0;16775:8:::1;::::0;16786:13:::1;::::0;-1:-1:-1;;;16786:9:18;::::1;;;16798:1;16786:13;:::i;:::-;16775:24;;16770:117;16806:9;::::0;:23:::1;::::0;16818:11;;-1:-1:-1;;;16806:9:18;::::1;;;:23;:::i;:::-;16801:28;;:1;:28;;;16770:117;;16850:18;:26:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;16850:26:18;;;;;::::1;::::0;::::1;;::::0;;;;;;::::1;;;;;::::0;;::::1;;::::0;;::::1;::::0;;::::1;;::::0;;;::::1;::::0;;;16831:3:::1;16850:26:::0;16831:3:::1;:::i;:::-;;;;16770:117;;;-1:-1:-1::0;16909:9:18::1;::::0;:23:::1;::::0;16921:11;;-1:-1:-1;;;16909:9:18;::::1;;;:23;:::i;:::-;16897:9;;:35;;;;;;;;;;;;;;;;;;16700:239:::0;:::o;3928:153:4:-;-1:-1:-1;;;;;4039:25:4;;;4016:4;4039:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;3928:153::o;2543:215:0:-;1531:13;:11;:13::i;:::-;-1:-1:-1;;;;;2627:22:0;::::1;2623:91;;2672:31;::::0;-1:-1:-1;;;2672:31:0;;2700:1:::1;2672:31;::::0;::::1;3901:51:19::0;3874:18;;2672:31:0::1;3755:203:19::0;2623:91:0::1;2723:28;2742:8;2723:18;:28::i;11541:214:18:-:0;2934:10;2923:22;;;;:10;:22;;;;;;;;2915:61;;;;-1:-1:-1;;;2915:61:18;;;;;;;:::i;:::-;11661:19:::1;::::0;;::::1;;::::0;;;:10:::1;:19;::::0;;;;:26:::1;;::::0;::::1;11653:52;;;;-1:-1:-1::0;;;11653:52:18::1;;;;;;;:::i;:::-;11715:19;::::0;;::::1;;::::0;;;:10:::1;:19;::::0;;;;:25:::1;;:33:::0;11541:214::o;1561:300:4:-;1663:4;-1:-1:-1;;;;;;1698:40:4;;-1:-1:-1;;;1698:40:4;;:104;;-1:-1:-1;;;;;;;1754:48:4;;-1:-1:-1;;;1754:48:4;1698:104;:156;;;-1:-1:-1;;;;;;;;;;861:40:14;;;1818:36:4;762:146:14;2116:213:9;2218:4;-1:-1:-1;;;;;;2241:41:9;;-1:-1:-1;;;2241:41:9;;:81;;;2286:36;2310:11;2286:23;:36::i;1796:162:0:-;1710:6;;-1:-1:-1;;;;;1710:6:0;735:10:11;1855:23:0;1851:101;;1901:40;;-1:-1:-1;;;1901:40:0;;735:10:11;1901:40:0;;;3901:51:19;3874:18;;1901:40:0;3755:203:19;3429:507:9;3156:5;-1:-1:-1;;;;;3576:26:9;;;-1:-1:-1;3572:173:9;;;3679:55;;-1:-1:-1;;;3679:55:9;;-1:-1:-1;;;;;28112:39:19;;3679:55:9;;;28094:58:19;28168:18;;;28161:34;;;28067:18;;3679:55:9;27921:280:19;3572:173:9;-1:-1:-1;;;;;3758:22:9;;3754:108;;3803:48;;-1:-1:-1;;;3803:48:9;;3848:1;3803:48;;;3901:51:19;3874:18;;3803:48:9;3755:203:19;3754:108:9;-1:-1:-1;3894:35:9;;;;;;;;;-1:-1:-1;;;;;3894:35:9;;;;;;-1:-1:-1;;;;;3894:35:9;;;;;;;;;;-1:-1:-1;;;3872:57:9;;;;:19;:57;3429:507::o;16138:241:4:-;16201:7;5799:16;;;:7;:16;;;;;;-1:-1:-1;;;;;5799:16:4;;16263:88;;16309:31;;-1:-1:-1;;;16309:31:4;;;;;8758:25:19;;;8731:18;;16309:31:4;8612:177:19;2336:287:3;1759:1;2468:7;;:19;2460:63;;;;-1:-1:-1;;;2460:63:3;;28408:2:19;2460:63:3;;;28390:21:19;28447:2;28427:18;;;28420:30;28486:33;28466:18;;;28459:61;28537:18;;2460:63:3;28206:355:19;2460:63:3;1759:1;2598:7;:18;2336:287::o;9656:336:18:-;9934:36;;-1:-1:-1;;28743:2:19;28739:15;;;28735:53;9934:36:18;;;28723:66:19;28805:12;;;28798:28;;;9808:4:18;;9843:142;;9879:5;;9902:4;;28842:12:19;;9934:36:18;;;;;;;;;;;;9924:47;;;;;;9843:18;:142::i;:::-;9824:161;9656:336;-1:-1:-1;;;;;9656:336:18:o;10059:674::-;10120:9;10115:612;10139:6;10135:10;;:1;:10;10115:612;;;10174:18;:25;10166:66;;;;-1:-1:-1;;;10166:66:18;;29067:2:19;10166:66:18;;;29049:21:19;29106:2;29086:18;;;29079:30;29145:26;29125:18;;;29118:54;29189:18;;10166:66:18;28865:348:19;10166:66:18;10279:18;:25;10910:208;;;10952:15;10910:208;;;;30296:19:19;;;;-1:-1:-1;;10993:10:18;30353:2:19;30349:15;30345:53;30331:12;;;30324:75;30415:12;;;30408:28;;;11080:16:18;30452:12:19;;;;30445:28;;;;10910:208:18;;;;;;;;;;30489:13:19;;;;10910:208:18;;;10879:257;;;;;-1:-1:-1;;10269:35:18;;;:::i;:::-;10247:57;;10318:14;10335:18;10354:11;10335:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;10318:48;;10468:18;10532:1;10504:18;:25;;;;:29;;;;:::i;:::-;10468:79;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;10434:18;10453:11;10434:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;:113;;;;;;;;;;;;;;;;;;10561:18;:24;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10630:30;10640:10;10652:7;10630:30;;:9;:30::i;:::-;10679:23;;5930:6:19;5918:19;;5900:38;;10679:23:18;;5888:2:19;5873:18;10679:23:18;;;;;;;-1:-1:-1;;10147:3:18;;10115:612;;14418:120:4;14498:33;14507:2;14511:7;14520:4;14526;14498:8;:33::i;8838:795::-;8924:7;5799:16;;;:7;:16;;;;;;-1:-1:-1;;;;;5799:16:4;;;;9035:18;;;9031:86;;9069:37;9086:4;9092;9098:7;9069:16;:37::i;:::-;-1:-1:-1;;;;;9161:18:4;;;9157:256;;9277:48;9294:1;9298:7;9315:1;9319:5;9277:8;:48::i;:::-;-1:-1:-1;;;;;9368:15:4;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;9368:20:4;;;9157:256;-1:-1:-1;;;;;9427:16:4;;;9423:107;;-1:-1:-1;;;;;9487:13:4;;;;;;:9;:13;;;;;:18;;9504:1;9487:18;;;9423:107;9540:16;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;9540:21:4;-1:-1:-1;;;;;9540:21:4;;;;;;;;;9577:27;;9540:16;;9577:27;;;;;;;9622:4;8838:795;-1:-1:-1;;;;8838:795:4:o;11462:227::-;11513:21;11537:40;11553:1;11557:7;11574:1;11537:7;:40::i;:::-;11513:64;-1:-1:-1;;;;;;11591:27:4;;11587:96;;11641:31;;-1:-1:-1;;;11641:31:4;;;;;8758:25:19;;;8731:18;;11641:31:4;8612:177:19;2912:187:0;3004:6;;;-1:-1:-1;;;;;3020:17:0;;;-1:-1:-1;;;;;;3020:17:0;;;;;;;3052:40;;3004:6;;;3020:17;3004:6;;3052:40;;2985:16;;3052:40;2975:124;2912:187;:::o;15591:312:4:-;-1:-1:-1;;;;;15698:22:4;;15694:91;;15743:31;;-1:-1:-1;;;15743:31:4;;-1:-1:-1;;;;;3919:32:19;;15743:31:4;;;3901:51:19;3874:18;;15743:31:4;3755:203:19;15694:91:4;-1:-1:-1;;;;;15794:25:4;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;15794:46:4;;;;;;;;;;15855:41;;540::19;;;15855::4;;513:18:19;15855:41:4;;;;;;;15591:312;;;:::o;16918:782::-;-1:-1:-1;;;;;17034:14:4;;;:18;17030:664;;17072:71;;-1:-1:-1;;;17072:71:4;;-1:-1:-1;;;;;17072:36:4;;;;;:71;;735:10:11;;17123:4:4;;17129:7;;17138:4;;17072:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;17072:71:4;;;;;;;;-1:-1:-1;;17072:71:4;;;;;;;;;;;;:::i;:::-;;;17068:616;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17381:6;:13;17398:1;17381:18;17377:293;;17430:25;;-1:-1:-1;;;17430:25:4;;-1:-1:-1;;;;;3919:32:19;;17430:25:4;;;3901:51:19;3874:18;;17430:25:4;3755:203:19;17377:293:4;17622:6;17616:13;17607:6;17603:2;17599:15;17592:38;17068:616;-1:-1:-1;;;;;;17190:51:4;;-1:-1:-1;;;17190:51:4;17186:130;;17272:25;;-1:-1:-1;;;17272:25:4;;-1:-1:-1;;;;;3919:32:19;;17272:25:4;;;3901:51:19;3874:18;;17272:25:4;3755:203:19;17186:130:4;17144:186;16918:782;;;;:::o;637:698:12:-;693:13;742:14;759:17;770:5;759:10;:17::i;:::-;779:1;759:21;742:38;;794:20;828:6;817:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;817:18:12;-1:-1:-1;794:41:12;-1:-1:-1;955:28:12;;;971:2;955:28;1010:282;-1:-1:-1;;1041:5:12;-1:-1:-1;;;1175:2:12;1164:14;;1159:32;1041:5;1146:46;1236:2;1227:11;;;-1:-1:-1;1256:21:12;1010:282;1256:21;-1:-1:-1;1312:6:12;637:698;-1:-1:-1;;;637:698:12:o;1265:154:13:-;1356:4;1408;1379:25;1392:5;1399:4;1379:12;:25::i;:::-;:33;;1265:154;-1:-1:-1;;;;1265:154:13:o;10633:100:4:-;10700:26;10710:2;10714:7;10700:26;;;;;;;;;;;;:9;:26::i;14720:662::-;14880:9;:31;;;-1:-1:-1;;;;;;14893:18:4;;;;14880:31;14876:460;;;14927:13;14943:22;14957:7;14943:13;:22::i;:::-;14927:38;-1:-1:-1;;;;;;15093:18:4;;;;;;:35;;;15124:4;-1:-1:-1;;;;;15115:13:4;:5;-1:-1:-1;;;;;15115:13:4;;;15093:35;:69;;;;;15133:29;15150:5;15157:4;15133:16;:29::i;:::-;15132:30;15093:69;15089:142;;;15189:27;;-1:-1:-1;;;15189:27:4;;-1:-1:-1;;;;;3919:32:19;;15189:27:4;;;3901:51:19;3874:18;;15189:27:4;3755:203:19;15089:142:4;15249:9;15245:81;;;15303:7;15299:2;-1:-1:-1;;;;;15283:28:4;15292:5;-1:-1:-1;;;;;15283:28:4;;;;;;;;;;;15245:81;14913:423;14876:460;-1:-1:-1;;15346:24:4;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;15346:29:4;-1:-1:-1;;;;;15346:29:4;;;;;;;;;;14720:662::o;7082:368::-;7194:38;7208:5;7215:7;7224;7194:13;:38::i;:::-;7189:255;;-1:-1:-1;;;;;7252:19:4;;7248:186;;7298:31;;-1:-1:-1;;;7298:31:4;;;;;8758:25:19;;;8731:18;;7298:31:4;8612:177:19;7248:186:4;7375:44;;-1:-1:-1;;;7375:44:4;;-1:-1:-1;;;;;5669:32:19;;7375:44:4;;;5651:51:19;5718:18;;;5711:34;;;5624:18;;7375:44:4;5477:274:19;12214:916:16;12267:7;;-1:-1:-1;;;12342:17:16;;12338:103;;-1:-1:-1;;;12379:17:16;;;-1:-1:-1;12424:2:16;12414:12;12338:103;12467:8;12458:5;:17;12454:103;;12504:8;12495:17;;;-1:-1:-1;12540:2:16;12530:12;12454:103;12583:8;12574:5;:17;12570:103;;12620:8;12611:17;;;-1:-1:-1;12656:2:16;12646:12;12570:103;12699:7;12690:5;:16;12686:100;;12735:7;12726:16;;;-1:-1:-1;12770:1:16;12760:11;12686:100;12812:7;12803:5;:16;12799:100;;12848:7;12839:16;;;-1:-1:-1;12883:1:16;12873:11;12799:100;12925:7;12916:5;:16;12912:100;;12961:7;12952:16;;;-1:-1:-1;12996:1:16;12986:11;12912:100;13038:7;13029:5;:16;13025:66;;13075:1;13065:11;13117:6;12214:916;-1:-1:-1;;12214:916:16:o;1967:290:13:-;2050:7;2092:4;2050:7;2106:116;2130:5;:12;2126:1;:16;2106:116;;;2178:33;2188:12;2202:5;2208:1;2202:8;;;;;;;;:::i;:::-;;;;;;;2178:9;:33::i;:::-;2163:48;-1:-1:-1;2144:3:13;;2106:116;;;-1:-1:-1;2238:12:13;1967:290;-1:-1:-1;;;1967:290:13:o;10954:182:4:-;11048:18;11054:2;11058:7;11048:5;:18::i;:::-;11076:53;11107:1;11111:2;11115:7;11124:4;11076:22;:53::i;6376:272::-;6479:4;-1:-1:-1;;;;;6514:21:4;;;;;;:127;;;6561:7;-1:-1:-1;;;;;6552:16:4;:5;-1:-1:-1;;;;;6552:16:4;;:52;;;;6572:32;6589:5;6596:7;6572:16;:32::i;:::-;6552:88;;;-1:-1:-1;6008:7:4;6034:24;;;:15;:24;;;;;;-1:-1:-1;;;;;6608:32:4;;;6034:24;;6608:32;6552:88;6495:146;6376:272;-1:-1:-1;;;;6376:272:4:o;9229:147:13:-;9292:7;9322:1;9318;:5;:51;;9564:13;9655:15;;;9690:4;9683:15;;;9736:4;9720:21;;9318:51;;;9564:13;9655:15;;;9690:4;9683:15;;;9736:4;9720:21;;9326:20;9311:58;9229:147;-1:-1:-1;;;9229:147:13:o;9955:327:4:-;-1:-1:-1;;;;;10022:16:4;;10018:87;;10061:33;;-1:-1:-1;;;10061:33:4;;10091:1;10061:33;;;3901:51:19;3874:18;;10061:33:4;3755:203:19;10018:87:4;10114:21;10138:32;10146:2;10150:7;10167:1;10138:7;:32::i;:::-;10114:56;-1:-1:-1;;;;;;10184:27:4;;;10180:96;;10234:31;;-1:-1:-1;;;10234:31:4;;10262:1;10234:31;;;3901:51:19;3874:18;;10234:31:4;3755:203:19;14:131;-1:-1:-1;;;;;;88:32:19;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:127::-;653:10;648:3;644:20;641:1;634:31;684:4;681:1;674:15;708:4;705:1;698:15;724:632;789:5;819:18;860:2;852:6;849:14;846:40;;;866:18;;:::i;:::-;941:2;935:9;909:2;995:15;;-1:-1:-1;;991:24:19;;;1017:2;987:33;983:42;971:55;;;1041:18;;;1061:22;;;1038:46;1035:72;;;1087:18;;:::i;:::-;1127:10;1123:2;1116:22;1156:6;1147:15;;1186:6;1178;1171:22;1226:3;1217:6;1212:3;1208:16;1205:25;1202:45;;;1243:1;1240;1233:12;1202:45;1293:6;1288:3;1281:4;1273:6;1269:17;1256:44;1348:1;1341:4;1332:6;1324;1320:19;1316:30;1309:41;;;;724:632;;;;;:::o;1361:451::-;1430:6;1483:2;1471:9;1462:7;1458:23;1454:32;1451:52;;;1499:1;1496;1489:12;1451:52;1539:9;1526:23;1572:18;1564:6;1561:30;1558:50;;;1604:1;1601;1594:12;1558:50;1627:22;;1680:4;1672:13;;1668:27;-1:-1:-1;1658:55:19;;1709:1;1706;1699:12;1658:55;1732:74;1798:7;1793:2;1780:16;1775:2;1771;1767:11;1732:74;:::i;1817:173::-;1885:20;;-1:-1:-1;;;;;1934:31:19;;1924:42;;1914:70;;1980:1;1977;1970:12;1914:70;1817:173;;;:::o;1995:366::-;2062:6;2070;2123:2;2111:9;2102:7;2098:23;2094:32;2091:52;;;2139:1;2136;2129:12;2091:52;2162:29;2181:9;2162:29;:::i;:::-;2152:39;;2241:2;2230:9;2226:18;2213:32;-1:-1:-1;;;;;2278:5:19;2274:38;2267:5;2264:49;2254:77;;2327:1;2324;2317:12;2254:77;2350:5;2340:15;;;1995:366;;;;;:::o;2366:254::-;2434:6;2442;2495:2;2483:9;2474:7;2470:23;2466:32;2463:52;;;2511:1;2508;2501:12;2463:52;2534:29;2553:9;2534:29;:::i;:::-;2524:39;2610:2;2595:18;;;;2582:32;;-1:-1:-1;;;2366:254:19:o;2814:250::-;2899:1;2909:113;2923:6;2920:1;2917:13;2909:113;;;2999:11;;;2993:18;2980:11;;;2973:39;2945:2;2938:10;2909:113;;;-1:-1:-1;;3056:1:19;3038:16;;3031:27;2814:250::o;3069:271::-;3111:3;3149:5;3143:12;3176:6;3171:3;3164:19;3192:76;3261:6;3254:4;3249:3;3245:14;3238:4;3231:5;3227:16;3192:76;:::i;:::-;3322:2;3301:15;-1:-1:-1;;3297:29:19;3288:39;;;;3329:4;3284:50;;3069:271;-1:-1:-1;;3069:271:19:o;3345:220::-;3494:2;3483:9;3476:21;3457:4;3514:45;3555:2;3544:9;3540:18;3532:6;3514:45;:::i;3570:180::-;3629:6;3682:2;3670:9;3661:7;3657:23;3653:32;3650:52;;;3698:1;3695;3688:12;3650:52;-1:-1:-1;3721:23:19;;3570:180;-1:-1:-1;3570:180:19:o;3963:159::-;4030:20;;4090:6;4079:18;;4069:29;;4059:57;;4112:1;4109;4102:12;4127:759;4229:6;4237;4245;4253;4306:2;4294:9;4285:7;4281:23;4277:32;4274:52;;;4322:1;4319;4312:12;4274:52;4345:28;4363:9;4345:28;:::i;:::-;4335:38;;4392:37;4425:2;4414:9;4410:18;4392:37;:::i;:::-;4382:47;;4480:2;4469:9;4465:18;4452:32;4503:18;4544:2;4536:6;4533:14;4530:34;;;4560:1;4557;4550:12;4530:34;4598:6;4587:9;4583:22;4573:32;;4643:7;4636:4;4632:2;4628:13;4624:27;4614:55;;4665:1;4662;4655:12;4614:55;4705:2;4692:16;4731:2;4723:6;4720:14;4717:34;;;4747:1;4744;4737:12;4717:34;4800:7;4795:2;4785:6;4782:1;4778:14;4774:2;4770:23;4766:32;4763:45;4760:65;;;4821:1;4818;4811:12;4760:65;4127:759;;;;-1:-1:-1;;4852:2:19;4844:11;;-1:-1:-1;;;4127:759:19:o;4891:328::-;4968:6;4976;4984;5037:2;5025:9;5016:7;5012:23;5008:32;5005:52;;;5053:1;5050;5043:12;5005:52;5076:29;5095:9;5076:29;:::i;:::-;5066:39;;5124:38;5158:2;5147:9;5143:18;5124:38;:::i;:::-;5114:48;;5209:2;5198:9;5194:18;5181:32;5171:42;;4891:328;;;;;:::o;5224:248::-;5292:6;5300;5353:2;5341:9;5332:7;5328:23;5324:32;5321:52;;;5369:1;5366;5359:12;5321:52;-1:-1:-1;;5392:23:19;;;5462:2;5447:18;;;5434:32;;-1:-1:-1;5224:248:19:o;5949:186::-;6008:6;6061:2;6049:9;6040:7;6036:23;6032:32;6029:52;;;6077:1;6074;6067:12;6029:52;6100:29;6119:9;6100:29;:::i;6140:406::-;6192:3;6236:5;6230:12;6263:4;6258:3;6251:17;6289:47;6330:4;6325:3;6321:14;6307:12;6289:47;:::i;:::-;6277:59;;6385:4;6378:5;6374:16;6368:23;6361:4;6356:3;6352:14;6345:47;6441:4;6434:5;6430:16;6424:23;6417:4;6412:3;6408:14;6401:47;6511:4;6504:5;6500:16;6494:23;6487:31;6480:39;6473:4;6468:3;6464:14;6457:63;6536:4;6529:11;;;6140:406;;;;:::o;6551:604::-;6848:4;6840:6;6836:17;6825:9;6818:36;6799:4;6873:6;6927:2;6919:6;6915:15;6910:2;6899:9;6895:18;6888:43;6979:2;6971:6;6967:15;6962:2;6951:9;6947:18;6940:43;7019:3;7014:2;7003:9;6999:18;6992:31;7040:56;7091:3;7080:9;7076:19;7068:6;7040:56;:::i;:::-;7032:64;;7145:2;7137:6;7133:15;7127:3;7116:9;7112:19;7105:44;;6551:604;;;;;;;;:::o;7160:923::-;7409:2;7461:21;;;7531:13;;7434:18;;;7553:22;;;7380:4;;7409:2;7594;;7612:18;;;;7653:15;;;7380:4;7696:361;7710:6;7707:1;7704:13;7696:361;;;7769:13;;7811:9;;-1:-1:-1;;;;;7807:35:19;7795:48;;7887:11;;;7881:18;7901:4;7877:29;7863:12;;;7856:51;7951:11;;7945:18;7965:8;7941:33;7927:12;;;7920:55;8004:4;7995:14;;;;8032:15;;;;7839:1;7725:9;7696:361;;;-1:-1:-1;8074:3:19;;7160:923;-1:-1:-1;;;;;;;7160:923:19:o;8088:330::-;8163:6;8171;8179;8232:2;8220:9;8211:7;8207:23;8203:32;8200:52;;;8248:1;8245;8238:12;8200:52;8271:28;8289:9;8271:28;:::i;:::-;8261:38;;8318;8352:2;8341:9;8337:18;8318:38;:::i;:::-;8308:48;;8375:37;8408:2;8397:9;8393:18;8375:37;:::i;:::-;8365:47;;8088:330;;;;;:::o;8423:184::-;8481:6;8534:2;8522:9;8513:7;8509:23;8505:32;8502:52;;;8550:1;8547;8540:12;8502:52;8573:28;8591:9;8573:28;:::i;8794:254::-;8862:6;8870;8923:2;8911:9;8902:7;8898:23;8894:32;8891:52;;;8939:1;8936;8929:12;8891:52;8975:9;8962:23;8952:33;;9004:38;9038:2;9027:9;9023:18;9004:38;:::i;:::-;8994:48;;8794:254;;;;;:::o;9053:347::-;9118:6;9126;9179:2;9167:9;9158:7;9154:23;9150:32;9147:52;;;9195:1;9192;9185:12;9147:52;9218:29;9237:9;9218:29;:::i;:::-;9208:39;;9297:2;9286:9;9282:18;9269:32;9344:5;9337:13;9330:21;9323:5;9320:32;9310:60;;9366:1;9363;9356:12;9405:156;9471:20;;9531:4;9520:16;;9510:27;;9500:55;;9551:1;9548;9541:12;9566:250;9632:6;9640;9693:2;9681:9;9672:7;9668:23;9664:32;9661:52;;;9709:1;9706;9699:12;9661:52;9732:27;9749:9;9732:27;:::i;9821:182::-;9878:6;9931:2;9919:9;9910:7;9906:23;9902:32;9899:52;;;9947:1;9944;9937:12;9899:52;9970:27;9987:9;9970:27;:::i;10008:445::-;10235:3;10224:9;10217:22;10198:4;10256:46;10297:3;10286:9;10282:19;10274:6;10256:46;:::i;:::-;10333:2;10318:18;;10311:34;;;;-1:-1:-1;10376:2:19;10361:18;;10354:34;;;;10431:14;10424:22;10419:2;10404:18;;;10397:50;10248:54;10008:445;-1:-1:-1;10008:445:19:o;10458:667::-;10553:6;10561;10569;10577;10630:3;10618:9;10609:7;10605:23;10601:33;10598:53;;;10647:1;10644;10637:12;10598:53;10670:29;10689:9;10670:29;:::i;:::-;10660:39;;10718:38;10752:2;10741:9;10737:18;10718:38;:::i;:::-;10708:48;;10803:2;10792:9;10788:18;10775:32;10765:42;;10858:2;10847:9;10843:18;10830:32;10885:18;10877:6;10874:30;10871:50;;;10917:1;10914;10907:12;10871:50;10940:22;;10993:4;10985:13;;10981:27;-1:-1:-1;10971:55:19;;11022:1;11019;11012:12;10971:55;11045:74;11111:7;11106:2;11093:16;11088:2;11084;11080:11;11045:74;:::i;:::-;11035:84;;;10458:667;;;;;;;:::o;11130:418::-;11204:6;11212;11220;11273:2;11261:9;11252:7;11248:23;11244:32;11241:52;;;11289:1;11286;11279:12;11241:52;11312:29;11331:9;11312:29;:::i;:::-;11302:39;;11360:36;11392:2;11381:9;11377:18;11360:36;:::i;:::-;11350:46;;11446:2;11435:9;11431:18;11418:32;11490:8;11483:5;11479:20;11472:5;11469:31;11459:59;;11514:1;11511;11504:12;11459:59;11537:5;11527:15;;;11130:418;;;;;:::o;11553:264::-;11736:2;11725:9;11718:21;11699:4;11756:55;11807:2;11796:9;11792:18;11784:6;11756:55;:::i;11822:260::-;11890:6;11898;11951:2;11939:9;11930:7;11926:23;11922:32;11919:52;;;11967:1;11964;11957:12;11919:52;11990:29;12009:9;11990:29;:::i;:::-;11980:39;;12038:38;12072:2;12061:9;12057:18;12038:38;:::i;12342:350::-;12544:2;12526:21;;;12583:2;12563:18;;;12556:30;12622:28;12617:2;12602:18;;12595:56;12683:2;12668:18;;12342:350::o;13046:380::-;13125:1;13121:12;;;;13168;;;13189:61;;13243:4;13235:6;13231:17;13221:27;;13189:61;13296:2;13288:6;13285:14;13265:18;13262:38;13259:161;;13342:10;13337:3;13333:20;13330:1;13323:31;13377:4;13374:1;13367:15;13405:4;13402:1;13395:15;13557:543;13659:2;13654:3;13651:11;13648:446;;;13695:1;13719:5;13716:1;13709:16;13763:4;13760:1;13750:18;13833:2;13821:10;13817:19;13814:1;13810:27;13804:4;13800:38;13869:4;13857:10;13854:20;13851:47;;;-1:-1:-1;13892:4:19;13851:47;13947:2;13942:3;13938:12;13935:1;13931:20;13925:4;13921:31;13911:41;;14002:82;14020:2;14013:5;14010:13;14002:82;;;14065:17;;;14046:1;14035:13;14002:82;;;14006:3;;;13557:543;;;:::o;14276:1345::-;14402:3;14396:10;14429:18;14421:6;14418:30;14415:56;;;14451:18;;:::i;:::-;14480:97;14570:6;14530:38;14562:4;14556:11;14530:38;:::i;:::-;14524:4;14480:97;:::i;:::-;14632:4;;14689:2;14678:14;;14706:1;14701:663;;;;15408:1;15425:6;15422:89;;;-1:-1:-1;15477:19:19;;;15471:26;15422:89;-1:-1:-1;;14233:1:19;14229:11;;;14225:24;14221:29;14211:40;14257:1;14253:11;;;14208:57;15524:81;;14671:944;;14701:663;13504:1;13497:14;;;13541:4;13528:18;;-1:-1:-1;;14737:20:19;;;14855:236;14869:7;14866:1;14863:14;14855:236;;;14958:19;;;14952:26;14937:42;;15050:27;;;;15018:1;15006:14;;;;14885:19;;14855:236;;;14859:3;15119:6;15110:7;15107:19;15104:201;;;15180:19;;;15174:26;-1:-1:-1;;15263:1:19;15259:14;;;15275:3;15255:24;15251:37;15247:42;15232:58;15217:74;;15104:201;-1:-1:-1;;;;;15351:1:19;15335:14;;;15331:22;15318:36;;-1:-1:-1;14276:1345:19:o;15626:354::-;15828:2;15810:21;;;15867:2;15847:18;;;15840:30;15906:32;15901:2;15886:18;;15879:60;15971:2;15956:18;;15626:354::o;15985:339::-;16187:2;16169:21;;;16226:2;16206:18;;;16199:30;-1:-1:-1;;;16260:2:19;16245:18;;16238:45;16315:2;16300:18;;15985:339::o;16329:400::-;16531:2;16513:21;;;16570:2;16550:18;;;16543:30;16609:34;16604:2;16589:18;;16582:62;-1:-1:-1;;;16675:2:19;16660:18;;16653:34;16719:3;16704:19;;16329:400::o;16734:127::-;16795:10;16790:3;16786:20;16783:1;16776:31;16826:4;16823:1;16816:15;16850:4;16847:1;16840:15;16866:135;16905:3;16926:17;;;16923:43;;16946:18;;:::i;:::-;-1:-1:-1;16993:1:19;16982:13;;16866:135::o;17006:327::-;17208:2;17190:21;;;17247:1;17227:18;;;17220:29;-1:-1:-1;;;17280:2:19;17265:18;;17258:34;17324:2;17309:18;;17006:327::o;18370:168::-;18437:6;18463:10;;;18475;;;18459:27;;18498:11;;;18495:37;;;18512:18;;:::i;:::-;18495:37;18370:168;;;;:::o;18896:::-;18969:9;;;19000;;19017:15;;;19011:22;;18997:37;18987:71;;19038:18;;:::i;19836:127::-;19897:10;19892:3;19888:20;19885:1;19878:31;19928:4;19925:1;19918:15;19952:4;19949:1;19942:15;21326:127;21387:10;21382:3;21378:20;21375:1;21368:31;21418:4;21415:1;21408:15;21442:4;21439:1;21432:15;21458:120;21498:1;21524;21514:35;;21529:18;;:::i;:::-;-1:-1:-1;21563:9:19;;21458:120::o;21927:175::-;21964:3;22008:4;22001:5;21997:16;22037:4;22028:7;22025:17;22022:43;;22045:18;;:::i;:::-;22094:1;22081:15;;21927:175;-1:-1:-1;;21927:175:19:o;22107:340::-;22309:2;22291:21;;;22348:2;22328:18;;;22321:30;-1:-1:-1;;;22382:2:19;22367:18;;22360:46;22438:2;22423:18;;22107:340::o;22796:178::-;22833:3;22877:4;22870:5;22866:16;22901:7;22891:41;;22912:18;;:::i;:::-;-1:-1:-1;;22948:20:19;;22796:178;-1:-1:-1;;22796:178:19:o;23331:197::-;23369:3;23397:6;23438:2;23431:5;23427:14;23465:2;23456:7;23453:15;23450:41;;23471:18;;:::i;:::-;23520:1;23507:15;;23331:197;-1:-1:-1;;;23331:197:19:o;24268:136::-;24307:3;24335:5;24325:39;;24344:18;;:::i;:::-;-1:-1:-1;;;24380:18:19;;24268:136::o;24766:128::-;24833:9;;;24854:11;;;24851:37;;;24868:18;;:::i;24899:127::-;24960:10;24955:3;24951:20;24948:1;24941:31;24991:4;24988:1;24981:15;25015:4;25012:1;25005:15;25031:337;25233:2;25215:21;;;25272:2;25252:18;;;25245:30;-1:-1:-1;;;25306:2:19;25291:18;;25284:43;25359:2;25344:18;;25031:337::o;26030:1188::-;26307:3;26336:1;26369:6;26363:13;26399:36;26425:9;26399:36;:::i;:::-;26454:1;26471:17;;;26497:133;;;;26644:1;26639:358;;;;26464:533;;26497:133;-1:-1:-1;;26530:24:19;;26518:37;;26603:14;;26596:22;26584:35;;26575:45;;;-1:-1:-1;26497:133:19;;26639:358;26670:6;26667:1;26660:17;26700:4;26745;26742:1;26732:18;26772:1;26786:165;26800:6;26797:1;26794:13;26786:165;;;26878:14;;26865:11;;;26858:35;26921:16;;;;26815:10;;26786:165;;;26790:3;;;26980:6;26975:3;26971:16;26964:23;;26464:533;;;;;27028:6;27022:13;27044:68;27103:8;27098:3;27091:4;27083:6;27079:17;27044:68;:::i;:::-;-1:-1:-1;;;27134:18:19;;27161:22;;;27210:1;27199:13;;26030:1188;-1:-1:-1;;;;26030:1188:19:o;29218:112::-;29250:1;29276;29266:35;;29281:18;;:::i;:::-;-1:-1:-1;29315:9:19;;29218:112::o;29335:489::-;-1:-1:-1;;;;;29604:15:19;;;29586:34;;29656:15;;29651:2;29636:18;;29629:43;29703:2;29688:18;;29681:34;;;29751:3;29746:2;29731:18;;29724:31;;;29529:4;;29772:46;;29798:19;;29790:6;29772:46;:::i;:::-;29764:54;29335:489;-1:-1:-1;;;;;;29335:489:19:o;29829:249::-;29898:6;29951:2;29939:9;29930:7;29926:23;29922:32;29919:52;;;29967:1;29964;29957:12;29919:52;29999:9;29993:16;30018:30;30042:5;30018:30;:::i
Swarm Source
ipfs://12c9f0c909fa3b14f0c214bd790fd2d85216f014083b211d450ebd55865ca4f5
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 29 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.